Merge "Add initial ambient light sensor rate"
diff --git a/Android.mk b/Android.mk
index 0b5e0cc..6f96803 100644
--- a/Android.mk
+++ b/Android.mk
@@ -68,6 +68,7 @@
 	core/java/android/app/IActivityContainer.aidl \
 	core/java/android/app/IActivityContainerCallback.aidl \
 	core/java/android/app/IActivityController.aidl \
+	core/java/android/app/IActivityManager.aidl \
 	core/java/android/app/IActivityPendingResult.aidl \
 	core/java/android/app/IAlarmCompleteListener.aidl \
 	core/java/android/app/IAlarmListener.aidl \
@@ -118,9 +119,10 @@
 	core/java/android/bluetooth/IBluetoothPan.aidl \
 	core/java/android/bluetooth/IBluetoothManager.aidl \
 	core/java/android/bluetooth/IBluetoothManagerCallback.aidl \
+	core/java/android/bluetooth/IBluetoothMap.aidl \
+	core/java/android/bluetooth/IBluetoothMapClient.aidl \
 	core/java/android/bluetooth/IBluetoothPbap.aidl \
 	core/java/android/bluetooth/IBluetoothPbapClient.aidl \
-	core/java/android/bluetooth/IBluetoothMap.aidl \
 	core/java/android/bluetooth/IBluetoothSap.aidl \
 	core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl \
 	core/java/android/bluetooth/IBluetoothHeadsetClient.aidl \
@@ -128,6 +130,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 \
@@ -204,6 +207,7 @@
 	core/java/android/net/IIpConnectivityMetrics.aidl \
 	core/java/android/net/IEthernetManager.aidl \
 	core/java/android/net/IEthernetServiceListener.aidl \
+	core/java/android/net/INetdEventCallback.aidl \
 	core/java/android/net/INetworkManagementEventObserver.aidl \
 	core/java/android/net/INetworkPolicyListener.aidl \
 	core/java/android/net/INetworkPolicyManager.aidl \
@@ -241,6 +245,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 +302,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 \
@@ -457,9 +467,9 @@
 	telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
 	telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
 	wifi/java/android/net/wifi/IWifiManager.aidl \
-	wifi/java/android/net/wifi/nan/IWifiNanEventCallback.aidl \
-	wifi/java/android/net/wifi/nan/IWifiNanManager.aidl \
-	wifi/java/android/net/wifi/nan/IWifiNanDiscoverySessionCallback.aidl \
+	wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl \
+	wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl \
+	wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl \
 	wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \
 	wifi/java/android/net/wifi/IWifiScanner.aidl \
 	wifi/java/android/net/wifi/IRttManager.aidl \
@@ -503,7 +513,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
 
@@ -549,9 +562,9 @@
 	frameworks/base/media/java/android/media/tv/TvTrackInfo.aidl \
 	frameworks/base/media/java/android/media/browse/MediaBrowser.aidl \
 	frameworks/base/wifi/java/android/net/wifi/ScanSettings.aidl \
-	frameworks/base/wifi/java/android/net/wifi/nan/ConfigRequest.aidl \
-	frameworks/base/wifi/java/android/net/wifi/nan/PublishConfig.aidl \
-	frameworks/base/wifi/java/android/net/wifi/nan/SubscribeConfig.aidl \
+	frameworks/base/wifi/java/android/net/wifi/aware/ConfigRequest.aidl \
+	frameworks/base/wifi/java/android/net/wifi/aware/PublishConfig.aidl \
+	frameworks/base/wifi/java/android/net/wifi/aware/SubscribeConfig.aidl \
 	frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pInfo.aidl \
 	frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.aidl \
 	frameworks/base/wifi/java/android/net/wifi/p2p/WifiP2pConfig.aidl \
@@ -574,6 +587,9 @@
 	frameworks/base/graphics/java/android/graphics/drawable/Icon.aidl \
 	frameworks/base/core/java/android/accounts/AuthenticatorDescription.aidl \
 	frameworks/base/core/java/android/accounts/Account.aidl \
+	frameworks/base/core/java/android/app/admin/ConnectEvent.aidl \
+	frameworks/base/core/java/android/app/admin/DnsEvent.aidl \
+	frameworks/base/core/java/android/app/admin/NetworkEvent.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 \
@@ -600,6 +616,7 @@
 	frameworks/base/core/java/android/os/DropBoxManager.aidl \
 	frameworks/base/core/java/android/os/Bundle.aidl \
 	frameworks/base/core/java/android/os/Debug.aidl \
+	frameworks/base/core/java/android/os/StrictMode.aidl \
 	frameworks/base/core/java/android/accessibilityservice/AccessibilityServiceInfo.aidl \
 	frameworks/base/core/java/android/net/Network.aidl \
 	frameworks/base/core/java/android/net/RouteInfo.aidl \
@@ -680,6 +697,7 @@
 	frameworks/base/core/java/android/content/pm/ApplicationInfo.aidl \
 	frameworks/base/core/java/android/content/pm/PermissionInfo.aidl \
 	frameworks/base/core/java/android/content/pm/ActivityInfo.aidl \
+	frameworks/base/core/java/android/content/pm/ConfigurationInfo.aidl \
 	frameworks/base/core/java/android/content/pm/PackageInfo.aidl \
 	frameworks/base/core/java/android/content/pm/ResolveInfo.aidl \
 	frameworks/base/core/java/android/content/pm/ProviderInfo.aidl \
diff --git a/apct-tests/perftests/core/res/layout/test_simple_view.xml b/apct-tests/perftests/core/res/layout/test_simple_view.xml
new file mode 100644
index 0000000..9bc29a8
--- /dev/null
+++ b/apct-tests/perftests/core/res/layout/test_simple_view.xml
@@ -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.
+-->
+
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/simple_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" />
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java
index 19047d3..922a475 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java
@@ -31,11 +31,38 @@
 
     @Test
     public void testMeasureRenderNodeJniOverhead() {
-        RenderNode node = RenderNode.create("benchmark", null);
-        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        final RenderNode node = RenderNode.create("benchmark", null);
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
 
         while (state.keepRunning()) {
             node.setTranslationX(1.0f);
         }
     }
+
+    @Test
+    public void testCreateRenderNodeNoName() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            RenderNode node = RenderNode.create(null, null);
+            node.destroy();
+        }
+    }
+
+    @Test
+    public void testCreateRenderNode() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            RenderNode node = RenderNode.create("LinearLayout", null);
+            node.destroy();
+        }
+    }
+
+    @Test
+    public void testIsValid() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        RenderNode node = RenderNode.create("LinearLayout", null);
+        while (state.keepRunning()) {
+            node.isValid();
+        }
+    }
 }
diff --git a/apct-tests/perftests/core/src/android/view/ViewPerfTest.java b/apct-tests/perftests/core/src/android/view/ViewPerfTest.java
new file mode 100644
index 0000000..5503ca9
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/view/ViewPerfTest.java
@@ -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.
+ */
+
+package android.view;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+import android.widget.FrameLayout;
+
+import com.android.perftests.core.R;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+@LargeTest
+public class ViewPerfTest {
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void testSimpleViewInflate() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        LayoutInflater inflater = LayoutInflater.from(context);
+        FrameLayout root = new FrameLayout(context);
+        while (state.keepRunning()) {
+            inflater.inflate(R.layout.test_simple_view, root, false);
+        }
+    }
+}
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java b/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
index 519d524..fd393e9 100644
--- a/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
@@ -19,8 +19,11 @@
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.os.Bundle;
+import android.os.Debug;
+import android.support.test.InstrumentationRegistry;
 import android.util.Log;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.concurrent.TimeUnit;
@@ -45,6 +48,7 @@
 public final class BenchmarkState {
 
     private static final String TAG = "BenchmarkState";
+    private static final boolean ENABLE_PROFILING = false;
 
     private static final int NOT_STARTED = 0;  // The benchmark has not started yet.
     private static final int WARMUP = 1; // The benchmark is warming up.
@@ -146,6 +150,11 @@
     }
 
     private void beginBenchmark(long warmupDuration, int iterations) {
+        if (ENABLE_PROFILING) {
+            File f = new File(InstrumentationRegistry.getContext().getDataDir(), "benchprof");
+            Log.d(TAG, "Tracing to: " + f.getAbsolutePath());
+            Debug.startMethodTracingSampling(f.getAbsolutePath(), 16 * 1024 * 1024, 100);
+        }
         mMaxIterations = (int) (TARGET_TEST_DURATION_NS / (warmupDuration / iterations));
         mMaxIterations = Math.min(MAX_TEST_ITERATIONS,
                 Math.max(mMaxIterations, MIN_TEST_ITERATIONS));
@@ -161,6 +170,9 @@
         mResults.add((currentTime - mStartTimeNs - mPausedDurationNs) / mMaxIterations);
         mRepeatCount++;
         if (mRepeatCount >= REPEAT_COUNT) {
+            if (ENABLE_PROFILING) {
+                Debug.stopMethodTracing();
+            }
             calculateSatistics();
             mState = FINISHED;
             return false;
diff --git a/api/current.txt b/api/current.txt
index 9aa8c59..22871fa 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);
@@ -5312,16 +5335,20 @@
   }
 
   public final class NotificationChannel implements android.os.Parcelable {
-    ctor public NotificationChannel(java.lang.String, java.lang.CharSequence);
+    ctor public NotificationChannel(java.lang.String, java.lang.CharSequence, int);
     ctor protected NotificationChannel(android.os.Parcel);
     method public boolean canBypassDnd();
     method public int describeContents();
-    method public android.net.Uri getDefaultRingtone();
     method public java.lang.String getId();
     method public int getImportance();
+    method public int getLockscreenVisibility();
     method public java.lang.CharSequence getName();
-    method public void setDefaultRingtone(android.net.Uri);
+    method public android.net.Uri getRingtone();
+    method public void setBypassDnd(boolean);
+    method public void setImportance(int);
     method public void setLights(boolean);
+    method public void setLockscreenVisibility(int);
+    method public void setRingtone(android.net.Uri);
     method public void setVibration(boolean);
     method public boolean shouldShowLights();
     method public boolean shouldVibrate();
@@ -5353,7 +5380,6 @@
     method public final void setInterruptionFilter(int);
     method public void setNotificationPolicy(android.app.NotificationManager.Policy);
     method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
-    method public void updateNotificationChannel(android.app.NotificationChannel);
     field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_CHANGED = "android.app.action.NOTIFICATION_POLICY_CHANGED";
@@ -6498,6 +6524,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 +6534,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 +10065,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
@@ -14778,6 +14808,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);
   }
@@ -14831,10 +14862,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);
   }
 
@@ -28458,6 +28490,7 @@
     field public static final int M = 23; // 0x17
     field public static final int N = 24; // 0x18
     field public static final int N_MR1 = 25; // 0x19
+    field public static final int O = 10000; // 0x2710
   }
 
   public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -32027,6 +32060,7 @@
     method public static android.net.Uri copyDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri);
     method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String);
     method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri);
+    method public static java.util.List<java.lang.String> findDocumentPath(android.content.ContentResolver, android.net.Uri);
     method public static java.lang.String getDocumentId(android.net.Uri);
     method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal);
     method public static java.lang.String getRootId(android.net.Uri);
@@ -32069,6 +32103,15 @@
     field public static final java.lang.String MIME_TYPE_DIR = "vnd.android.document/directory";
   }
 
+  public static final class DocumentsContract.Path implements android.os.Parcelable {
+    ctor public DocumentsContract.Path(java.lang.String, java.util.List<java.lang.String>);
+    method public int describeContents();
+    method public java.util.List<java.lang.String> getPath();
+    method public java.lang.String getRootId();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.provider.DocumentsContract.Path> CREATOR;
+  }
+
   public static final class DocumentsContract.Root {
     field public static final java.lang.String COLUMN_AVAILABLE_BYTES = "available_bytes";
     field public static final java.lang.String COLUMN_CAPACITY_BYTES = "capacity_bytes";
@@ -32092,6 +32135,7 @@
     method public java.lang.String createDocument(java.lang.String, java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public void deleteDocument(java.lang.String) throws java.io.FileNotFoundException;
+    method public android.provider.DocumentsContract.Path findDocumentPath(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public java.lang.String[] getDocumentStreamTypes(java.lang.String, java.lang.String);
     method public java.lang.String getDocumentType(java.lang.String) throws java.io.FileNotFoundException;
     method public final java.lang.String getType(android.net.Uri);
@@ -37533,6 +37577,7 @@
     method public boolean isWorldPhone();
     method public void listen(android.telephony.PhoneStateListener, int);
     method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
+    method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler);
     method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
     method public boolean setOperatorBrandOverride(java.lang.String);
     method public boolean setPreferredNetworkTypeToGlobal();
@@ -37597,6 +37642,12 @@
     field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
   }
 
+  public static abstract class TelephonyManager.OnReceiveUssdResponseCallback {
+    ctor public TelephonyManager.OnReceiveUssdResponseCallback();
+    method public void onReceiveUssdResponse(java.lang.String, java.lang.CharSequence);
+    method public void onReceiveUssdResponseFailed(java.lang.String, int);
+  }
+
 }
 
 package android.telephony.cdma {
@@ -42338,6 +42389,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);
@@ -44024,8 +44076,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
@@ -63011,6 +63063,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 {
@@ -63020,6 +63073,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 e6e5d38..a8a725e 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
@@ -3819,6 +3819,7 @@
 
   public class ActivityManager {
     method public int addAppTask(android.app.Activity, android.content.Intent, android.app.ActivityManager.TaskDescription, android.graphics.Bitmap);
+    method public void addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int);
     method public boolean clearApplicationUserData();
     method public void clearWatchHeapLimit();
     method public void dumpPackageState(java.io.FileDescriptor, java.lang.String);
@@ -3849,6 +3850,7 @@
     method public void killUid(int, java.lang.String);
     method public void moveTaskToFront(int, int);
     method public void moveTaskToFront(int, int, android.os.Bundle);
+    method public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
     method public deprecated void restartPackage(java.lang.String);
     method public static void setVrThread(int);
     method public void setWatchHeapLimit(long);
@@ -3883,6 +3885,10 @@
     field public long totalMem;
   }
 
+  public static abstract interface ActivityManager.OnUidImportanceListener {
+    method public abstract void onUidImportance(int, int);
+  }
+
   public static class ActivityManager.ProcessErrorStateInfo implements android.os.Parcelable {
     ctor public ActivityManager.ProcessErrorStateInfo();
     method public int describeContents();
@@ -4634,6 +4640,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 +4666,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 +4783,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 +4799,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 +4843,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);
@@ -5459,22 +5487,23 @@
   }
 
   public final class NotificationChannel implements android.os.Parcelable {
-    ctor public NotificationChannel(java.lang.String, java.lang.CharSequence);
+    ctor public NotificationChannel(java.lang.String, java.lang.CharSequence, int);
     ctor protected NotificationChannel(android.os.Parcel);
     method public boolean canBypassDnd();
     method public int describeContents();
-    method public android.net.Uri getDefaultRingtone();
     method public java.lang.String getId();
     method public int getImportance();
     method public int getLockscreenVisibility();
     method public java.lang.CharSequence getName();
+    method public android.net.Uri getRingtone();
+    method public int getUserLockedFields();
+    method public void lockFields(int);
     method public void populateFromXml(org.xmlpull.v1.XmlPullParser);
     method public void setBypassDnd(boolean);
-    method public void setDefaultRingtone(android.net.Uri);
     method public void setImportance(int);
     method public void setLights(boolean);
     method public void setLockscreenVisibility(int);
-    method public void setName(java.lang.CharSequence);
+    method public void setRingtone(android.net.Uri);
     method public void setVibration(boolean);
     method public boolean shouldShowLights();
     method public boolean shouldVibrate();
@@ -5483,6 +5512,12 @@
     method public void writeXml(org.xmlpull.v1.XmlSerializer) throws java.io.IOException;
     field public static final android.os.Parcelable.Creator<android.app.NotificationChannel> CREATOR;
     field public static final java.lang.String DEFAULT_CHANNEL_ID = "miscellaneous";
+    field public static final int USER_LOCKED_IMPORTANCE = 4; // 0x4
+    field public static final int USER_LOCKED_LIGHTS = 8; // 0x8
+    field public static final int USER_LOCKED_PRIORITY = 1; // 0x1
+    field public static final int USER_LOCKED_RINGTONE = 32; // 0x20
+    field public static final int USER_LOCKED_VIBRATION = 16; // 0x10
+    field public static final int USER_LOCKED_VISIBILITY = 2; // 0x2
   }
 
   public class NotificationManager {
@@ -5508,7 +5543,6 @@
     method public final void setInterruptionFilter(int);
     method public void setNotificationPolicy(android.app.NotificationManager.Policy);
     method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
-    method public void updateNotificationChannel(android.app.NotificationChannel);
     field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_CHANGED = "android.app.action.NOTIFICATION_POLICY_CHANGED";
@@ -6788,6 +6822,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 +6832,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 +10499,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 +10508,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
@@ -15988,6 +16027,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);
@@ -16042,10 +16082,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);
   }
 
@@ -30949,6 +30990,7 @@
     field public static final int M = 23; // 0x17
     field public static final int N = 24; // 0x18
     field public static final int N_MR1 = 25; // 0x19
+    field public static final int O = 10000; // 0x2710
   }
 
   public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -34681,6 +34723,7 @@
     method public static android.net.Uri copyDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri);
     method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String);
     method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri);
+    method public static java.util.List<java.lang.String> findDocumentPath(android.content.ContentResolver, android.net.Uri);
     method public static java.lang.String getDocumentId(android.net.Uri);
     method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal);
     method public static java.lang.String getRootId(android.net.Uri);
@@ -34723,6 +34766,15 @@
     field public static final java.lang.String MIME_TYPE_DIR = "vnd.android.document/directory";
   }
 
+  public static final class DocumentsContract.Path implements android.os.Parcelable {
+    ctor public DocumentsContract.Path(java.lang.String, java.util.List<java.lang.String>);
+    method public int describeContents();
+    method public java.util.List<java.lang.String> getPath();
+    method public java.lang.String getRootId();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.provider.DocumentsContract.Path> CREATOR;
+  }
+
   public static final class DocumentsContract.Root {
     field public static final java.lang.String COLUMN_AVAILABLE_BYTES = "available_bytes";
     field public static final java.lang.String COLUMN_CAPACITY_BYTES = "capacity_bytes";
@@ -34746,6 +34798,7 @@
     method public java.lang.String createDocument(java.lang.String, java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public void deleteDocument(java.lang.String) throws java.io.FileNotFoundException;
+    method public android.provider.DocumentsContract.Path findDocumentPath(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public java.lang.String[] getDocumentStreamTypes(java.lang.String, java.lang.String);
     method public java.lang.String getDocumentType(java.lang.String) throws java.io.FileNotFoundException;
     method public final java.lang.String getType(android.net.Uri);
@@ -40673,6 +40726,7 @@
     method public void listen(android.telephony.PhoneStateListener, int);
     method public boolean needsOtaServiceProvisioning();
     method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
+    method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler);
     method public void setDataEnabled(boolean);
     method public void setDataEnabled(int, boolean);
     method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
@@ -40763,6 +40817,12 @@
     field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
   }
 
+  public static abstract class TelephonyManager.OnReceiveUssdResponseCallback {
+    ctor public TelephonyManager.OnReceiveUssdResponseCallback();
+    method public void onReceiveUssdResponse(java.lang.String, java.lang.CharSequence);
+    method public void onReceiveUssdResponseFailed(java.lang.String, int);
+  }
+
 }
 
 package android.telephony.cdma {
@@ -45517,6 +45577,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);
@@ -47206,8 +47267,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
@@ -66549,6 +66610,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 {
@@ -66558,6 +66620,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 ee3cb0d..50dfa2a 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
@@ -3698,6 +3699,7 @@
 
   public class ActivityManager {
     method public int addAppTask(android.app.Activity, android.content.Intent, android.app.ActivityManager.TaskDescription, android.graphics.Bitmap);
+    method public void addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int);
     method public boolean clearApplicationUserData();
     method public void clearWatchHeapLimit();
     method public void dumpPackageState(java.io.FileDescriptor, java.lang.String);
@@ -3711,6 +3713,7 @@
     method public int getMemoryClass();
     method public void getMemoryInfo(android.app.ActivityManager.MemoryInfo);
     method public static void getMyMemoryState(android.app.ActivityManager.RunningAppProcessInfo);
+    method public int getPackageImportance(java.lang.String);
     method public android.os.Debug.MemoryInfo[] getProcessMemoryInfo(int[]);
     method public java.util.List<android.app.ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState();
     method public deprecated java.util.List<android.app.ActivityManager.RecentTaskInfo> getRecentTasks(int, int) throws java.lang.SecurityException;
@@ -3725,6 +3728,7 @@
     method public void killBackgroundProcesses(java.lang.String);
     method public void moveTaskToFront(int, int);
     method public void moveTaskToFront(int, int, android.os.Bundle);
+    method public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
     method public deprecated void restartPackage(java.lang.String);
     method public static void setVrThread(int);
     method public void setWatchHeapLimit(long);
@@ -3759,6 +3763,10 @@
     field public long totalMem;
   }
 
+  public static abstract interface ActivityManager.OnUidImportanceListener {
+    method public abstract void onUidImportance(int, int);
+  }
+
   public static class ActivityManager.ProcessErrorStateInfo implements android.os.Parcelable {
     ctor public ActivityManager.ProcessErrorStateInfo();
     method public int describeContents();
@@ -4492,6 +4500,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 +4526,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 +4643,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 +4659,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 +4703,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);
@@ -5315,16 +5345,20 @@
   }
 
   public final class NotificationChannel implements android.os.Parcelable {
-    ctor public NotificationChannel(java.lang.String, java.lang.CharSequence);
+    ctor public NotificationChannel(java.lang.String, java.lang.CharSequence, int);
     ctor protected NotificationChannel(android.os.Parcel);
     method public boolean canBypassDnd();
     method public int describeContents();
-    method public android.net.Uri getDefaultRingtone();
     method public java.lang.String getId();
     method public int getImportance();
+    method public int getLockscreenVisibility();
     method public java.lang.CharSequence getName();
-    method public void setDefaultRingtone(android.net.Uri);
+    method public android.net.Uri getRingtone();
+    method public void setBypassDnd(boolean);
+    method public void setImportance(int);
     method public void setLights(boolean);
+    method public void setLockscreenVisibility(int);
+    method public void setRingtone(android.net.Uri);
     method public void setVibration(boolean);
     method public boolean shouldShowLights();
     method public boolean shouldVibrate();
@@ -5356,7 +5390,6 @@
     method public final void setInterruptionFilter(int);
     method public void setNotificationPolicy(android.app.NotificationManager.Policy);
     method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
-    method public void updateNotificationChannel(android.app.NotificationChannel);
     field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
     field public static final java.lang.String ACTION_NOTIFICATION_POLICY_CHANGED = "android.app.action.NOTIFICATION_POLICY_CHANGED";
@@ -6507,6 +6540,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 +6550,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 +10080,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 +10089,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
@@ -14795,6 +14833,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);
   }
@@ -14848,10 +14887,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);
   }
 
@@ -28531,6 +28571,7 @@
     field public static final int M = 23; // 0x17
     field public static final int N = 24; // 0x18
     field public static final int N_MR1 = 25; // 0x19
+    field public static final int O = 10000; // 0x2710
   }
 
   public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -32105,6 +32146,7 @@
     method public static android.net.Uri copyDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri);
     method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String);
     method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri);
+    method public static java.util.List<java.lang.String> findDocumentPath(android.content.ContentResolver, android.net.Uri);
     method public static java.lang.String getDocumentId(android.net.Uri);
     method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal);
     method public static java.lang.String getRootId(android.net.Uri);
@@ -32147,6 +32189,15 @@
     field public static final java.lang.String MIME_TYPE_DIR = "vnd.android.document/directory";
   }
 
+  public static final class DocumentsContract.Path implements android.os.Parcelable {
+    ctor public DocumentsContract.Path(java.lang.String, java.util.List<java.lang.String>);
+    method public int describeContents();
+    method public java.util.List<java.lang.String> getPath();
+    method public java.lang.String getRootId();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.provider.DocumentsContract.Path> CREATOR;
+  }
+
   public static final class DocumentsContract.Root {
     field public static final java.lang.String COLUMN_AVAILABLE_BYTES = "available_bytes";
     field public static final java.lang.String COLUMN_CAPACITY_BYTES = "capacity_bytes";
@@ -32170,6 +32221,7 @@
     method public java.lang.String createDocument(java.lang.String, java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public void deleteDocument(java.lang.String) throws java.io.FileNotFoundException;
+    method public android.provider.DocumentsContract.Path findDocumentPath(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public java.lang.String[] getDocumentStreamTypes(java.lang.String, java.lang.String);
     method public java.lang.String getDocumentType(java.lang.String) throws java.io.FileNotFoundException;
     method public final java.lang.String getType(android.net.Uri);
@@ -37614,6 +37666,7 @@
     method public boolean isWorldPhone();
     method public void listen(android.telephony.PhoneStateListener, int);
     method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
+    method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler);
     method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
     method public boolean setOperatorBrandOverride(java.lang.String);
     method public boolean setPreferredNetworkTypeToGlobal();
@@ -37678,6 +37731,12 @@
     field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
   }
 
+  public static abstract class TelephonyManager.OnReceiveUssdResponseCallback {
+    ctor public TelephonyManager.OnReceiveUssdResponseCallback();
+    method public void onReceiveUssdResponse(java.lang.String, java.lang.CharSequence);
+    method public void onReceiveUssdResponseFailed(java.lang.String, int);
+  }
+
 }
 
 package android.telephony.cdma {
@@ -42574,6 +42633,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);
@@ -44260,8 +44320,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
@@ -63263,6 +63323,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 {
@@ -63272,6 +63333,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/am b/cmds/am/am
index 1d426bc..54c2d39 100755
--- a/cmds/am/am
+++ b/cmds/am/am
@@ -1,9 +1,9 @@
 #!/system/bin/sh
-#
-# Script to start "am" on the device, which has a very rudimentary
-# shell.
-#
-base=/system
-export CLASSPATH=$base/framework/am.jar
-exec app_process $base/bin com.android.commands.am.Am "$@"
 
+if [ "$1" != "instrument" ] ; then
+    cmd activity "$@"
+else
+    base=/system
+    export CLASSPATH=$base/framework/am.jar
+    exec app_process $base/bin com.android.commands.am.Am "$@"
+fi
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 91a4549..470a0fa 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -84,34 +84,9 @@
 
 public class Am extends BaseCommand {
 
-    private static final String SHELL_PACKAGE_NAME = "com.android.shell";
-
-    // Is the object moving in a positive direction?
-    private static final boolean MOVING_FORWARD = true;
-    // Is the object moving in the horizontal plan?
-    private static final boolean MOVING_HORIZONTALLY = true;
-    // Is the object current point great then its target point?
-    private static final boolean GREATER_THAN_TARGET = true;
-    // Amount we reduce the stack size by when testing a task re-size.
-    private static final int STACK_BOUNDS_INSET = 10;
-
-    public static final String NO_CLASS_ERROR_CODE = "Error type 3";
     private IActivityManager mAm;
     private IPackageManager mPm;
 
-    private int mStartFlags = 0;
-    private boolean mWaitOption = false;
-    private boolean mStopOption = false;
-
-    private int mRepeat = 0;
-    private int mUserId;
-    private String mReceiverPermission;
-
-    private String mProfileFile;
-    private int mSamplingInterval;
-    private boolean mAutoStop;
-    private int mStackId;
-
     /**
      * Command-line entry point.
      *
@@ -123,249 +98,11 @@
 
     @Override
     public void onShowUsage(PrintStream out) {
-        PrintWriter pw = new PrintWriter(out);
-        pw.println(
-                "usage: am [subcommand] [options]\n" +
-                "usage: am start [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]\n" +
-                "               [--sampling INTERVAL] [-R COUNT] [-S]\n" +
-                "               [--track-allocation] [--user <USER_ID> | current] <INTENT>\n" +
-                "       am startservice [--user <USER_ID> | current] <INTENT>\n" +
-                "       am stopservice [--user <USER_ID> | current] <INTENT>\n" +
-                "       am force-stop [--user <USER_ID> | all | current] <PACKAGE>\n" +
-                "       am kill [--user <USER_ID> | all | current] <PACKAGE>\n" +
-                "       am kill-all\n" +
-                "       am broadcast [--user <USER_ID> | all | current] <INTENT>\n" +
-                "       am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" +
-                "               [--user <USER_ID> | current]\n" +
-                "               [--no-window-animation] [--abi <ABI>] <COMPONENT>\n" +
-                "       am profile start [--user <USER_ID> current] [--sampling INTERVAL] <PROCESS> <FILE>\n" +
-                "       am profile stop [--user <USER_ID> current] [<PROCESS>]\n" +
-                "       am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>\n" +
-                "       am set-debug-app [-w] [--persistent] <PACKAGE>\n" +
-                "       am clear-debug-app\n" +
-                "       am set-watch-heap <PROCESS> <MEM-LIMIT>\n" +
-                "       am clear-watch-heap\n" +
-                "       am bug-report [--progress]\n" +
-                "       am monitor [--gdb <port>]\n" +
-                "       am hang [--allow-restart]\n" +
-                "       am restart\n" +
-                "       am idle-maintenance\n" +
-                "       am screen-compat [on|off] <PACKAGE>\n" +
-                "       am package-importance <PACKAGE>\n" +
-                "       am to-uri [INTENT]\n" +
-                "       am to-intent-uri [INTENT]\n" +
-                "       am to-app-uri [INTENT]\n" +
-                "       am switch-user <USER_ID>\n" +
-                "       am start-user <USER_ID>\n" +
-                "       am unlock-user <USER_ID> [TOKEN_HEX]\n" +
-                "       am stop-user [-w] [-f] <USER_ID>\n" +
-                "       am stack start <DISPLAY_ID> <INTENT>\n" +
-                "       am stack movetask <TASK_ID> <STACK_ID> [true|false]\n" +
-                "       am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
-                "       am stack resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
-                "       am stack resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]\n" +
-                "       am stack size-docked-stack-test: <STEP_SIZE> <l|t|r|b> [DELAY_MS]\n" +
-                "       am stack move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
-                "       am stack positiontask <TASK_ID> <STACK_ID> <POSITION>\n" +
-                "       am stack list\n" +
-                "       am stack info <STACK_ID>\n" +
-                "       am stack remove <STACK_ID>\n" +
-                "       am task lock <TASK_ID>\n" +
-                "       am task lock stop\n" +
-                "       am task resizeable <TASK_ID> [0 (unresizeable) | 1 (crop_windows) | 2 (resizeable) | 3 (resizeable_and_pipable)]\n" +
-                "       am task resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
-                "       am task drag-task-test <TASK_ID> <STEP_SIZE> [DELAY_MS] \n" +
-                "       am task size-task-test <TASK_ID> <STEP_SIZE> [DELAY_MS] \n" +
-                "       am get-config\n" +
-                "       am suppress-resize-config-changes <true|false>\n" +
-                "       am set-inactive [--user <USER_ID>] <PACKAGE> true|false\n" +
-                "       am get-inactive [--user <USER_ID>] <PACKAGE>\n" +
-                "       am send-trim-memory [--user <USER_ID>] <PROCESS>\n" +
-                "               [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]\n" +
-                "       am get-current-user\n" +
-                "\n" +
-                "am start: start an Activity.  Options are:\n" +
-                "    -D: enable debugging\n" +
-                "    -N: enable native debugging\n" +
-                "    -W: wait for launch to complete\n" +
-                "    --start-profiler <FILE>: start profiler and send results to <FILE>\n" +
-                "    --sampling INTERVAL: use sample profiling with INTERVAL microseconds\n" +
-                "        between samples (use with --start-profiler)\n" +
-                "    -P <FILE>: like above, but profiling stops when app goes idle\n" +
-                "    -R: repeat the activity launch <COUNT> times.  Prior to each repeat,\n" +
-                "        the top activity will be finished.\n" +
-                "    -S: force stop the target app before starting the activity\n" +
-                "    --track-allocation: enable tracking of object allocations\n" +
-                "    --user <USER_ID> | current: Specify which user to run as; if not\n" +
-                "        specified then run as the current user.\n" +
-                "    --stack <STACK_ID>: Specify into which stack should the activity be put.\n" +
-                "\n" +
-                "am startservice: start a Service.  Options are:\n" +
-                "    --user <USER_ID> | current: Specify which user to run as; if not\n" +
-                "        specified then run as the current user.\n" +
-                "\n" +
-                "am stopservice: stop a Service.  Options are:\n" +
-                "    --user <USER_ID> | current: Specify which user to run as; if not\n" +
-                "        specified then run as the current user.\n" +
-                "\n" +
-                "am force-stop: force stop everything associated with <PACKAGE>.\n" +
-                "    --user <USER_ID> | all | current: Specify user to force stop;\n" +
-                "        all users if not specified.\n" +
-                "\n" +
-                "am kill: Kill all processes associated with <PACKAGE>.  Only kills.\n" +
-                "  processes that are safe to kill -- that is, will not impact the user\n" +
-                "  experience.\n" +
-                "    --user <USER_ID> | all | current: Specify user whose processes to kill;\n" +
-                "        all users if not specified.\n" +
-                "\n" +
-                "am kill-all: Kill all background processes.\n" +
-                "\n" +
-                "am broadcast: send a broadcast Intent.  Options are:\n" +
-                "    --user <USER_ID> | all | current: Specify which user to send to; if not\n" +
-                "        specified then send to all users.\n" +
-                "    --receiver-permission <PERMISSION>: Require receiver to hold permission.\n" +
-                "\n" +
-                "am instrument: start an Instrumentation.  Typically this target <COMPONENT>\n" +
-                "  is the form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there \n" +
-                "  is only one instrumentation.  Options are:\n" +
-                "    -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT).  Use with\n" +
-                "        [-e perf true] to generate raw output for performance measurements.\n" +
-                "    -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" +
-                "        current user if not specified.\n" +
-                "    --no-window-animation: turn off window animations while running.\n" +
-                "    --abi <ABI>: Launch the instrumented process with the selected ABI.\n"  +
-                "        This assumes that the process supports the selected ABI.\n" +
-                "\n" +
-                "am trace-ipc: Trace IPC transactions.\n" +
-                "  start: start tracing IPC transactions.\n" +
-                "  stop: stop tracing IPC transactions and dump the results to file.\n" +
-                "    --dump-file <FILE>: Specify the file the trace should be dumped to.\n" +
-                "\n" +
-                "am profile: start and stop profiler on a process.  The given <PROCESS> argument\n" +
-                "  may be either a process name or pid.  Options are:\n" +
-                "    --user <USER_ID> | current: When supplying a process name,\n" +
-                "        specify user of process to profile; uses current user if not specified.\n" +
-                "\n" +
-                "am dumpheap: dump the heap of a process.  The given <PROCESS> argument may\n" +
-                "  be either a process name or pid.  Options are:\n" +
-                "    -n: dump native heap instead of managed heap\n" +
-                "    --user <USER_ID> | current: When supplying a process name,\n" +
-                "        specify user of process to dump; uses current user if not specified.\n" +
-                "\n" +
-                "am set-debug-app: set application <PACKAGE> to debug.  Options are:\n" +
-                "    -w: wait for debugger when application starts\n" +
-                "    --persistent: retain this value\n" +
-                "\n" +
-                "am clear-debug-app: clear the previously set-debug-app.\n" +
-                "\n" +
-                "am set-watch-heap: start monitoring pss size of <PROCESS>, if it is at or\n" +
-                "    above <HEAP-LIMIT> then a heap dump is collected for the user to report\n" +
-                "\n" +
-                "am clear-watch-heap: clear the previously set-watch-heap.\n" +
-                "\n" +
-                "am bug-report: request bug report generation; will launch a notification\n" +
-                "    when done to select where it should be delivered. Options are: \n" +
-                "   --progress: will launch a notification right away to show its progress.\n" +
-                "\n" +
-                "am monitor: start monitoring for crashes or ANRs.\n" +
-                "    --gdb: start gdbserv on the given port at crash/ANR\n" +
-                "\n" +
-                "am hang: hang the system.\n" +
-                "    --allow-restart: allow watchdog to perform normal system restart\n" +
-                "\n" +
-                "am restart: restart the user-space system.\n" +
-                "\n" +
-                "am idle-maintenance: perform idle maintenance now.\n" +
-                "\n" +
-                "am screen-compat: control screen compatibility mode of <PACKAGE>.\n" +
-                "\n" +
-                "am package-importance: print current importance of <PACKAGE>.\n" +
-                "\n" +
-                "am to-uri: print the given Intent specification as a URI.\n" +
-                "\n" +
-                "am to-intent-uri: print the given Intent specification as an intent: URI.\n" +
-                "\n" +
-                "am to-app-uri: print the given Intent specification as an android-app: URI.\n" +
-                "\n" +
-                "am switch-user: switch to put USER_ID in the foreground, starting\n" +
-                "  execution of that user if it is currently stopped.\n" +
-                "\n" +
-                "am start-user: start USER_ID in background if it is currently stopped,\n" +
-                "  use switch-user if you want to start the user in foreground.\n" +
-                "\n" +
-                "am stop-user: stop execution of USER_ID, not allowing it to run any\n" +
-                "  code until a later explicit start or switch to it.\n" +
-                "  -w: wait for stop-user to complete.\n" +
-                "  -f: force stop even if there are related users that cannot be stopped.\n" +
-                "\n" +
-                "am stack start: start a new activity on <DISPLAY_ID> using <INTENT>.\n" +
-                "\n" +
-                "am stack movetask: move <TASK_ID> from its current stack to the top (true) or" +
-                "   bottom (false) of <STACK_ID>.\n" +
-                "\n" +
-                "am stack resize: change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.\n" +
-                "\n" +
-                "am stack resize-docked-stack: change docked stack to <LEFT,TOP,RIGHT,BOTTOM>\n" +
-                "   and supplying temporary different task bounds indicated by\n" +
-                "   <TASK_LEFT,TOP,RIGHT,BOTTOM>\n" +
-                "\n" +
-                "am stack size-docked-stack-test: test command for sizing docked stack by\n" +
-                "   <STEP_SIZE> increments from the side <l>eft, <t>op, <r>ight, or <b>ottom\n" +
-                "   applying the optional [DELAY_MS] between each step.\n" +
-                "\n" +
-                "am stack move-top-activity-to-pinned-stack: moves the top activity from\n" +
-                "   <STACK_ID> to the pinned stack using <LEFT,TOP,RIGHT,BOTTOM> for the\n" +
-                "   bounds of the pinned stack.\n" +
-                "\n" +
-                "am stack positiontask: place <TASK_ID> in <STACK_ID> at <POSITION>" +
-                "\n" +
-                "am stack list: list all of the activity stacks and their sizes.\n" +
-                "\n" +
-                "am stack info: display the information about activity stack <STACK_ID>.\n" +
-                "\n" +
-                "am stack remove: remove stack <STACK_ID>.\n" +
-                "\n" +
-                "am task lock: bring <TASK_ID> to the front and don't allow other tasks to run.\n" +
-                "\n" +
-                "am task lock stop: end the current task lock.\n" +
-                "\n" +
-                "am task resizeable: change resizeable mode of <TASK_ID>.\n" +
-                "   0 (unresizeable) | 1 (crop_windows) | 2 (resizeable) | 3 (resizeable_and_pipable)\n" +
-                "\n" +
-                "am task resize: makes sure <TASK_ID> is in a stack with the specified bounds.\n" +
-                "   Forces the task to be resizeable and creates a stack if no existing stack\n" +
-                "   has the specified bounds.\n" +
-                "\n" +
-                "am task drag-task-test: test command for dragging/moving <TASK_ID> by\n" +
-                "   <STEP_SIZE> increments around the screen applying the optional [DELAY_MS]\n" +
-                "   between each step.\n" +
-                "\n" +
-                "am task size-task-test: test command for sizing <TASK_ID> by <STEP_SIZE>" +
-                "   increments within the screen applying the optional [DELAY_MS] between\n" +
-                "   each step.\n" +
-                "\n" +
-                "am get-config: retrieve the configuration and any recent configurations\n" +
-                "  of the device.\n" +
-                "am suppress-resize-config-changes: suppresses configuration changes due to\n" +
-                "  user resizing an activity/task.\n" +
-                "\n" +
-                "am set-inactive: sets the inactive state of an app.\n" +
-                "\n" +
-                "am get-inactive: returns the inactive state of an app.\n" +
-                "\n" +
-                "am send-trim-memory: send a memory trim event to a <PROCESS>.\n" +
-                "\n" +
-                "am get-current-user: returns id of the current foreground user.\n" +
-                "\n"
-        );
-        Intent.printIntentArgsHelp(pw, "");
-        pw.flush();
+        try {
+            runAmCmd(new String[] { "help" });
+        } catch (AndroidException e) {
+            e.printStackTrace(System.err);
+        }
     }
 
     @Override
@@ -385,9 +122,7 @@
 
         String op = nextArgRequired();
 
-        if (op.equals("broadcast")) {
-            sendBroadcast();
-        } else if (op.equals("instrument")) {
+        if (op.equals("instrument")) {
             runInstrument();
         } else {
             runAmCmd(getRawArgs());
@@ -458,90 +193,6 @@
         }
     }
 
-    private Intent makeIntent(int defUser) throws URISyntaxException {
-        mStartFlags = 0;
-        mWaitOption = false;
-        mStopOption = false;
-        mRepeat = 0;
-        mProfileFile = null;
-        mSamplingInterval = 0;
-        mAutoStop = false;
-        mUserId = defUser;
-        mStackId = INVALID_STACK_ID;
-
-        return Intent.parseCommandArgs(mArgs, new Intent.CommandOptionHandler() {
-            @Override
-            public boolean handleOption(String opt, ShellCommand cmd) {
-                if (opt.equals("-D")) {
-                    mStartFlags |= ActivityManager.START_FLAG_DEBUG;
-                } else if (opt.equals("-N")) {
-                    mStartFlags |= ActivityManager.START_FLAG_NATIVE_DEBUGGING;
-                } else if (opt.equals("-W")) {
-                    mWaitOption = true;
-                } else if (opt.equals("-P")) {
-                    mProfileFile = nextArgRequired();
-                    mAutoStop = true;
-                } else if (opt.equals("--start-profiler")) {
-                    mProfileFile = nextArgRequired();
-                    mAutoStop = false;
-                } else if (opt.equals("--sampling")) {
-                    mSamplingInterval = Integer.parseInt(nextArgRequired());
-                } else if (opt.equals("-R")) {
-                    mRepeat = Integer.parseInt(nextArgRequired());
-                } else if (opt.equals("-S")) {
-                    mStopOption = true;
-                } else if (opt.equals("--track-allocation")) {
-                    mStartFlags |= ActivityManager.START_FLAG_TRACK_ALLOCATION;
-                } else if (opt.equals("--user")) {
-                    mUserId = UserHandle.parseUserArg(nextArgRequired());
-                } else if (opt.equals("--receiver-permission")) {
-                    mReceiverPermission = nextArgRequired();
-                } else if (opt.equals("--stack")) {
-                    mStackId = Integer.parseInt(nextArgRequired());
-                } else {
-                    return false;
-                }
-                return true;
-            }
-        });
-    }
-
-    private class IntentReceiver extends IIntentReceiver.Stub {
-        private boolean mFinished = false;
-
-        @Override
-        public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
-                boolean ordered, boolean sticky, int sendingUser) {
-            String line = "Broadcast completed: result=" + resultCode;
-            if (data != null) line = line + ", data=\"" + data + "\"";
-            if (extras != null) line = line + ", extras: " + extras;
-            System.out.println(line);
-            synchronized (this) {
-                mFinished = true;
-                notifyAll();
-            }
-        }
-
-        public synchronized void waitForFinish() {
-            try {
-                while (!mFinished) wait();
-            } catch (InterruptedException e) {
-                throw new IllegalStateException(e);
-            }
-        }
-    }
-
-    private void sendBroadcast() throws Exception {
-        Intent intent = makeIntent(UserHandle.USER_CURRENT);
-        IntentReceiver receiver = new IntentReceiver();
-        String[] requiredPermissions = mReceiverPermission == null ? null
-                : new String[] {mReceiverPermission};
-        System.out.println("Broadcasting: " + intent);
-        mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, requiredPermissions,
-                android.app.AppOpsManager.OP_NONE, null, true, false, mUserId);
-        receiver.waitForFinish();
-    }
-
     public void runInstrument() throws Exception {
         Instrument instrument = new Instrument(mAm, mPm);
 
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/appops/appops b/cmds/appops/appops
index 25d2031..5dc85aa 100755
--- a/cmds/appops/appops
+++ b/cmds/appops/appops
@@ -1 +1,2 @@
-cmd appops $@
+#!/system/bin/sh
+cmd appops "$@"
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 3c2efd8..7967e2a 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -74,6 +74,7 @@
 static const char LAST_TIME_CHANGED_FILE_PATH[] = "/data/system/time/last_time_change";
 static const char ACCURATE_TIME_FLAG_FILE_NAME[] = "time_is_accurate";
 static const char ACCURATE_TIME_FLAG_FILE_PATH[] = "/data/system/time/time_is_accurate";
+static const char TIME_FORMAT_12_HOUR_FLAG_FILE_PATH[] = "/data/system/time/time_format_12_hour";
 // Java timestamp format. Don't show the clock if the date is before 2000-01-01 00:00:00.
 static const long long ACCURATE_TIME_EPOCH = 946684800000;
 static constexpr char FONT_BEGIN_CHAR = ' ';
@@ -99,7 +100,7 @@
 // ---------------------------------------------------------------------------
 
 BootAnimation::BootAnimation() : Thread(false), mClockEnabled(true), mTimeIsAccurate(false),
-        mTimeCheckThread(NULL) {
+        mTimeFormat12Hour(false), mTimeCheckThread(NULL) {
     mSession = new SurfaceComposerClient();
 
     // If the system has already booted, the animation is not being used for a boot.
@@ -587,9 +588,10 @@
     glBindTexture(GL_TEXTURE_2D, 0);
 }
 
-// We render 24 hour time.
+// We render 12 or 24 hour time.
 void BootAnimation::drawClock(const Font& font, const int xPos, const int yPos) {
-    static constexpr char TIME_FORMAT[] = "%H:%M";
+    static constexpr char TIME_FORMAT_12[] = "%l:%M";
+    static constexpr char TIME_FORMAT_24[] = "%H:%M";
     static constexpr int TIME_LENGTH = 6;
 
     time_t rawtime;
@@ -597,7 +599,8 @@
     struct tm* timeInfo = localtime(&rawtime);
 
     char timeBuff[TIME_LENGTH];
-    size_t length = strftime(timeBuff, TIME_LENGTH, TIME_FORMAT, timeInfo);
+    const char* timeFormat = mTimeFormat12Hour ? TIME_FORMAT_12 : TIME_FORMAT_24;
+    size_t length = strftime(timeBuff, TIME_LENGTH, timeFormat, timeInfo);
 
     if (length != TIME_LENGTH - 1) {
         ALOGE("Couldn't format time; abandoning boot animation clock");
@@ -1059,6 +1062,11 @@
     }
 
     struct stat statResult;
+
+    if(stat(TIME_FORMAT_12_HOUR_FLAG_FILE_PATH, &statResult) == 0) {
+        mTimeFormat12Hour = true;
+    }
+
     if(stat(ACCURATE_TIME_FLAG_FILE_PATH, &statResult) == 0) {
         mTimeIsAccurate = true;
         return true;
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 42759f1..7a2e4c2 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -152,6 +152,7 @@
     sp<Surface> mFlingerSurface;
     bool        mClockEnabled;
     bool        mTimeIsAccurate;
+    bool        mTimeFormat12Hour;
     bool        mSystemBoot;
     String8     mZipFileName;
     SortedVector<String8> mLoadedFiles;
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index c7474a11..132a4f8 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -17,8 +17,8 @@
 package com.android.commands.content;
 
 import android.app.ActivityManagerNative;
+import android.app.ContentProviderHolder;
 import android.app.IActivityManager;
-import android.app.IActivityManager.ContentProviderHolder;
 import android.content.ContentValues;
 import android.content.IContentProvider;
 import android.database.Cursor;
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/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 7bf073b..a41f122 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -177,7 +177,7 @@
         if (png) {
             const SkImageInfo info = SkImageInfo::Make(w, h, flinger2skia(f),
                                                        kPremul_SkAlphaType);
-            SkAutoTUnref<SkData> data(SkImageEncoder::EncodeData(info, base, s*bytesPerPixel(f),
+            sk_sp<SkData> data(SkImageEncoder::EncodeData(info, base, s*bytesPerPixel(f),
                     SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality));
             if (data.get()) {
                 write(fd, data->data(), data->size());
diff --git a/cmds/settings/Android.mk b/cmds/settings/Android.mk
index 05deb99..8a8d1bb 100644
--- a/cmds/settings/Android.mk
+++ b/cmds/settings/Android.mk
@@ -3,11 +3,6 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := settings
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_JAVA_LIBRARY)
-
 include $(CLEAR_VARS)
 LOCAL_MODULE := settings
 LOCAL_SRC_FILES := settings
diff --git a/cmds/settings/settings b/cmds/settings/settings
index ef459ca..d41ccc62 100755
--- a/cmds/settings/settings
+++ b/cmds/settings/settings
@@ -1,5 +1,2 @@
-# Script to start "settings" on the device
-#
-base=/system
-export CLASSPATH=$base/framework/settings.jar
-exec app_process $base/bin com.android.commands.settings.SettingsCmd "$@"
+#!/system/bin/sh
+cmd settings "$@"
diff --git a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
deleted file mode 100644
index e63a1f5..0000000
--- a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.commands.settings;
-
-import android.app.ActivityManagerNative;
-import android.app.IActivityManager;
-import android.app.IActivityManager.ContentProviderHolder;
-import android.content.IContentProvider;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-public final class SettingsCmd {
-
-    enum CommandVerb {
-        UNSPECIFIED,
-        GET,
-        PUT,
-        DELETE,
-        LIST,
-    }
-
-    static String[] mArgs;
-    int mNextArg;
-    int mUser = -1;     // unspecified
-    CommandVerb mVerb = CommandVerb.UNSPECIFIED;
-    String mTable = null;
-    String mKey = null;
-    String mValue = null;
-
-    public static void main(String[] args) {
-        if (args == null || args.length < 2) {
-            printUsage();
-            return;
-        }
-
-        mArgs = args;
-        try {
-            new SettingsCmd().run();
-        } catch (Exception e) {
-            System.err.println("Unable to run settings command");
-        }
-    }
-
-    public void run() {
-        boolean valid = false;
-        String arg;
-        try {
-            while ((arg = nextArg()) != null) {
-                if ("--user".equals(arg)) {
-                    if (mUser != -1) {
-                        // --user specified more than once; invalid
-                        break;
-                    }
-                    arg = nextArg();
-                    if ("current".equals(arg) || "cur".equals(arg)) {
-                        mUser = UserHandle.USER_CURRENT;
-                    } else {
-                        mUser = Integer.parseInt(arg);
-                    }
-                } else if (mVerb == CommandVerb.UNSPECIFIED) {
-                    if ("get".equalsIgnoreCase(arg)) {
-                        mVerb = CommandVerb.GET;
-                    } else if ("put".equalsIgnoreCase(arg)) {
-                        mVerb = CommandVerb.PUT;
-                    } else if ("delete".equalsIgnoreCase(arg)) {
-                        mVerb = CommandVerb.DELETE;
-                    } else if ("list".equalsIgnoreCase(arg)) {
-                        mVerb = CommandVerb.LIST;
-                    } else {
-                        // invalid
-                        System.err.println("Invalid command: " + arg);
-                        break;
-                    }
-                } else if (mTable == null) {
-                    if (!"system".equalsIgnoreCase(arg)
-                            && !"secure".equalsIgnoreCase(arg)
-                            && !"global".equalsIgnoreCase(arg)) {
-                        System.err.println("Invalid namespace '" + arg + "'");
-                        break;  // invalid
-                    }
-                    mTable = arg.toLowerCase();
-                    if (mVerb == CommandVerb.LIST) {
-                        valid = true;
-                        break;
-                    }
-                } else if (mVerb == CommandVerb.GET || mVerb == CommandVerb.DELETE) {
-                    mKey = arg;
-                    if (mNextArg >= mArgs.length) {
-                        valid = true;
-                    } else {
-                        System.err.println("Too many arguments");
-                    }
-                    break;
-                } else if (mKey == null) {
-                    mKey = arg;
-                    // keep going; there's another PUT arg
-                } else {    // PUT, final arg
-                    mValue = arg;
-                    if (mNextArg >= mArgs.length) {
-                        valid = true;
-                    } else {
-                        System.err.println("Too many arguments");
-                    }
-                    break;
-                }
-            }
-        } catch (Exception e) {
-            valid = false;
-        }
-
-        if (valid) {
-            try {
-                IActivityManager activityManager = ActivityManagerNative.getDefault();
-                if (mUser == UserHandle.USER_CURRENT) {
-                    mUser = activityManager.getCurrentUser().id;
-                }
-                if (mUser < 0) {
-                    mUser = UserHandle.USER_SYSTEM;
-                }
-                IContentProvider provider = null;
-                IBinder token = new Binder();
-                try {
-                    ContentProviderHolder holder = activityManager.getContentProviderExternal(
-                            "settings", UserHandle.USER_SYSTEM, token);
-                    if (holder == null) {
-                        throw new IllegalStateException("Could not find settings provider");
-                    }
-                    provider = holder.provider;
-
-                    switch (mVerb) {
-                        case GET:
-                            System.out.println(getForUser(provider, mUser, mTable, mKey));
-                            break;
-                        case PUT:
-                            putForUser(provider, mUser, mTable, mKey, mValue);
-                            break;
-                        case DELETE:
-                            System.out.println("Deleted "
-                                    + deleteForUser(provider, mUser, mTable, mKey) + " rows");
-                            break;
-                        case LIST:
-                            for (String line : listForUser(provider, mUser, mTable)) {
-                                System.out.println(line);
-                            }
-                            break;
-                        default:
-                            System.err.println("Unspecified command");
-                            break;
-                    }
-
-                } finally {
-                    if (provider != null) {
-                        activityManager.removeContentProviderExternal("settings", token);
-                    }
-                }
-            } catch (Exception e) {
-                System.err.println("Error while accessing settings provider");
-                e.printStackTrace();
-            }
-
-        } else {
-            printUsage();
-        }
-    }
-
-    private List<String> listForUser(IContentProvider provider, int userHandle, String table) {
-        final Uri uri = "system".equals(table) ? Settings.System.CONTENT_URI
-                : "secure".equals(table) ? Settings.Secure.CONTENT_URI
-                : "global".equals(table) ? Settings.Global.CONTENT_URI
-                : null;
-        final ArrayList<String> lines = new ArrayList<String>();
-        if (uri == null) {
-            return lines;
-        }
-        try {
-            final Cursor cursor = provider.query(resolveCallingPackage(), uri, null, null, null,
-                    null, null);
-            try {
-                while (cursor != null && cursor.moveToNext()) {
-                    lines.add(cursor.getString(1) + "=" + cursor.getString(2));
-                }
-            } finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-            Collections.sort(lines);
-        } catch (RemoteException e) {
-            System.err.println("List failed in " + table + " for user " + userHandle);
-        }
-        return lines;
-    }
-
-    private String nextArg() {
-        if (mNextArg >= mArgs.length) {
-            return null;
-        }
-        String arg = mArgs[mNextArg];
-        mNextArg++;
-        return arg;
-    }
-
-    String getForUser(IContentProvider provider, int userHandle,
-            final String table, final String key) {
-        final String callGetCommand;
-        if ("system".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_SYSTEM;
-        else if ("secure".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_SECURE;
-        else if ("global".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_GLOBAL;
-        else {
-            System.err.println("Invalid table; no put performed");
-            throw new IllegalArgumentException("Invalid table " + table);
-        }
-
-        String result = null;
-        try {
-            Bundle arg = new Bundle();
-            arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
-            Bundle b = provider.call(resolveCallingPackage(), callGetCommand, key, arg);
-            if (b != null) {
-                result = b.getPairValue();
-            }
-        } catch (RemoteException e) {
-            System.err.println("Can't read key " + key + " in " + table + " for user " + userHandle);
-        }
-        return result;
-    }
-
-    void putForUser(IContentProvider provider, int userHandle,
-            final String table, final String key, final String value) {
-        final String callPutCommand;
-        if ("system".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_SYSTEM;
-        else if ("secure".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_SECURE;
-        else if ("global".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_GLOBAL;
-        else {
-            System.err.println("Invalid table; no put performed");
-            return;
-        }
-
-        try {
-            Bundle arg = new Bundle();
-            arg.putString(Settings.NameValueTable.VALUE, value);
-            arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
-            provider.call(resolveCallingPackage(), callPutCommand, key, arg);
-        } catch (RemoteException e) {
-            System.err.println("Can't set key " + key + " in " + table + " for user " + userHandle);
-        }
-    }
-
-    int deleteForUser(IContentProvider provider, int userHandle,
-            final String table, final String key) {
-        Uri targetUri;
-        if ("system".equals(table)) targetUri = Settings.System.getUriFor(key);
-        else if ("secure".equals(table)) targetUri = Settings.Secure.getUriFor(key);
-        else if ("global".equals(table)) targetUri = Settings.Global.getUriFor(key);
-        else {
-            System.err.println("Invalid table; no delete performed");
-            throw new IllegalArgumentException("Invalid table " + table);
-        }
-
-        int num = 0;
-        try {
-            num = provider.delete(resolveCallingPackage(), targetUri, null, null);
-        } catch (RemoteException e) {
-            System.err.println("Can't clear key " + key + " in " + table + " for user "
-                    + userHandle);
-        }
-        return num;
-    }
-
-    private static void printUsage() {
-        System.err.println("usage:  settings [--user <USER_ID> | current] get namespace key");
-        System.err.println("        settings [--user <USER_ID> | current] put namespace key value");
-        System.err.println("        settings [--user <USER_ID> | current] delete namespace key");
-        System.err.println("        settings [--user <USER_ID> | current] list namespace");
-        System.err.println("\n'namespace' is one of {system, secure, global}, case-insensitive");
-        System.err.println("If '--user <USER_ID> | current' is not given, the operations are "
-                + "performed on the system user.");
-    }
-
-    public static String resolveCallingPackage() {
-        switch (android.os.Process.myUid()) {
-            case Process.ROOT_UID: {
-                return "root";
-            }
-
-            case Process.SHELL_UID: {
-                return "com.android.shell";
-            }
-
-            default: {
-                return null;
-            }
-        }
-    }
-}
diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
index cb39e37..8681166 100644
--- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
+++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java
@@ -17,8 +17,8 @@
 package com.android.uiautomator.core;
 
 import android.app.ActivityManagerNative;
+import android.app.ContentProviderHolder;
 import android.app.IActivityManager;
-import android.app.IActivityManager.ContentProviderHolder;
 import android.app.UiAutomation;
 import android.content.Context;
 import android.content.IContentProvider;
diff --git a/compiled-classes-phone b/compiled-classes-phone
index 6214306..8428e41 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
@@ -246,6 +245,8 @@
 android.app.BackStackState
 android.app.BackStackState$1
 android.app.BroadcastOptions
+android.app.ContentProviderHolder
+android.app.ContentProviderHolder$1
 android.app.ContextImpl
 android.app.ContextImpl$1
 android.app.ContextImpl$ApplicationContentResolver
@@ -299,9 +300,8 @@
 android.app.IActivityContainerCallback
 android.app.IActivityController
 android.app.IActivityManager
-android.app.IActivityManager$ContentProviderHolder
-android.app.IActivityManager$ContentProviderHolder$1
-android.app.IActivityManager$WaitResult
+android.app.IActivityManager$Stub
+android.app.IActivityManager$Stub$Proxy
 android.app.IAlarmCompleteListener
 android.app.IAlarmCompleteListener$Stub
 android.app.IAlarmListener
@@ -313,6 +313,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
@@ -520,6 +522,7 @@
 android.app.TimePickerDialog
 android.app.TimePickerDialog$OnTimeSetListener
 android.app.UiModeManager
+android.app.WaitResult;
 android.app.WallpaperInfo
 android.app.WallpaperManager
 android.app.WallpaperManager$Globals
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 163e7d2..b311c21 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -334,7 +334,8 @@
     public static final int GLOBAL_ACTION_HOME = 2;
 
     /**
-     * Action to toggle showing the overview of recent apps
+     * Action to toggle showing the overview of recent apps. Will fail on platforms that don't
+     * show recent apps.
      */
     public static final int GLOBAL_ACTION_RECENTS = 3;
 
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index cb3eba6..b3e2f57 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -6047,8 +6047,8 @@
         boolean drawComplete;
         try {
             mTranslucentCallback = callback;
-            mChangeCanvasToTranslucent =
-                    ActivityManagerNative.getDefault().convertToTranslucent(mToken, options);
+            mChangeCanvasToTranslucent = ActivityManagerNative.getDefault().convertToTranslucent(
+                    mToken, options == null ? null : options.toBundle());
             WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false);
             drawComplete = true;
         } catch (RemoteException e) {
@@ -6092,7 +6092,8 @@
      */
     ActivityOptions getActivityOptions() {
         try {
-            return ActivityManagerNative.getDefault().getActivityOptions(mToken);
+            return ActivityOptions.fromBundle(
+                    ActivityManagerNative.getDefault().getActivityOptions(mToken));
         } catch (RemoteException e) {
         }
         return null;
@@ -6988,7 +6989,7 @@
      */
     public void startLockTask() {
         try {
-            ActivityManagerNative.getDefault().startLockTaskMode(mToken);
+            ActivityManagerNative.getDefault().startLockTaskModeByToken(mToken);
         } catch (RemoteException e) {
         }
     }
diff --git a/core/java/android/app/ActivityManager.aidl b/core/java/android/app/ActivityManager.aidl
index 92350da..5672f6b 100644
--- a/core/java/android/app/ActivityManager.aidl
+++ b/core/java/android/app/ActivityManager.aidl
@@ -16,4 +16,14 @@
 
 package android.app;
 
+parcelable ActivityManager.MemoryInfo;
+parcelable ActivityManager.ProcessErrorStateInfo;
 parcelable ActivityManager.RecentTaskInfo;
+parcelable ActivityManager.TaskDescription;
+parcelable ActivityManager.RunningAppProcessInfo;
+parcelable ActivityManager.RunningServiceInfo;
+parcelable ActivityManager.RunningTaskInfo;
+/** @hide */
+parcelable ActivityManager.StackInfo;
+/** @hide */
+parcelable ActivityManager.TaskThumbnail;
\ No newline at end of file
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 0d9be5f..9af7d8b 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Canvas;
@@ -61,7 +62,9 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.DisplayMetrics;
+import android.util.Singleton;
 import android.util.Size;
 
 import org.xmlpull.v1.XmlSerializer;
@@ -86,6 +89,49 @@
     private final Context mContext;
     private final Handler mHandler;
 
+    static final class UidObserver extends IUidObserver.Stub {
+        final OnUidImportanceListener mListener;
+        final int mImportanceCutpoint;
+        int mLastImportance;
+
+        UidObserver(OnUidImportanceListener listener, int importanceCutpoint) {
+            mListener = listener;
+            mImportanceCutpoint = importanceCutpoint;
+        }
+
+        @Override
+        public void onUidStateChanged(int uid, int procState) {
+            final boolean lastAboveCut = mLastImportance <= mImportanceCutpoint;
+            final int importance = RunningAppProcessInfo.procStateToImportance(procState);
+            final boolean newAboveCut = importance <= mImportanceCutpoint;
+            /*
+            Log.d(TAG, "Uid " + uid + " state change from " + mLastImportance + " to "
+                    + importance + " @ cut " + mImportanceCutpoint
+                    + ": lastAbove=" + lastAboveCut + " newAbove=" + newAboveCut);
+            */
+            mLastImportance = importance;
+            if (lastAboveCut != newAboveCut) {
+                mListener.onUidImportance(uid, importance);
+            }
+        }
+
+        @Override
+        public void onUidGone(int uid) {
+            mLastImportance = RunningAppProcessInfo.IMPORTANCE_GONE;
+            mListener.onUidImportance(uid, RunningAppProcessInfo.IMPORTANCE_GONE);
+        }
+
+        @Override
+        public void onUidActive(int uid) {
+        }
+
+        @Override
+        public void onUidIdle(int uid) {
+        }
+    }
+
+    final ArrayMap<OnUidImportanceListener, UidObserver> mImportanceListeners = new ArrayMap<>();
+
     /**
      * Defines acceptable types of bugreports.
      * @hide
@@ -1687,7 +1733,7 @@
      */
     public List<ActivityManager.AppTask> getAppTasks() {
         ArrayList<AppTask> tasks = new ArrayList<AppTask>();
-        List<IAppTask> appTasks;
+        List<IBinder> appTasks;
         try {
             appTasks = ActivityManagerNative.getDefault().getAppTasks(mContext.getPackageName());
         } catch (RemoteException e) {
@@ -1695,7 +1741,7 @@
         }
         int numAppTasks = appTasks.size();
         for (int i = 0; i < numAppTasks; i++) {
-            tasks.add(new AppTask(appTasks.get(i)));
+            tasks.add(new AppTask(IAppTask.Stub.asInterface(appTasks.get(i))));
         }
         return tasks;
     }
@@ -3044,10 +3090,11 @@
      * running its code, {@link RunningAppProcessInfo#IMPORTANCE_GONE} is returned.
      * @hide
      */
-    @SystemApi
+    @SystemApi @TestApi
+    @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
     public int getPackageImportance(String packageName) {
         try {
-            int procState = ActivityManagerNative.getDefault().getPackageProcessState(packageName,
+            int procState = getService().getPackageProcessState(packageName,
                     mContext.getOpPackageName());
             return RunningAppProcessInfo.procStateToImportance(procState);
         } catch (RemoteException e) {
@@ -3056,6 +3103,83 @@
     }
 
     /**
+     * Callback to get reports about changes to the importance of a uid.  Use with
+     * {@link #addOnUidImportanceListener}.
+     * @hide
+     */
+    @SystemApi @TestApi
+    public interface OnUidImportanceListener {
+        /**
+         * The importance if a given uid has changed.  Will be one of the importance
+         * values in {@link RunningAppProcessInfo};
+         * {@link RunningAppProcessInfo#IMPORTANCE_GONE IMPORTANCE_GONE} will be reported
+         * when the uid is no longer running at all.  This callback will happen on a thread
+         * from a thread pool, not the main UI thread.
+         * @param uid The uid whose importance has changed.
+         * @param importance The new importance value as per {@link RunningAppProcessInfo}.
+         */
+        void onUidImportance(int uid, int importance);
+    }
+
+    /**
+     * Start monitoring changes to the imoportance of uids running in the system.
+     * @param listener The listener callback that will receive change reports.
+     * @param importanceCutpoint The level of importance in which the caller is interested
+     * in differences.  For example, if {@link RunningAppProcessInfo#IMPORTANCE_PERCEPTIBLE}
+     * is used here, you will receive a call each time a uids importance transitions between
+     * being <= {@link RunningAppProcessInfo#IMPORTANCE_PERCEPTIBLE} and
+     * > {@link RunningAppProcessInfo#IMPORTANCE_PERCEPTIBLE}.
+     *
+     * <p>The caller must hold the {@link android.Manifest.permission#PACKAGE_USAGE_STATS}
+     * permission to use this feature.</p>
+     *
+     * @throws IllegalArgumentException If the listener is already registered.
+     * @throws SecurityException If the caller does not hold
+     * {@link android.Manifest.permission#PACKAGE_USAGE_STATS}.
+     * @hide
+     */
+    @SystemApi @TestApi
+    public void addOnUidImportanceListener(OnUidImportanceListener listener,
+            int importanceCutpoint) {
+        synchronized (this) {
+            if (mImportanceListeners.containsKey(listener)) {
+                throw new IllegalArgumentException("Listener already registered: " + listener);
+            }
+            // TODO: implement the cut point in the system process to avoid IPCs.
+            UidObserver observer = new UidObserver(listener, importanceCutpoint);
+            try {
+                getService().registerUidObserver(observer,
+                        UID_OBSERVER_PROCSTATE | UID_OBSERVER_GONE, mContext.getOpPackageName());
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+            mImportanceListeners.put(listener, observer);
+        }
+    }
+
+    /**
+     * Remove an importance listener that was previously registered with
+     * {@link #addOnUidImportanceListener}.
+     *
+     * @throws IllegalArgumentException If the listener is not registered.
+     * @hide
+     */
+    @SystemApi @TestApi
+    public void removeOnUidImportanceListener(OnUidImportanceListener listener) {
+        synchronized (this) {
+            UidObserver observer = mImportanceListeners.remove(listener);
+            if (observer == null) {
+                throw new IllegalArgumentException("Listener not registered: " + listener);
+            }
+            try {
+                getService().unregisterUidObserver(observer);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
      * Return global memory state information for the calling process.  This
      * does not fill in all fields of the {@link RunningAppProcessInfo}.  The
      * only fields that will be filled in are
@@ -3519,6 +3643,76 @@
         pw.flush();
     }
 
+    /**
+     * @hide
+     */
+    public static void broadcastStickyIntent(Intent intent, int userId) {
+        broadcastStickyIntent(intent, AppOpsManager.OP_NONE, userId);
+    }
+
+    /**
+     * Convenience for sending a sticky broadcast.  For internal use only.
+     *
+     * @hide
+     */
+    public static void broadcastStickyIntent(Intent intent, int appOp, int userId) {
+        try {
+            getService().broadcastIntent(
+                    null, intent, null, null, Activity.RESULT_OK, null, null,
+                    null /*permission*/, appOp, null, false, true, userId);
+        } catch (RemoteException ex) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg,
+            String tag) {
+        try {
+            getService().noteWakeupAlarm((ps != null) ? ps.getTarget() : null,
+                    sourceUid, sourcePkg, tag);
+        } catch (RemoteException ex) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static void noteAlarmStart(PendingIntent ps, int sourceUid, String tag) {
+        try {
+            getService().noteAlarmStart((ps != null) ? ps.getTarget() : null, sourceUid, tag);
+        } catch (RemoteException ex) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static void noteAlarmFinish(PendingIntent ps, int sourceUid, String tag) {
+        try {
+            getService().noteAlarmFinish((ps != null) ? ps.getTarget() : null, sourceUid, tag);
+        } catch (RemoteException ex) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static IActivityManager getService() {
+        return IActivityManagerSingleton.get();
+    }
+
+    private static final Singleton<IActivityManager> IActivityManagerSingleton =
+            new Singleton<IActivityManager>() {
+                @Override
+                protected IActivityManager create() {
+                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
+                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
+                    return am;
+                }
+            };
+
     private static void dumpService(PrintWriter pw, FileDescriptor fd, String name, String[] args) {
         pw.print("DUMP OF SERVICE "); pw.print(name); pw.println(":");
         IBinder service = ServiceManager.checkService(name);
@@ -3592,7 +3786,7 @@
      */
     public void startLockTaskMode(int taskId) {
         try {
-            ActivityManagerNative.getDefault().startLockTaskMode(taskId);
+            ActivityManagerNative.getDefault().startLockTaskModeById(taskId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 0ba937a..e56fe0f 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.IIntentSender;
 import android.content.Intent;
@@ -179,4 +180,18 @@
      * (-1).
      */
     public abstract int getUidProcessState(int uid);
+
+    /**
+     * Called when Keyguard flags might have changed.
+     *
+     * @param callback Callback to run after activity visibilities have been reevaluated. This can
+     *                 be used from window manager so that when the callback is called, it's
+     *                 guaranteed that all apps have their visibility updated accordingly.
+     */
+    public abstract void notifyKeyguardFlagsChanged(@Nullable Runnable callback);
+
+    /**
+     * @return {@code true} if system is ready, {@code false} otherwise.
+     */
+    public abstract boolean isSystemReady();
 }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 4de5b42..10f0425 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -15,88 +15,52 @@
  */
 
 package android.app;
-
-import android.annotation.UserIdInt;
-import android.app.ActivityManager.StackInfo;
-import android.app.assist.AssistContent;
-import android.app.assist.AssistStructure;
-import android.content.ComponentName;
-import android.content.IIntentReceiver;
-import android.content.IIntentSender;
 import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.UriPermission;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.ConfigurationInfo;
-import android.content.pm.IPackageDataObserver;
-import android.content.pm.ParceledListSlice;
-import android.content.pm.UserInfo;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Debug;
 import android.os.IBinder;
-import android.os.IProgressListener;
-import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
-import android.os.PersistableBundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.StrictMode;
-import android.service.voice.IVoiceInteractionSession;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Singleton;
-import com.android.internal.app.IVoiceInteractor;
-import com.android.internal.os.IResultReceiver;
+import com.android.server.LocalServices;
 
-import java.util.ArrayList;
-import java.util.List;
-
-/** {@hide} */
-public abstract class ActivityManagerNative extends Binder implements IActivityManager
-{
+/**
+ * {@hide}
+ * @deprecated will be removed soon. See individual methods for alternatives.
+ */
+@Deprecated
+public abstract class ActivityManagerNative {
     /**
      * Cast a Binder object into an activity manager interface, generating
      * a proxy if needed.
+     *
+     * @deprecated use IActivityManager.Stub.asInterface instead.
      */
     static public IActivityManager asInterface(IBinder obj) {
-        if (obj == null) {
-            return null;
-        }
-        IActivityManager in =
-            (IActivityManager)obj.queryLocalInterface(descriptor);
-        if (in != null) {
-            return in;
-        }
-
-        return new ActivityManagerProxy(obj);
+        return IActivityManager.Stub.asInterface(obj);
     }
 
     /**
      * Retrieve the system's default/global activity manager.
+     *
+     * @deprecated use ActivityManager.getService instead.
      */
     static public IActivityManager getDefault() {
-        return gDefault.get();
+        return ActivityManager.getService();
     }
 
     /**
      * Convenience for checking whether the system is ready.  For internal use only.
+     *
+     * @deprecated use ActivityManagerInternal.isSystemReady instead.
      */
     static public boolean isSystemReady() {
         if (!sSystemReady) {
-            sSystemReady = getDefault().testIsSystemReady();
+            sSystemReady = LocalServices.getService(ActivityManagerInternal.class).isSystemReady();
         }
         return sSystemReady;
     }
+
     static volatile boolean sSystemReady = false;
 
+    /**
+     * @deprecated use ActivityManager.broadcastStickyIntent instead.
+     */
     static public void broadcastStickyIntent(Intent intent, String permission, int userId) {
         broadcastStickyIntent(intent, permission, AppOpsManager.OP_NONE, userId);
     }
@@ -104,7078 +68,33 @@
     /**
      * Convenience for sending a sticky broadcast.  For internal use only.
      * If you don't care about permission, use null.
+     *
+     * @deprecated use ActivityManager.broadcastStickyIntent instead.
      */
     static public void broadcastStickyIntent(Intent intent, String permission, int appOp,
             int userId) {
-        try {
-            getDefault().broadcastIntent(
-                    null, intent, null, null, Activity.RESULT_OK, null, null,
-                    null /*permission*/, appOp, null, false, true, userId);
-        } catch (RemoteException ex) {
-        }
+        ActivityManager.broadcastStickyIntent(intent, appOp, userId);
     }
 
+    /**
+     * @deprecated use ActivityManager.noteWakeupAlarm instead.
+     */
     static public void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg,
             String tag) {
-        try {
-            getDefault().noteWakeupAlarm((ps != null) ? ps.getTarget() : null,
-                    sourceUid, sourcePkg, tag);
-        } catch (RemoteException ex) {
-        }
+        ActivityManager.noteWakeupAlarm(ps, sourceUid, sourcePkg, tag);
     }
 
+    /**
+     * @deprecated use ActivityManager.noteAlarmStart instead.
+     */
     static public void noteAlarmStart(PendingIntent ps, int sourceUid, String tag) {
-        try {
-            getDefault().noteAlarmStart((ps != null) ? ps.getTarget() : null, sourceUid, tag);
-        } catch (RemoteException ex) {
-        }
+        ActivityManager.noteAlarmStart(ps, sourceUid, tag);
     }
 
+    /**
+     * @deprecated use ActivityManager.noteAlarmFinish instead.
+     */
     static public void noteAlarmFinish(PendingIntent ps, int sourceUid, String tag) {
-        try {
-            getDefault().noteAlarmFinish((ps != null) ? ps.getTarget() : null, sourceUid, tag);
-        } catch (RemoteException ex) {
-        }
+        ActivityManager.noteAlarmFinish(ps, sourceUid, tag);
     }
-
-    public ActivityManagerNative() {
-        attachInterface(this, descriptor);
-    }
-
-    @Override
-    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
-            throws RemoteException {
-        switch (code) {
-        case START_ACTIVITY_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String callingPackage = data.readString();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            IBinder resultTo = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            int startFlags = data.readInt();
-            ProfilerInfo profilerInfo = data.readInt() != 0
-                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int result = startActivity(app, callingPackage, intent, resolvedType,
-                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case START_ACTIVITY_AS_USER_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String callingPackage = data.readString();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            IBinder resultTo = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            int startFlags = data.readInt();
-            ProfilerInfo profilerInfo = data.readInt() != 0
-                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int userId = data.readInt();
-            int result = startActivityAsUser(app, callingPackage, intent, resolvedType,
-                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options, userId);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case START_ACTIVITY_AS_CALLER_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String callingPackage = data.readString();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            IBinder resultTo = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            int startFlags = data.readInt();
-            ProfilerInfo profilerInfo = data.readInt() != 0
-                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            boolean ignoreTargetSecurity = data.readInt() != 0;
-            int userId = data.readInt();
-            int result = startActivityAsCaller(app, callingPackage, intent, resolvedType,
-                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options,
-                    ignoreTargetSecurity, userId);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case START_ACTIVITY_AND_WAIT_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String callingPackage = data.readString();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            IBinder resultTo = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            int startFlags = data.readInt();
-            ProfilerInfo profilerInfo = data.readInt() != 0
-                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int userId = data.readInt();
-            WaitResult result = startActivityAndWait(app, callingPackage, intent, resolvedType,
-                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options, userId);
-            reply.writeNoException();
-            result.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case START_ACTIVITY_WITH_CONFIG_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String callingPackage = data.readString();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            IBinder resultTo = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            int startFlags = data.readInt();
-            Configuration config = Configuration.CREATOR.createFromParcel(data);
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int userId = data.readInt();
-            int result = startActivityWithConfig(app, callingPackage, intent, resolvedType,
-                    resultTo, resultWho, requestCode, startFlags, config, options, userId);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case START_ACTIVITY_INTENT_SENDER_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            IntentSender intent = IntentSender.CREATOR.createFromParcel(data);
-            Intent fillInIntent = null;
-            if (data.readInt() != 0) {
-                fillInIntent = Intent.CREATOR.createFromParcel(data);
-            }
-            String resolvedType = data.readString();
-            IBinder resultTo = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            int flagsMask = data.readInt();
-            int flagsValues = data.readInt();
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int result = startActivityIntentSender(app, intent,
-                    fillInIntent, resolvedType, resultTo, resultWho,
-                    requestCode, flagsMask, flagsValues, options);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case START_VOICE_ACTIVITY_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            String callingPackage = data.readString();
-            int callingPid = data.readInt();
-            int callingUid = data.readInt();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            IVoiceInteractionSession session = IVoiceInteractionSession.Stub.asInterface(
-                    data.readStrongBinder());
-            IVoiceInteractor interactor = IVoiceInteractor.Stub.asInterface(
-                    data.readStrongBinder());
-            int startFlags = data.readInt();
-            ProfilerInfo profilerInfo = data.readInt() != 0
-                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int userId = data.readInt();
-            int result = startVoiceActivity(callingPackage, callingPid, callingUid, intent,
-                    resolvedType, session, interactor, startFlags, profilerInfo, options, userId);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case START_LOCAL_VOICE_INTERACTION_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Bundle options = data.readBundle();
-            startLocalVoiceInteraction(token, options);
-            reply.writeNoException();
-            return true;
-        }
-
-        case STOP_LOCAL_VOICE_INTERACTION_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            stopLocalVoiceInteraction(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SUPPORTS_LOCAL_VOICE_INTERACTION_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean result = supportsLocalVoiceInteraction();
-            reply.writeNoException();
-            reply.writeInt(result? 1 : 0);
-            return true;
-        }
-
-        case START_NEXT_MATCHING_ACTIVITY_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder callingActivity = data.readStrongBinder();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            boolean result = startNextMatchingActivity(callingActivity, intent, options);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-
-        case START_ACTIVITY_FROM_RECENTS_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int taskId = data.readInt();
-            final Bundle options =
-                    data.readInt() == 0 ? null : Bundle.CREATOR.createFromParcel(data);
-            final int result = startActivityFromRecents(taskId, options);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case FINISH_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Intent resultData = null;
-            int resultCode = data.readInt();
-            if (data.readInt() != 0) {
-                resultData = Intent.CREATOR.createFromParcel(data);
-            }
-            int finishTask = data.readInt();
-            boolean res = finishActivity(token, resultCode, resultData, finishTask);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case FINISH_SUB_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            finishSubActivity(token, resultWho, requestCode);
-            reply.writeNoException();
-            return true;
-        }
-
-        case FINISH_ACTIVITY_AFFINITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean res = finishActivityAffinity(token);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case FINISH_VOICE_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IVoiceInteractionSession session = IVoiceInteractionSession.Stub.asInterface(
-                    data.readStrongBinder());
-            finishVoiceTask(session);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REQUEST_ACTIVITY_RELAUNCH: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            requestActivityRelaunch(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case RELEASE_ACTIVITY_INSTANCE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean res = releaseActivityInstance(token);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case RELEASE_SOME_ACTIVITIES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IApplicationThread app = IApplicationThread.Stub.asInterface(data.readStrongBinder());
-            releaseSomeActivities(app);
-            reply.writeNoException();
-            return true;
-        }
-
-        case WILL_ACTIVITY_BE_VISIBLE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean res = willActivityBeVisible(token);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case REGISTER_RECEIVER_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app =
-                b != null ? IApplicationThread.Stub.asInterface(b) : null;
-            String packageName = data.readString();
-            b = data.readStrongBinder();
-            IIntentReceiver rec
-                = b != null ? IIntentReceiver.Stub.asInterface(b) : null;
-            IntentFilter filter = IntentFilter.CREATOR.createFromParcel(data);
-            String perm = data.readString();
-            int userId = data.readInt();
-            Intent intent = registerReceiver(app, packageName, rec, filter, perm, userId);
-            reply.writeNoException();
-            if (intent != null) {
-                reply.writeInt(1);
-                intent.writeToParcel(reply, 0);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case UNREGISTER_RECEIVER_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            if (b == null) {
-                return true;
-            }
-            IIntentReceiver rec = IIntentReceiver.Stub.asInterface(b);
-            unregisterReceiver(rec);
-            reply.writeNoException();
-            return true;
-        }
-
-        case BROADCAST_INTENT_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app =
-                b != null ? IApplicationThread.Stub.asInterface(b) : null;
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            b = data.readStrongBinder();
-            IIntentReceiver resultTo =
-                b != null ? IIntentReceiver.Stub.asInterface(b) : null;
-            int resultCode = data.readInt();
-            String resultData = data.readString();
-            Bundle resultExtras = data.readBundle();
-            String[] perms = data.readStringArray();
-            int appOp = data.readInt();
-            Bundle options = data.readBundle();
-            boolean serialized = data.readInt() != 0;
-            boolean sticky = data.readInt() != 0;
-            int userId = data.readInt();
-            int res = broadcastIntent(app, intent, resolvedType, resultTo,
-                    resultCode, resultData, resultExtras, perms, appOp,
-                    options, serialized, sticky, userId);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case UNBROADCAST_INTENT_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = b != null ? IApplicationThread.Stub.asInterface(b) : null;
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            int userId = data.readInt();
-            unbroadcastIntent(app, intent, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case FINISH_RECEIVER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder who = data.readStrongBinder();
-            int resultCode = data.readInt();
-            String resultData = data.readString();
-            Bundle resultExtras = data.readBundle();
-            boolean resultAbort = data.readInt() != 0;
-            int intentFlags = data.readInt();
-            if (who != null) {
-                finishReceiver(who, resultCode, resultData, resultExtras, resultAbort, intentFlags);
-            }
-            reply.writeNoException();
-            return true;
-        }
-
-        case ATTACH_APPLICATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IApplicationThread app = IApplicationThread.Stub.asInterface(
-                    data.readStrongBinder());
-            if (app != null) {
-                attachApplication(app);
-            }
-            reply.writeNoException();
-            return true;
-        }
-
-        case ACTIVITY_IDLE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Configuration config = null;
-            if (data.readInt() != 0) {
-                config = Configuration.CREATOR.createFromParcel(data);
-            }
-            boolean stopProfiling = data.readInt() != 0;
-            if (token != null) {
-                activityIdle(token, config, stopProfiling);
-            }
-            reply.writeNoException();
-            return true;
-        }
-
-        case ACTIVITY_RESUMED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            activityResumed(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case ACTIVITY_PAUSED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            activityPaused(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case ACTIVITY_STOPPED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Bundle map = data.readBundle();
-            PersistableBundle persistentState = data.readPersistableBundle();
-            CharSequence description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(data);
-            activityStopped(token, map, persistentState, description);
-            reply.writeNoException();
-            return true;
-        }
-
-        case ACTIVITY_SLEPT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            activitySlept(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case ACTIVITY_DESTROYED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            activityDestroyed(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case ACTIVITY_RELAUNCHED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            activityRelaunched(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_CALLING_PACKAGE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            String res = token != null ? getCallingPackage(token) : null;
-            reply.writeNoException();
-            reply.writeString(res);
-            return true;
-        }
-
-        case GET_CALLING_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            ComponentName cn = getCallingActivity(token);
-            reply.writeNoException();
-            ComponentName.writeToParcel(cn, reply);
-            return true;
-        }
-
-        case GET_APP_TASKS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String callingPackage = data.readString();
-            List<IAppTask> list = getAppTasks(callingPackage);
-            reply.writeNoException();
-            int N = list != null ? list.size() : -1;
-            reply.writeInt(N);
-            int i;
-            for (i=0; i<N; i++) {
-                IAppTask task = list.get(i);
-                reply.writeStrongBinder(task.asBinder());
-            }
-            return true;
-        }
-
-        case ADD_APP_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder activityToken = data.readStrongBinder();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            ActivityManager.TaskDescription descr
-                    = ActivityManager.TaskDescription.CREATOR.createFromParcel(data);
-            Bitmap thumbnail = Bitmap.CREATOR.createFromParcel(data);
-            int res = addAppTask(activityToken, intent, descr, thumbnail);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case GET_APP_TASK_THUMBNAIL_SIZE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Point size = getAppTaskThumbnailSize();
-            reply.writeNoException();
-            size.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case GET_TASKS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int maxNum = data.readInt();
-            int fl = data.readInt();
-            List<ActivityManager.RunningTaskInfo> list = getTasks(maxNum, fl);
-            reply.writeNoException();
-            int N = list != null ? list.size() : -1;
-            reply.writeInt(N);
-            int i;
-            for (i=0; i<N; i++) {
-                ActivityManager.RunningTaskInfo info = list.get(i);
-                info.writeToParcel(reply, 0);
-            }
-            return true;
-        }
-
-        case GET_RECENT_TASKS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int maxNum = data.readInt();
-            int fl = data.readInt();
-            int userId = data.readInt();
-            ParceledListSlice<ActivityManager.RecentTaskInfo> list = getRecentTasks(maxNum,
-                    fl, userId);
-            reply.writeNoException();
-            list.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            return true;
-        }
-
-        case GET_TASK_THUMBNAIL_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int id = data.readInt();
-            ActivityManager.TaskThumbnail taskThumbnail = getTaskThumbnail(id);
-            reply.writeNoException();
-            if (taskThumbnail != null) {
-                reply.writeInt(1);
-                taskThumbnail.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case GET_SERVICES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int maxNum = data.readInt();
-            int fl = data.readInt();
-            List<ActivityManager.RunningServiceInfo> list = getServices(maxNum, fl);
-            reply.writeNoException();
-            int N = list != null ? list.size() : -1;
-            reply.writeInt(N);
-            int i;
-            for (i=0; i<N; i++) {
-                ActivityManager.RunningServiceInfo info = list.get(i);
-                info.writeToParcel(reply, 0);
-            }
-            return true;
-        }
-
-        case GET_PROCESSES_IN_ERROR_STATE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            List<ActivityManager.ProcessErrorStateInfo> list = getProcessesInErrorState();
-            reply.writeNoException();
-            reply.writeTypedList(list);
-            return true;
-        }
-
-        case GET_RUNNING_APP_PROCESSES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            List<ActivityManager.RunningAppProcessInfo> list = getRunningAppProcesses();
-            reply.writeNoException();
-            reply.writeTypedList(list);
-            return true;
-        }
-
-        case GET_RUNNING_EXTERNAL_APPLICATIONS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            List<ApplicationInfo> list = getRunningExternalApplications();
-            reply.writeNoException();
-            reply.writeTypedList(list);
-            return true;
-        }
-
-        case MOVE_TASK_TO_FRONT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int task = data.readInt();
-            int fl = data.readInt();
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            moveTaskToFront(task, fl, options);
-            reply.writeNoException();
-            return true;
-        }
-
-        case MOVE_ACTIVITY_TASK_TO_BACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean nonRoot = data.readInt() != 0;
-            boolean res = moveActivityTaskToBack(token, nonRoot);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case MOVE_TASK_BACKWARDS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int task = data.readInt();
-            moveTaskBackwards(task);
-            reply.writeNoException();
-            return true;
-        }
-
-        case MOVE_TASK_TO_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            int stackId = data.readInt();
-            boolean toTop = data.readInt() != 0;
-            moveTaskToStack(taskId, stackId, toTop);
-            reply.writeNoException();
-            return true;
-        }
-
-        case MOVE_TASK_TO_DOCKED_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            int createMode = data.readInt();
-            boolean toTop = data.readInt() != 0;
-            boolean animate = data.readInt() != 0;
-            Rect bounds = null;
-            boolean hasBounds = data.readInt() != 0;
-            if (hasBounds) {
-                bounds = Rect.CREATOR.createFromParcel(data);
-            }
-            final boolean moveHomeStackFront = data.readInt() != 0;
-            final boolean res = moveTaskToDockedStack(
-                    taskId, createMode, toTop, animate, bounds, moveHomeStackFront);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case MOVE_TOP_ACTIVITY_TO_PINNED_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int stackId = data.readInt();
-            final Rect r = Rect.CREATOR.createFromParcel(data);
-            final boolean res = moveTopActivityToPinnedStack(stackId, r);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case RESIZE_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int stackId = data.readInt();
-            final boolean hasRect = data.readInt() != 0;
-            Rect r = null;
-            if (hasRect) {
-                r = Rect.CREATOR.createFromParcel(data);
-            }
-            final boolean allowResizeInDockedMode = data.readInt() == 1;
-            final boolean preserveWindows = data.readInt() == 1;
-            final boolean animate = data.readInt() == 1;
-            final int animationDuration = data.readInt();
-            resizeStack(stackId,
-                    r, allowResizeInDockedMode, preserveWindows, animate, animationDuration);
-            reply.writeNoException();
-            return true;
-        }
-        case RESIZE_PINNED_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final boolean hasBounds = data.readInt() != 0;
-            Rect bounds = null;
-            if (hasBounds) {
-                bounds = Rect.CREATOR.createFromParcel(data);
-            }
-            final boolean hasTempPinnedTaskBounds = data.readInt() != 0;
-            Rect tempPinnedTaskBounds = null;
-            if (hasTempPinnedTaskBounds) {
-                tempPinnedTaskBounds = Rect.CREATOR.createFromParcel(data);
-            }
-            resizePinnedStack(bounds, tempPinnedTaskBounds);
-            return true;
-        }
-        case SWAP_DOCKED_AND_FULLSCREEN_STACK: {
-            data.enforceInterface(IActivityManager.descriptor);
-            swapDockedAndFullscreenStack();
-            reply.writeNoException();
-            return true;
-        }
-        case RESIZE_DOCKED_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final boolean hasBounds = data.readInt() != 0;
-            Rect bounds = null;
-            if (hasBounds) {
-                bounds = Rect.CREATOR.createFromParcel(data);
-            }
-            final boolean hasTempDockedTaskBounds = data.readInt() != 0;
-            Rect tempDockedTaskBounds = null;
-            if (hasTempDockedTaskBounds) {
-                tempDockedTaskBounds = Rect.CREATOR.createFromParcel(data);
-            }
-            final boolean hasTempDockedTaskInsetBounds = data.readInt() != 0;
-            Rect tempDockedTaskInsetBounds = null;
-            if (hasTempDockedTaskInsetBounds) {
-                tempDockedTaskInsetBounds = Rect.CREATOR.createFromParcel(data);
-            }
-            final boolean hasTempOtherTaskBounds = data.readInt() != 0;
-            Rect tempOtherTaskBounds = null;
-            if (hasTempOtherTaskBounds) {
-                tempOtherTaskBounds = Rect.CREATOR.createFromParcel(data);
-            }
-            final boolean hasTempOtherTaskInsetBounds = data.readInt() != 0;
-            Rect tempOtherTaskInsetBounds = null;
-            if (hasTempOtherTaskInsetBounds) {
-                tempOtherTaskInsetBounds = Rect.CREATOR.createFromParcel(data);
-            }
-            resizeDockedStack(bounds, tempDockedTaskBounds, tempDockedTaskInsetBounds,
-                    tempOtherTaskBounds, tempOtherTaskInsetBounds);
-            reply.writeNoException();
-            return true;
-        }
-
-        case POSITION_TASK_IN_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            int stackId = data.readInt();
-            int position = data.readInt();
-            positionTaskInStack(taskId, stackId, position);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_ALL_STACK_INFOS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            List<StackInfo> list = getAllStackInfos();
-            reply.writeNoException();
-            reply.writeTypedList(list);
-            return true;
-        }
-
-        case GET_STACK_INFO_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int stackId = data.readInt();
-            StackInfo info = getStackInfo(stackId);
-            reply.writeNoException();
-            if (info != null) {
-                reply.writeInt(1);
-                info.writeToParcel(reply, 0);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case IS_IN_HOME_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            boolean isInHomeStack = isInHomeStack(taskId);
-            reply.writeNoException();
-            reply.writeInt(isInHomeStack ? 1 : 0);
-            return true;
-        }
-
-        case SET_FOCUSED_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int stackId = data.readInt();
-            setFocusedStack(stackId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_FOCUSED_STACK_ID_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int focusedStackId = getFocusedStackId();
-            reply.writeNoException();
-            reply.writeInt(focusedStackId);
-            return true;
-        }
-
-        case SET_FOCUSED_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            setFocusedTask(taskId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REGISTER_TASK_STACK_LISTENER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            registerTaskStackListener(ITaskStackListener.Stub.asInterface(token));
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_TASK_FOR_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean onlyRoot = data.readInt() != 0;
-            int res = token != null
-                ? getTaskForActivity(token, onlyRoot) : -1;
-                reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case GET_CONTENT_PROVIDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String name = data.readString();
-            int userId = data.readInt();
-            boolean stable = data.readInt() != 0;
-            ContentProviderHolder cph = getContentProvider(app, name, userId, stable);
-            reply.writeNoException();
-            if (cph != null) {
-                reply.writeInt(1);
-                cph.writeToParcel(reply, 0);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String name = data.readString();
-            int userId = data.readInt();
-            IBinder token = data.readStrongBinder();
-            ContentProviderHolder cph = getContentProviderExternal(name, userId, token);
-            reply.writeNoException();
-            if (cph != null) {
-                reply.writeInt(1);
-                cph.writeToParcel(reply, 0);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case PUBLISH_CONTENT_PROVIDERS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            ArrayList<ContentProviderHolder> providers =
-                data.createTypedArrayList(ContentProviderHolder.CREATOR);
-            publishContentProviders(app, providers);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REF_CONTENT_PROVIDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            int stable = data.readInt();
-            int unstable = data.readInt();
-            boolean res = refContentProvider(b, stable, unstable);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case UNSTABLE_PROVIDER_DIED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            unstableProviderDied(b);
-            reply.writeNoException();
-            return true;
-        }
-
-        case APP_NOT_RESPONDING_VIA_PROVIDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            appNotRespondingViaProvider(b);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REMOVE_CONTENT_PROVIDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            boolean stable = data.readInt() != 0;
-            removeContentProvider(b, stable);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String name = data.readString();
-            IBinder token = data.readStrongBinder();
-            removeContentProviderExternal(name, token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_RUNNING_SERVICE_CONTROL_PANEL_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ComponentName comp = ComponentName.CREATOR.createFromParcel(data);
-            PendingIntent pi = getRunningServiceControlPanel(comp);
-            reply.writeNoException();
-            PendingIntent.writePendingIntentOrNullToParcel(pi, reply);
-            return true;
-        }
-
-        case START_SERVICE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            Intent service = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            String callingPackage = data.readString();
-            int userId = data.readInt();
-            ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);
-            reply.writeNoException();
-            ComponentName.writeToParcel(cn, reply);
-            return true;
-        }
-
-        case STOP_SERVICE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            Intent service = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            int userId = data.readInt();
-            int res = stopService(app, service, resolvedType, userId);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case STOP_SERVICE_TOKEN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ComponentName className = ComponentName.readFromParcel(data);
-            IBinder token = data.readStrongBinder();
-            int startId = data.readInt();
-            boolean res = stopServiceToken(className, token, startId);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case SET_SERVICE_FOREGROUND_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ComponentName className = ComponentName.readFromParcel(data);
-            IBinder token = data.readStrongBinder();
-            int id = data.readInt();
-            Notification notification = null;
-            if (data.readInt() != 0) {
-                notification = Notification.CREATOR.createFromParcel(data);
-            }
-            int sflags = data.readInt();
-            setServiceForeground(className, token, id, notification, sflags);
-            reply.writeNoException();
-            return true;
-        }
-
-        case BIND_SERVICE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            IBinder token = data.readStrongBinder();
-            Intent service = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            b = data.readStrongBinder();
-            int fl = data.readInt();
-            String callingPackage = data.readString();
-            int userId = data.readInt();
-            IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
-            int res = bindService(app, token, service, resolvedType, conn, fl,
-                    callingPackage, userId);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case UNBIND_SERVICE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
-            boolean res = unbindService(conn);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case PUBLISH_SERVICE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            IBinder service = data.readStrongBinder();
-            publishService(token, intent, service);
-            reply.writeNoException();
-            return true;
-        }
-
-        case UNBIND_FINISHED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            boolean doRebind = data.readInt() != 0;
-            unbindFinished(token, intent, doRebind);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SERVICE_DONE_EXECUTING_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            int type = data.readInt();
-            int startId = data.readInt();
-            int res = data.readInt();
-            serviceDoneExecuting(token, type, startId, res);
-            reply.writeNoException();
-            return true;
-        }
-
-        case START_INSTRUMENTATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ComponentName className = ComponentName.readFromParcel(data);
-            String profileFile = data.readString();
-            int fl = data.readInt();
-            Bundle arguments = data.readBundle();
-            IBinder b = data.readStrongBinder();
-            IInstrumentationWatcher w = IInstrumentationWatcher.Stub.asInterface(b);
-            b = data.readStrongBinder();
-            IUiAutomationConnection c = IUiAutomationConnection.Stub.asInterface(b);
-            int userId = data.readInt();
-            String abiOverride = data.readString();
-            boolean res = startInstrumentation(className, profileFile, fl, arguments, w, c, userId,
-                    abiOverride);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-
-        case FINISH_INSTRUMENTATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            int resultCode = data.readInt();
-            Bundle results = data.readBundle();
-            finishInstrumentation(app, resultCode, results);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_CONFIGURATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Configuration config = getConfiguration();
-            reply.writeNoException();
-            config.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case UPDATE_CONFIGURATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Configuration config = Configuration.CREATOR.createFromParcel(data);
-            final boolean updated = updateConfiguration(config);
-            reply.writeNoException();
-            reply.writeInt(updated ? 1 : 0);
-            return true;
-        }
-
-        case SET_REQUESTED_ORIENTATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            int requestedOrientation = data.readInt();
-            setRequestedOrientation(token, requestedOrientation);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_REQUESTED_ORIENTATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            int req = getRequestedOrientation(token);
-            reply.writeNoException();
-            reply.writeInt(req);
-            return true;
-        }
-
-        case GET_ACTIVITY_CLASS_FOR_TOKEN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            ComponentName cn = getActivityClassForToken(token);
-            reply.writeNoException();
-            ComponentName.writeToParcel(cn, reply);
-            return true;
-        }
-
-        case GET_PACKAGE_FOR_TOKEN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            reply.writeNoException();
-            reply.writeString(getPackageForToken(token));
-            return true;
-        }
-
-        case GET_INTENT_SENDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int type = data.readInt();
-            String packageName = data.readString();
-            IBinder token = data.readStrongBinder();
-            String resultWho = data.readString();
-            int requestCode = data.readInt();
-            Intent[] requestIntents;
-            String[] requestResolvedTypes;
-            if (data.readInt() != 0) {
-                requestIntents = data.createTypedArray(Intent.CREATOR);
-                requestResolvedTypes = data.createStringArray();
-            } else {
-                requestIntents = null;
-                requestResolvedTypes = null;
-            }
-            int fl = data.readInt();
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int userId = data.readInt();
-            IIntentSender res = getIntentSender(type, packageName, token,
-                    resultWho, requestCode, requestIntents,
-                    requestResolvedTypes, fl, options, userId);
-            reply.writeNoException();
-            reply.writeStrongBinder(res != null ? res.asBinder() : null);
-            return true;
-        }
-
-        case CANCEL_INTENT_SENDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender r = IIntentSender.Stub.asInterface(
-                data.readStrongBinder());
-            cancelIntentSender(r);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_PACKAGE_FOR_INTENT_SENDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender r = IIntentSender.Stub.asInterface(
-                data.readStrongBinder());
-            String res = getPackageForIntentSender(r);
-            reply.writeNoException();
-            reply.writeString(res);
-            return true;
-        }
-
-        case GET_UID_FOR_INTENT_SENDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender r = IIntentSender.Stub.asInterface(
-                data.readStrongBinder());
-            int res = getUidForIntentSender(r);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case HANDLE_INCOMING_USER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int callingPid = data.readInt();
-            int callingUid = data.readInt();
-            int userId = data.readInt();
-            boolean allowAll = data.readInt() != 0 ;
-            boolean requireFull = data.readInt() != 0;
-            String name = data.readString();
-            String callerPackage = data.readString();
-            int res = handleIncomingUser(callingPid, callingUid, userId, allowAll,
-                    requireFull, name, callerPackage);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case SET_PROCESS_LIMIT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int max = data.readInt();
-            setProcessLimit(max);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_PROCESS_LIMIT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int limit = getProcessLimit();
-            reply.writeNoException();
-            reply.writeInt(limit);
-            return true;
-        }
-
-        case SET_PROCESS_FOREGROUND_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            int pid = data.readInt();
-            boolean isForeground = data.readInt() != 0;
-            setProcessForeground(token, pid, isForeground);
-            reply.writeNoException();
-            return true;
-        }
-
-        case CHECK_PERMISSION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String perm = data.readString();
-            int pid = data.readInt();
-            int uid = data.readInt();
-            int res = checkPermission(perm, pid, uid);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case CHECK_PERMISSION_WITH_TOKEN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String perm = data.readString();
-            int pid = data.readInt();
-            int uid = data.readInt();
-            IBinder token = data.readStrongBinder();
-            int res = checkPermissionWithToken(perm, pid, uid, token);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case CHECK_URI_PERMISSION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int pid = data.readInt();
-            int uid = data.readInt();
-            int mode = data.readInt();
-            int userId = data.readInt();
-            IBinder callerToken = data.readStrongBinder();
-            int res = checkUriPermission(uri, pid, uid, mode, userId, callerToken);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case CLEAR_APP_DATA_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            IPackageDataObserver observer = IPackageDataObserver.Stub.asInterface(
-                    data.readStrongBinder());
-            int userId = data.readInt();
-            boolean res = clearApplicationUserData(packageName, observer, userId);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case GRANT_URI_PERMISSION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String targetPkg = data.readString();
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int mode = data.readInt();
-            int userId = data.readInt();
-            grantUriPermission(app, targetPkg, uri, mode, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REVOKE_URI_PERMISSION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int mode = data.readInt();
-            int userId = data.readInt();
-            revokeUriPermission(app, uri, mode, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case TAKE_PERSISTABLE_URI_PERMISSION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int mode = data.readInt();
-            int userId = data.readInt();
-            takePersistableUriPermission(uri, mode, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case RELEASE_PERSISTABLE_URI_PERMISSION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int mode = data.readInt();
-            int userId = data.readInt();
-            releasePersistableUriPermission(uri, mode, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_PERSISTED_URI_PERMISSIONS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final String packageName = data.readString();
-            final boolean incoming = data.readInt() != 0;
-            final ParceledListSlice<UriPermission> perms = getPersistedUriPermissions(
-                    packageName, incoming);
-            reply.writeNoException();
-            perms.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            return true;
-        }
-
-        case GET_GRANTED_URI_PERMISSIONS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final String packageName = data.readString();
-            final int userId = data.readInt();
-            final ParceledListSlice<UriPermission> perms = getGrantedUriPermissions(packageName,
-                    userId);
-            reply.writeNoException();
-            perms.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            return true;
-        }
-
-        case CLEAR_GRANTED_URI_PERMISSIONS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final String packageName = data.readString();
-            final int userId = data.readInt();
-            clearGrantedUriPermissions(packageName, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SHOW_WAITING_FOR_DEBUGGER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            boolean waiting = data.readInt() != 0;
-            showWaitingForDebugger(app, waiting);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_MEMORY_INFO_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
-            getMemoryInfo(mi);
-            reply.writeNoException();
-            mi.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case UNHANDLED_BACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            unhandledBack();
-            reply.writeNoException();
-            return true;
-        }
-
-        case OPEN_CONTENT_URI_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Uri uri = Uri.parse(data.readString());
-            ParcelFileDescriptor pfd = openContentUri(uri);
-            reply.writeNoException();
-            if (pfd != null) {
-                reply.writeInt(1);
-                pfd.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case SET_LOCK_SCREEN_SHOWN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final boolean showing = data.readInt() != 0;
-            final boolean occluded = data.readInt() != 0;
-            setLockScreenShown(showing, occluded);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_DEBUG_APP_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String pn = data.readString();
-            boolean wfd = data.readInt() != 0;
-            boolean per = data.readInt() != 0;
-            setDebugApp(pn, wfd, per);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_ALWAYS_FINISH_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean enabled = data.readInt() != 0;
-            setAlwaysFinish(enabled);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_ACTIVITY_CONTROLLER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IActivityController watcher = IActivityController.Stub.asInterface(
-                    data.readStrongBinder());
-            boolean imAMonkey = data.readInt() != 0;
-            setActivityController(watcher, imAMonkey);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_LENIENT_BACKGROUND_CHECK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean enabled = data.readInt() != 0;
-            setLenientBackgroundCheck(enabled);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_MEMORY_TRIM_LEVEL_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int level = getMemoryTrimLevel();
-            reply.writeNoException();
-            reply.writeInt(level);
-            return true;
-        }
-
-        case ENTER_SAFE_MODE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            enterSafeMode();
-            reply.writeNoException();
-            return true;
-        }
-
-        case NOTE_WAKEUP_ALARM_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender is = IIntentSender.Stub.asInterface(
-                    data.readStrongBinder());
-            int sourceUid = data.readInt();
-            String sourcePkg = data.readString();
-            String tag = data.readString();
-            noteWakeupAlarm(is, sourceUid, sourcePkg, tag);
-            reply.writeNoException();
-            return true;
-        }
-
-        case NOTE_ALARM_START_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender is = IIntentSender.Stub.asInterface(
-                    data.readStrongBinder());
-            int sourceUid = data.readInt();
-            String tag = data.readString();
-            noteAlarmStart(is, sourceUid, tag);
-            reply.writeNoException();
-            return true;
-        }
-
-        case NOTE_ALARM_FINISH_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender is = IIntentSender.Stub.asInterface(
-                    data.readStrongBinder());
-            int sourceUid = data.readInt();
-            String tag = data.readString();
-            noteAlarmFinish(is, sourceUid, tag);
-            reply.writeNoException();
-            return true;
-        }
-
-        case KILL_PIDS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int[] pids = data.createIntArray();
-            String reason = data.readString();
-            boolean secure = data.readInt() != 0;
-            boolean res = killPids(pids, reason, secure);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String reason = data.readString();
-            boolean res = killProcessesBelowForeground(reason);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case HANDLE_APPLICATION_CRASH_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder app = data.readStrongBinder();
-            ApplicationErrorReport.CrashInfo ci = new ApplicationErrorReport.CrashInfo(data);
-            handleApplicationCrash(app, ci);
-            reply.writeNoException();
-            return true;
-        }
-
-        case HANDLE_APPLICATION_WTF_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder app = data.readStrongBinder();
-            String tag = data.readString();
-            boolean system = data.readInt() != 0;
-            ApplicationErrorReport.CrashInfo ci = new ApplicationErrorReport.CrashInfo(data);
-            boolean res = handleApplicationWtf(app, tag, system, ci);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case HANDLE_APPLICATION_STRICT_MODE_VIOLATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder app = data.readStrongBinder();
-            int violationMask = data.readInt();
-            StrictMode.ViolationInfo info = new StrictMode.ViolationInfo(data);
-            handleApplicationStrictModeViolation(app, violationMask, info);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SIGNAL_PERSISTENT_PROCESSES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int sig = data.readInt();
-            signalPersistentProcesses(sig);
-            reply.writeNoException();
-            return true;
-        }
-
-        case KILL_BACKGROUND_PROCESSES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            int userId = data.readInt();
-            killBackgroundProcesses(packageName, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            killAllBackgroundProcesses();
-            reply.writeNoException();
-            return true;
-        }
-
-        case KILL_PACKAGE_DEPENDENTS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            int userId = data.readInt();
-            killPackageDependents(packageName, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case FORCE_STOP_PACKAGE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            int userId = data.readInt();
-            forceStopPackage(packageName, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_MY_MEMORY_STATE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ActivityManager.RunningAppProcessInfo info =
-                    new ActivityManager.RunningAppProcessInfo();
-            getMyMemoryState(info);
-            reply.writeNoException();
-            info.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case GET_DEVICE_CONFIGURATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ConfigurationInfo config = getDeviceConfigurationInfo();
-            reply.writeNoException();
-            config.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case PROFILE_CONTROL_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String process = data.readString();
-            int userId = data.readInt();
-            boolean start = data.readInt() != 0;
-            int profileType = data.readInt();
-            ProfilerInfo profilerInfo = data.readInt() != 0
-                    ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
-            boolean res = profileControl(process, userId, start, profilerInfo, profileType);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case SHUTDOWN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean res = shutdown(data.readInt());
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case STOP_APP_SWITCHES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            stopAppSwitches();
-            reply.writeNoException();
-            return true;
-        }
-
-        case RESUME_APP_SWITCHES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            resumeAppSwitches();
-            reply.writeNoException();
-            return true;
-        }
-
-        case PEEK_SERVICE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Intent service = Intent.CREATOR.createFromParcel(data);
-            String resolvedType = data.readString();
-            String callingPackage = data.readString();
-            IBinder binder = peekService(service, resolvedType, callingPackage);
-            reply.writeNoException();
-            reply.writeStrongBinder(binder);
-            return true;
-        }
-
-        case START_BACKUP_AGENT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            int backupRestoreMode = data.readInt();
-            int userId = data.readInt();
-            boolean success = bindBackupAgent(packageName, backupRestoreMode, userId);
-            reply.writeNoException();
-            reply.writeInt(success ? 1 : 0);
-            return true;
-        }
-
-        case BACKUP_AGENT_CREATED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            IBinder agent = data.readStrongBinder();
-            backupAgentCreated(packageName, agent);
-            reply.writeNoException();
-            return true;
-        }
-
-        case UNBIND_BACKUP_AGENT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ApplicationInfo info = ApplicationInfo.CREATOR.createFromParcel(data);
-            unbindBackupAgent(info);
-            reply.writeNoException();
-            return true;
-        }
-
-        case ADD_PACKAGE_DEPENDENCY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            addPackageDependency(packageName);
-            reply.writeNoException();
-            return true;
-        }
-
-        case KILL_APPLICATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String pkg = data.readString();
-            int appId = data.readInt();
-            int userId = data.readInt();
-            String reason = data.readString();
-            killApplication(pkg, appId, userId, reason);
-            reply.writeNoException();
-            return true;
-        }
-
-        case CLOSE_SYSTEM_DIALOGS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String reason = data.readString();
-            closeSystemDialogs(reason);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_PROCESS_MEMORY_INFO_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int[] pids = data.createIntArray();
-            Debug.MemoryInfo[] res =  getProcessMemoryInfo(pids);
-            reply.writeNoException();
-            reply.writeTypedArray(res, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            return true;
-        }
-
-        case KILL_APPLICATION_PROCESS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String processName = data.readString();
-            int uid = data.readInt();
-            killApplicationProcess(processName, uid);
-            reply.writeNoException();
-            return true;
-        }
-
-        case OVERRIDE_PENDING_TRANSITION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            String packageName = data.readString();
-            int enterAnim = data.readInt();
-            int exitAnim = data.readInt();
-            overridePendingTransition(token, packageName, enterAnim, exitAnim);
-            reply.writeNoException();
-            return true;
-        }
-
-        case IS_USER_A_MONKEY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean areThey = isUserAMonkey();
-            reply.writeNoException();
-            reply.writeInt(areThey ? 1 : 0);
-            return true;
-        }
-
-        case SET_USER_IS_MONKEY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final boolean monkey = (data.readInt() == 1);
-            setUserIsMonkey(monkey);
-            reply.writeNoException();
-            return true;
-        }
-
-        case FINISH_HEAVY_WEIGHT_APP_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            finishHeavyWeightApp();
-            reply.writeNoException();
-            return true;
-        }
-
-        case IS_IMMERSIVE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean isit = isImmersive(token);
-            reply.writeNoException();
-            reply.writeInt(isit ? 1 : 0);
-            return true;
-        }
-
-        case IS_TOP_OF_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            final boolean isTopOfTask = isTopOfTask(token);
-            reply.writeNoException();
-            reply.writeInt(isTopOfTask ? 1 : 0);
-            return true;
-        }
-
-        case CONVERT_FROM_TRANSLUCENT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean converted = convertFromTranslucent(token);
-            reply.writeNoException();
-            reply.writeInt(converted ? 1 : 0);
-            return true;
-        }
-
-        case CONVERT_TO_TRANSLUCENT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            final Bundle bundle;
-            if (data.readInt() == 0) {
-                bundle = null;
-            } else {
-                bundle = data.readBundle();
-            }
-            final ActivityOptions options = ActivityOptions.fromBundle(bundle);
-            boolean converted = convertToTranslucent(token, options);
-            reply.writeNoException();
-            reply.writeInt(converted ? 1 : 0);
-            return true;
-        }
-
-        case GET_ACTIVITY_OPTIONS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            final ActivityOptions options = getActivityOptions(token);
-            reply.writeNoException();
-            reply.writeBundle(options == null ? null : options.toBundle());
-            return true;
-        }
-
-        case SET_IMMERSIVE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean imm = data.readInt() == 1;
-            setImmersive(token, imm);
-            reply.writeNoException();
-            return true;
-        }
-
-        case IS_TOP_ACTIVITY_IMMERSIVE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean isit = isTopActivityImmersive();
-            reply.writeNoException();
-            reply.writeInt(isit ? 1 : 0);
-            return true;
-        }
-
-        case CRASH_APPLICATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int uid = data.readInt();
-            int initialPid = data.readInt();
-            String packageName = data.readString();
-            String message = data.readString();
-            crashApplication(uid, initialPid, packageName, message);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_PROVIDER_MIME_TYPE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int userId = data.readInt();
-            String type = getProviderMimeType(uri, userId);
-            reply.writeNoException();
-            reply.writeString(type);
-            return true;
-        }
-
-        case NEW_URI_PERMISSION_OWNER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String name = data.readString();
-            IBinder perm = newUriPermissionOwner(name);
-            reply.writeNoException();
-            reply.writeStrongBinder(perm);
-            return true;
-        }
-
-        case GET_URI_PERMISSION_OWNER_FOR_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder activityToken = data.readStrongBinder();
-            IBinder perm = getUriPermissionOwnerForActivity(activityToken);
-            reply.writeNoException();
-            reply.writeStrongBinder(perm);
-            return true;
-        }
-
-        case GRANT_URI_PERMISSION_FROM_OWNER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder owner = data.readStrongBinder();
-            int fromUid = data.readInt();
-            String targetPkg = data.readString();
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int mode = data.readInt();
-            int sourceUserId = data.readInt();
-            int targetUserId = data.readInt();
-            grantUriPermissionFromOwner(owner, fromUid, targetPkg, uri, mode, sourceUserId,
-                    targetUserId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REVOKE_URI_PERMISSION_FROM_OWNER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder owner = data.readStrongBinder();
-            Uri uri = null;
-            if (data.readInt() != 0) {
-                uri = Uri.CREATOR.createFromParcel(data);
-            }
-            int mode = data.readInt();
-            int userId = data.readInt();
-            revokeUriPermissionFromOwner(owner, uri, mode, userId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case CHECK_GRANT_URI_PERMISSION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int callingUid = data.readInt();
-            String targetPkg = data.readString();
-            Uri uri = Uri.CREATOR.createFromParcel(data);
-            int modeFlags = data.readInt();
-            int userId = data.readInt();
-            int res = checkGrantUriPermission(callingUid, targetPkg, uri, modeFlags, userId);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case DUMP_HEAP_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String process = data.readString();
-            int userId = data.readInt();
-            boolean managed = data.readInt() != 0;
-            String path = data.readString();
-            ParcelFileDescriptor fd = data.readInt() != 0
-                    ? ParcelFileDescriptor.CREATOR.createFromParcel(data) : null;
-            boolean res = dumpHeap(process, userId, managed, path, fd);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case START_ACTIVITIES_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder b = data.readStrongBinder();
-            IApplicationThread app = IApplicationThread.Stub.asInterface(b);
-            String callingPackage = data.readString();
-            Intent[] intents = data.createTypedArray(Intent.CREATOR);
-            String[] resolvedTypes = data.createStringArray();
-            IBinder resultTo = data.readStrongBinder();
-            Bundle options = data.readInt() != 0
-                    ? Bundle.CREATOR.createFromParcel(data) : null;
-            int userId = data.readInt();
-            int result = startActivities(app, callingPackage, intents, resolvedTypes, resultTo,
-                    options, userId);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case GET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            int mode = getFrontActivityScreenCompatMode();
-            reply.writeNoException();
-            reply.writeInt(mode);
-            return true;
-        }
-
-        case SET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            int mode = data.readInt();
-            setFrontActivityScreenCompatMode(mode);
-            reply.writeNoException();
-            reply.writeInt(mode);
-            return true;
-        }
-
-        case GET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            String pkg = data.readString();
-            int mode = getPackageScreenCompatMode(pkg);
-            reply.writeNoException();
-            reply.writeInt(mode);
-            return true;
-        }
-
-        case SET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            String pkg = data.readString();
-            int mode = data.readInt();
-            setPackageScreenCompatMode(pkg, mode);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SWITCH_USER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int userid = data.readInt();
-            boolean result = switchUser(userid);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-
-        case START_USER_IN_BACKGROUND_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int userid = data.readInt();
-            boolean result = startUserInBackground(userid);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-
-        case UNLOCK_USER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int userId = data.readInt();
-            byte[] token = data.createByteArray();
-            byte[] secret = data.createByteArray();
-            IProgressListener listener = IProgressListener.Stub
-                    .asInterface(data.readStrongBinder());
-            boolean result = unlockUser(userId, token, secret, listener);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-
-        case STOP_USER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int userid = data.readInt();
-            boolean force = data.readInt() != 0;
-            IStopUserCallback callback = IStopUserCallback.Stub.asInterface(
-                    data.readStrongBinder());
-            int result = stopUser(userid, force, callback);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-
-        case GET_CURRENT_USER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            UserInfo userInfo = getCurrentUser();
-            reply.writeNoException();
-            userInfo.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case IS_USER_RUNNING_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int userid = data.readInt();
-            int _flags = data.readInt();
-            boolean result = isUserRunning(userid, _flags);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-
-        case GET_RUNNING_USER_IDS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int[] result = getRunningUserIds();
-            reply.writeNoException();
-            reply.writeIntArray(result);
-            return true;
-        }
-
-        case REMOVE_TASK_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            boolean result = removeTask(taskId);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-
-        case REGISTER_PROCESS_OBSERVER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IProcessObserver observer = IProcessObserver.Stub.asInterface(
-                    data.readStrongBinder());
-            registerProcessObserver(observer);
-            return true;
-        }
-
-        case UNREGISTER_PROCESS_OBSERVER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IProcessObserver observer = IProcessObserver.Stub.asInterface(
-                    data.readStrongBinder());
-            unregisterProcessObserver(observer);
-            return true;
-        }
-
-        case REGISTER_UID_OBSERVER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IUidObserver observer = IUidObserver.Stub.asInterface(
-                    data.readStrongBinder());
-            int which = data.readInt();
-            registerUidObserver(observer, which);
-            return true;
-        }
-
-        case UNREGISTER_UID_OBSERVER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IUidObserver observer = IUidObserver.Stub.asInterface(
-                    data.readStrongBinder());
-            unregisterUidObserver(observer);
-            return true;
-        }
-
-        case GET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            String pkg = data.readString();
-            boolean ask = getPackageAskScreenCompat(pkg);
-            reply.writeNoException();
-            reply.writeInt(ask ? 1 : 0);
-            return true;
-        }
-
-        case SET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION:
-        {
-            data.enforceInterface(IActivityManager.descriptor);
-            String pkg = data.readString();
-            boolean ask = data.readInt() != 0;
-            setPackageAskScreenCompat(pkg, ask);
-            reply.writeNoException();
-            return true;
-        }
-
-        case IS_INTENT_SENDER_TARGETED_TO_PACKAGE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender r = IIntentSender.Stub.asInterface(
-                    data.readStrongBinder());
-            boolean res = isIntentSenderTargetedToPackage(r);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case IS_INTENT_SENDER_AN_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender r = IIntentSender.Stub.asInterface(
-                data.readStrongBinder());
-            boolean res = isIntentSenderAnActivity(r);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case GET_INTENT_FOR_INTENT_SENDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender r = IIntentSender.Stub.asInterface(
-                data.readStrongBinder());
-            Intent intent = getIntentForIntentSender(r);
-            reply.writeNoException();
-            if (intent != null) {
-                reply.writeInt(1);
-                intent.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case GET_TAG_FOR_INTENT_SENDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender r = IIntentSender.Stub.asInterface(
-                data.readStrongBinder());
-            String prefix = data.readString();
-            String tag = getTagForIntentSender(r, prefix);
-            reply.writeNoException();
-            reply.writeString(tag);
-            return true;
-        }
-
-        case UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Configuration config = Configuration.CREATOR.createFromParcel(data);
-            updatePersistentConfiguration(config);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_PROCESS_PSS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int[] pids = data.createIntArray();
-            long[] pss = getProcessPss(pids);
-            reply.writeNoException();
-            reply.writeLongArray(pss);
-            return true;
-        }
-
-        case SHOW_BOOT_MESSAGE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            CharSequence msg = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(data);
-            boolean always = data.readInt() != 0;
-            showBootMessage(msg, always);
-            reply.writeNoException();
-            return true;
-        }
-
-        case KEYGUARD_WAITING_FOR_ACTIVITY_DRAWN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            keyguardWaitingForActivityDrawn();
-            reply.writeNoException();
-            return true;
-        }
-
-        case KEYGUARD_GOING_AWAY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            keyguardGoingAway(data.readInt());
-            reply.writeNoException();
-            return true;
-        }
-
-        case SHOULD_UP_RECREATE_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            String destAffinity = data.readString();
-            boolean res = shouldUpRecreateTask(token, destAffinity);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case NAVIGATE_UP_TO_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Intent target = Intent.CREATOR.createFromParcel(data);
-            int resultCode = data.readInt();
-            Intent resultData = null;
-            if (data.readInt() != 0) {
-                resultData = Intent.CREATOR.createFromParcel(data);
-            }
-            boolean res = navigateUpTo(token, target, resultCode, resultData);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case GET_LAUNCHED_FROM_UID_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            int res = getLaunchedFromUid(token);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case GET_LAUNCHED_FROM_PACKAGE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            String res = getLaunchedFromPackage(token);
-            reply.writeNoException();
-            reply.writeString(res);
-            return true;
-        }
-
-        case REGISTER_USER_SWITCH_OBSERVER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IUserSwitchObserver observer = IUserSwitchObserver.Stub.asInterface(
-                    data.readStrongBinder());
-            String name = data.readString();
-            registerUserSwitchObserver(observer, name);
-            reply.writeNoException();
-            return true;
-        }
-
-        case UNREGISTER_USER_SWITCH_OBSERVER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IUserSwitchObserver observer = IUserSwitchObserver.Stub.asInterface(
-                    data.readStrongBinder());
-            unregisterUserSwitchObserver(observer);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REQUEST_BUG_REPORT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int bugreportType = data.readInt();
-            requestBugReport(bugreportType);
-            reply.writeNoException();
-            return true;
-        }
-
-        case INPUT_DISPATCHING_TIMED_OUT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int pid = data.readInt();
-            boolean aboveSystem = data.readInt() != 0;
-            String reason = data.readString();
-            long res = inputDispatchingTimedOut(pid, aboveSystem, reason);
-            reply.writeNoException();
-            reply.writeLong(res);
-            return true;
-        }
-
-        case GET_ASSIST_CONTEXT_EXTRAS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int requestType = data.readInt();
-            Bundle res = getAssistContextExtras(requestType);
-            reply.writeNoException();
-            reply.writeBundle(res);
-            return true;
-        }
-
-        case REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int requestType = data.readInt();
-            IResultReceiver receiver = IResultReceiver.Stub.asInterface(data.readStrongBinder());
-            Bundle receiverExtras = data.readBundle();
-            IBinder activityToken = data.readStrongBinder();
-            boolean focused = data.readInt() == 1;
-            boolean newSessionId = data.readInt() == 1;
-            boolean res = requestAssistContextExtras(requestType, receiver, receiverExtras,
-                    activityToken, focused, newSessionId);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Bundle extras = data.readBundle();
-            AssistStructure structure = AssistStructure.CREATOR.createFromParcel(data);
-            AssistContent content = AssistContent.CREATOR.createFromParcel(data);
-            Uri referrer = data.readInt() != 0 ? Uri.CREATOR.createFromParcel(data) : null;
-            reportAssistContextExtras(token, extras, structure, content, referrer);
-            reply.writeNoException();
-            return true;
-        }
-
-        case LAUNCH_ASSIST_INTENT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Intent intent = Intent.CREATOR.createFromParcel(data);
-            int requestType = data.readInt();
-            String hint = data.readString();
-            int userHandle = data.readInt();
-            Bundle args = data.readBundle();
-            boolean res = launchAssistIntent(intent, requestType, hint, userHandle, args);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean res = isAssistDataAllowedOnCurrentActivity();
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            Bundle args = data.readBundle();
-            boolean res = showAssistFromActivity(token, args);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case KILL_UID_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int appId = data.readInt();
-            int userId = data.readInt();
-            String reason = data.readString();
-            killUid(appId, userId, reason);
-            reply.writeNoException();
-            return true;
-        }
-
-        case HANG_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder who = data.readStrongBinder();
-            boolean allowRestart = data.readInt() != 0;
-            hang(who, allowRestart);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            reportActivityFullyDrawn(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case NOTIFY_ACTIVITY_DRAWN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            notifyActivityDrawn(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case RESTART_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            restart();
-            reply.writeNoException();
-            return true;
-        }
-
-        case PERFORM_IDLE_MAINTENANCE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            performIdleMaintenance();
-            reply.writeNoException();
-            return true;
-        }
-
-        case CREATE_VIRTUAL_ACTIVITY_CONTAINER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder parentActivityToken = data.readStrongBinder();
-            IActivityContainerCallback callback =
-                    IActivityContainerCallback.Stub.asInterface(data.readStrongBinder());
-            IActivityContainer activityContainer =
-                    createVirtualActivityContainer(parentActivityToken, callback);
-            reply.writeNoException();
-            if (activityContainer != null) {
-                reply.writeInt(1);
-                reply.writeStrongBinder(activityContainer.asBinder());
-            } else {
-                reply.writeInt(0);
-            }
-            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();
-            IActivityContainer activityContainer = createStackOnDisplay(displayId);
-            reply.writeNoException();
-            if (activityContainer != null) {
-                reply.writeInt(1);
-                reply.writeStrongBinder(activityContainer.asBinder());
-            } else {
-                reply.writeInt(0);
-            }
-            return true;
-        }
-
-        case GET_ACTIVITY_DISPLAY_ID_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder activityToken = data.readStrongBinder();
-            int displayId = getActivityDisplayId(activityToken);
-            reply.writeNoException();
-            reply.writeInt(displayId);
-            return true;
-        }
-
-        case START_LOCK_TASK_BY_TASK_ID_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int taskId = data.readInt();
-            startLockTaskMode(taskId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case START_LOCK_TASK_BY_TOKEN_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            startLockTaskMode(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case START_SYSTEM_LOCK_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            startSystemLockTaskMode(taskId);
-            reply.writeNoException();
-            return true;
-        }
-
-        case STOP_LOCK_TASK_MODE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            stopLockTaskMode();
-            reply.writeNoException();
-            return true;
-        }
-
-        case STOP_SYSTEM_LOCK_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            stopSystemLockTaskMode();
-            reply.writeNoException();
-            return true;
-        }
-
-        case IS_IN_LOCK_TASK_MODE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final boolean isInLockTaskMode = isInLockTaskMode();
-            reply.writeNoException();
-            reply.writeInt(isInLockTaskMode ? 1 : 0);
-            return true;
-        }
-
-        case GET_LOCK_TASK_MODE_STATE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int lockTaskModeState = getLockTaskModeState();
-            reply.writeNoException();
-            reply.writeInt(lockTaskModeState);
-            return true;
-        }
-
-        case SHOW_LOCK_TASK_ESCAPE_MESSAGE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final IBinder token = data.readStrongBinder();
-            showLockTaskEscapeMessage(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_TASK_DESCRIPTION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            ActivityManager.TaskDescription values =
-                    ActivityManager.TaskDescription.CREATOR.createFromParcel(data);
-            setTaskDescription(token, values);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_TASK_RESIZEABLE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int taskId = data.readInt();
-            final int resizeableMode = data.readInt();
-            setTaskResizeable(taskId, resizeableMode);
-            reply.writeNoException();
-            return true;
-        }
-
-        case RESIZE_TASK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            int resizeMode = data.readInt();
-            Rect r = Rect.CREATOR.createFromParcel(data);
-            resizeTask(taskId, r, resizeMode);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_TASK_BOUNDS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int taskId = data.readInt();
-            Rect r = getTaskBounds(taskId);
-            reply.writeNoException();
-            r.writeToParcel(reply, 0);
-            return true;
-        }
-
-        case GET_TASK_DESCRIPTION_ICON_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String filename = data.readString();
-            int userId = data.readInt();
-            Bitmap icon = getTaskDescriptionIcon(filename, userId);
-            reply.writeNoException();
-            if (icon == null) {
-                reply.writeInt(0);
-            } else {
-                reply.writeInt(1);
-                icon.writeToParcel(reply, 0);
-            }
-            return true;
-        }
-
-        case START_IN_PLACE_ANIMATION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final Bundle bundle;
-            if (data.readInt() == 0) {
-                bundle = null;
-            } else {
-                bundle = data.readBundle();
-            }
-            final ActivityOptions options = ActivityOptions.fromBundle(bundle);
-            startInPlaceAnimationOnFrontMostApplication(options);
-            reply.writeNoException();
-            return true;
-        }
-
-        case REQUEST_VISIBLE_BEHIND_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean enable = data.readInt() > 0;
-            boolean success = requestVisibleBehind(token, enable);
-            reply.writeNoException();
-            reply.writeInt(success ? 1 : 0);
-            return true;
-        }
-
-        case IS_BACKGROUND_VISIBLE_BEHIND_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            final boolean enabled = isBackgroundVisibleBehind(token);
-            reply.writeNoException();
-            reply.writeInt(enabled ? 1 : 0);
-            return true;
-        }
-
-        case BACKGROUND_RESOURCES_RELEASED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            backgroundResourcesReleased(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            notifyLaunchTaskBehindComplete(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case NOTIFY_ENTER_ANIMATION_COMPLETE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            notifyEnterAnimationComplete(token);
-            reply.writeNoException();
-            return true;
-        }
-
-        case BOOT_ANIMATION_COMPLETE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            bootAnimationComplete();
-            reply.writeNoException();
-            return true;
-        }
-
-        case NOTIFY_CLEARTEXT_NETWORK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int uid = data.readInt();
-            final byte[] firstPacket = data.createByteArray();
-            notifyCleartextNetwork(uid, firstPacket);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_DUMP_HEAP_DEBUG_LIMIT_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String procName = data.readString();
-            int uid = data.readInt();
-            long maxMemSize = data.readLong();
-            String reportPackage = data.readString();
-            setDumpHeapDebugLimit(procName, uid, maxMemSize, reportPackage);
-            reply.writeNoException();
-            return true;
-        }
-
-        case DUMP_HEAP_FINISHED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String path = data.readString();
-            dumpHeapFinished(path);
-            reply.writeNoException();
-            return true;
-        }
-
-        case SET_VOICE_KEEP_AWAKE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IVoiceInteractionSession session = IVoiceInteractionSession.Stub.asInterface(
-                    data.readStrongBinder());
-            boolean keepAwake = data.readInt() != 0;
-            setVoiceKeepAwake(session, keepAwake);
-            reply.writeNoException();
-            return true;
-        }
-
-        case UPDATE_LOCK_TASK_PACKAGES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            int userId = data.readInt();
-            String[] packages = data.readStringArray();
-            updateLockTaskPackages(userId, packages);
-            reply.writeNoException();
-            return true;
-        }
-
-        case UPDATE_DEVICE_OWNER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String packageName = data.readString();
-            updateDeviceOwner(packageName);
-            reply.writeNoException();
-            return true;
-        }
-
-        case GET_PACKAGE_PROCESS_STATE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String pkg = data.readString();
-            String callingPackage = data.readString();
-            int res = getPackageProcessState(pkg, callingPackage);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-
-        case SET_PROCESS_MEMORY_TRIM_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            String process = data.readString();
-            int userId = data.readInt();
-            int level = data.readInt();
-            boolean res = setProcessMemoryTrimLevel(process, userId, level);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case IS_ROOT_VOICE_INTERACTION_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            boolean res = isRootVoiceInteraction(token);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case START_BINDER_TRACKING_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            boolean res = startBinderTracking();
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-
-        case STOP_BINDER_TRACKING_AND_DUMP_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            ParcelFileDescriptor fd = data.readInt() != 0
-                    ? ParcelFileDescriptor.CREATOR.createFromParcel(data) : null;
-            boolean res = stopBinderTrackingAndDump(fd);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-        case GET_ACTIVITY_STACK_ID_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            int stackId = getActivityStackId(token);
-            reply.writeNoException();
-            reply.writeInt(stackId);
-            return true;
-        }
-        case EXIT_FREEFORM_MODE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            exitFreeformMode(token);
-            reply.writeNoException();
-            return true;
-        }
-        case REPORT_SIZE_CONFIGURATIONS: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IBinder token = data.readStrongBinder();
-            int[] horizontal = readIntArray(data);
-            int[] vertical = readIntArray(data);
-            int[] smallest = readIntArray(data);
-            reportSizeConfigurations(token, horizontal, vertical, smallest);
-            return true;
-        }
-        case SUPPRESS_RESIZE_CONFIG_CHANGES_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final boolean suppress = data.readInt() == 1;
-            suppressResizeConfigChanges(suppress);
-            reply.writeNoException();
-            return true;
-        }
-        case MOVE_TASKS_TO_FULLSCREEN_STACK_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int stackId = data.readInt();
-            final boolean onTop = data.readInt() == 1;
-            moveTasksToFullscreenStack(stackId, onTop);
-            reply.writeNoException();
-            return true;
-        }
-        case GET_APP_START_MODE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int uid = data.readInt();
-            final String pkg = data.readString();
-            int res = getAppStartMode(uid, pkg);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-        case IN_MULTI_WINDOW_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final IBinder token = data.readStrongBinder();
-            final boolean inMultiWindow = isInMultiWindowMode(token);
-            reply.writeNoException();
-            reply.writeInt(inMultiWindow ? 1 : 0);
-            return true;
-        }
-        case IN_PICTURE_IN_PICTURE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final IBinder token = data.readStrongBinder();
-            final boolean inPip = isInPictureInPictureMode(token);
-            reply.writeNoException();
-            reply.writeInt(inPip ? 1 : 0);
-            return true;
-        }
-        case ENTER_PICTURE_IN_PICTURE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final IBinder token = data.readStrongBinder();
-            enterPictureInPictureMode(token);
-            reply.writeNoException();
-            return true;
-        }
-        case GET_DEFAULT_PICTURE_IN_PICTURE_BOUNDS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Rect r = getDefaultPictureInPictureBounds();
-            reply.writeNoException();
-            r.writeToParcel(reply, 0);
-            return true;
-        }
-        case GET_PICTURE_IN_PICTURE_MOVEMENT_BOUNDS_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            Rect r = getPictureInPictureMovementBounds();
-            reply.writeNoException();
-            r.writeToParcel(reply, 0);
-            return true;
-        }
-        case SET_VR_MODE_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final IBinder token = data.readStrongBinder();
-            final boolean enable = data.readInt() == 1;
-            final ComponentName packageName = ComponentName.CREATOR.createFromParcel(data);
-            int res = setVrMode(token, enable, packageName);
-            reply.writeNoException();
-            reply.writeInt(res);
-            return true;
-        }
-        case IS_VR_PACKAGE_ENABLED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final ComponentName packageName = ComponentName.CREATOR.createFromParcel(data);
-            boolean res = isVrModePackageEnabled(packageName);
-            reply.writeNoException();
-            reply.writeInt(res ? 1 : 0);
-            return true;
-        }
-        case IS_APP_FOREGROUND_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int userHandle = data.readInt();
-            final boolean isForeground = isAppForeground(userHandle);
-            reply.writeNoException();
-            reply.writeInt(isForeground ? 1 : 0);
-            return true;
-        }
-        case NOTIFY_PINNED_STACK_ANIMATION_ENDED_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            reply.writeNoException();
-            return true;
-        }
-        case REMOVE_STACK: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int stackId = data.readInt();
-            removeStack(stackId);
-            reply.writeNoException();
-            return true;
-        }
-        case NOTIFY_LOCKED_PROFILE: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int userId = data.readInt();
-            notifyLockedProfile(userId);
-            reply.writeNoException();
-            return true;
-        }
-        case START_CONFIRM_DEVICE_CREDENTIAL_INTENT: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final Intent intent = Intent.CREATOR.createFromParcel(data);
-            startConfirmDeviceCredentialIntent(intent);
-            reply.writeNoException();
-            return true;
-        }
-        case SEND_IDLE_JOB_TRIGGER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            sendIdleJobTrigger();
-            reply.writeNoException();
-            return true;
-        }
-        case SEND_INTENT_SENDER_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            IIntentSender sender = IIntentSender.Stub.asInterface(data.readStrongBinder());
-            int scode = data.readInt();
-            Intent intent = data.readInt() != 0 ? Intent.CREATOR.createFromParcel(data) : null;
-            String resolvedType = data.readString();
-            IIntentReceiver finishedReceiver = IIntentReceiver.Stub.asInterface(
-                    data.readStrongBinder());
-            String requiredPermission = data.readString();
-            Bundle options = data.readInt() != 0 ? Bundle.CREATOR.createFromParcel(data) : null;
-            int result = sendIntentSender(sender, scode, intent, resolvedType, finishedReceiver,
-                    requiredPermission, options);
-            reply.writeNoException();
-            reply.writeInt(result);
-            return true;
-        }
-        case SET_VR_THREAD_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int tid = data.readInt();
-            setVrThread(tid);
-            reply.writeNoException();
-            return true;
-        }
-        case SET_RENDER_THREAD_TRANSACTION: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final int tid = data.readInt();
-            setRenderThread(tid);
-            reply.writeNoException();
-            return true;
-        }
-        case SET_HAS_TOP_UI: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final boolean hasTopUi = data.readInt() != 0;
-            setHasTopUi(hasTopUi);
-            reply.writeNoException();
-            return true;
-        }
-        case CAN_BYPASS_WORK_CHALLENGE: {
-            data.enforceInterface(IActivityManager.descriptor);
-            final PendingIntent intent = PendingIntent.CREATOR.createFromParcel(data);
-            final boolean result = canBypassWorkChallenge(intent);
-            reply.writeNoException();
-            reply.writeInt(result ? 1 : 0);
-            return true;
-        }
-        }
-
-        return super.onTransact(code, data, reply, flags);
-    }
-
-    private int[] readIntArray(Parcel data) {
-        int[] smallest = null;
-        int smallestSize = data.readInt();
-        if (smallestSize > 0) {
-            smallest = new int[smallestSize];
-            data.readIntArray(smallest);
-        }
-        return smallest;
-    }
-
-    public IBinder asBinder() {
-        return this;
-    }
-
-    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
-        protected IActivityManager create() {
-            IBinder b = ServiceManager.getService("activity");
-            if (false) {
-                Log.v("ActivityManager", "default service binder = " + b);
-            }
-            IActivityManager am = asInterface(b);
-            if (false) {
-                Log.v("ActivityManager", "default service = " + am);
-            }
-            return am;
-        }
-    };
-}
-
-class ActivityManagerProxy implements IActivityManager
-{
-    public ActivityManagerProxy(IBinder remote)
-    {
-        mRemote = remote;
-    }
-
-    public IBinder asBinder()
-    {
-        return mRemote;
-    }
-
-    public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
-            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
-            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(callingPackage);
-        intent.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(resultTo);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        data.writeInt(startFlags);
-        if (profilerInfo != null) {
-            data.writeInt(1);
-            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent,
-            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
-            int startFlags, ProfilerInfo profilerInfo, Bundle options,
-            int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(callingPackage);
-        intent.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(resultTo);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        data.writeInt(startFlags);
-        if (profilerInfo != null) {
-            data.writeInt(1);
-            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(userId);
-        mRemote.transact(START_ACTIVITY_AS_USER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-    public int startActivityAsCaller(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
-            int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
-            int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(callingPackage);
-        intent.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(resultTo);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        data.writeInt(startFlags);
-        if (profilerInfo != null) {
-            data.writeInt(1);
-            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(ignoreTargetSecurity ? 1 : 0);
-        data.writeInt(userId);
-        mRemote.transact(START_ACTIVITY_AS_CALLER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-    public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
-            int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options,
-            int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(callingPackage);
-        intent.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(resultTo);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        data.writeInt(startFlags);
-        if (profilerInfo != null) {
-            data.writeInt(1);
-            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(userId);
-        mRemote.transact(START_ACTIVITY_AND_WAIT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        WaitResult result = WaitResult.CREATOR.createFromParcel(reply);
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-    public int startActivityWithConfig(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
-            int requestCode, int startFlags, Configuration config,
-            Bundle options, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(callingPackage);
-        intent.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(resultTo);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        data.writeInt(startFlags);
-        config.writeToParcel(data, 0);
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(userId);
-        mRemote.transact(START_ACTIVITY_WITH_CONFIG_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-    public int startActivityIntentSender(IApplicationThread caller,
-            IntentSender intent, Intent fillInIntent, String resolvedType,
-            IBinder resultTo, String resultWho, int requestCode,
-            int flagsMask, int flagsValues, Bundle options) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        intent.writeToParcel(data, 0);
-        if (fillInIntent != null) {
-            data.writeInt(1);
-            fillInIntent.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeString(resolvedType);
-        data.writeStrongBinder(resultTo);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        data.writeInt(flagsMask);
-        data.writeInt(flagsValues);
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(START_ACTIVITY_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
-            Intent intent, String resolvedType, IVoiceInteractionSession session,
-            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
-            Bundle options, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(callingPackage);
-        data.writeInt(callingPid);
-        data.writeInt(callingUid);
-        intent.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(session.asBinder());
-        data.writeStrongBinder(interactor.asBinder());
-        data.writeInt(startFlags);
-        if (profilerInfo != null) {
-            data.writeInt(1);
-            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(userId);
-        mRemote.transact(START_VOICE_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(callingActivity);
-        data.writeBundle(options);
-        mRemote.transact(START_LOCAL_VOICE_INTERACTION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(callingActivity);
-        mRemote.transact(STOP_LOCAL_VOICE_INTERACTION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public boolean supportsLocalVoiceInteraction() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(SUPPORTS_LOCAL_VOICE_INTERACTION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result != 0;
-    }
-
-    public boolean startNextMatchingActivity(IBinder callingActivity,
-            Intent intent, Bundle options) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(callingActivity);
-        intent.writeToParcel(data, 0);
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(START_NEXT_MATCHING_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result != 0;
-    }
-    public int startActivityFromRecents(int taskId, Bundle options)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        if (options == null) {
-            data.writeInt(0);
-        } else {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        }
-        mRemote.transact(START_ACTIVITY_FROM_RECENTS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-    public boolean finishActivity(IBinder token, int resultCode, Intent resultData, int finishTask)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(resultCode);
-        if (resultData != null) {
-            data.writeInt(1);
-            resultData.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(finishTask);
-        mRemote.transact(FINISH_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        mRemote.transact(FINISH_SUB_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public boolean finishActivityAffinity(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(FINISH_ACTIVITY_AFFINITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void finishVoiceTask(IVoiceInteractionSession session) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(session.asBinder());
-        mRemote.transact(FINISH_VOICE_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void requestActivityRelaunch(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(REQUEST_ACTIVITY_RELAUNCH, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public boolean releaseActivityInstance(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(RELEASE_ACTIVITY_INSTANCE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void releaseSomeActivities(IApplicationThread app) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(app.asBinder());
-        mRemote.transact(RELEASE_SOME_ACTIVITIES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public boolean willActivityBeVisible(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(WILL_ACTIVITY_BE_VISIBLE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public Intent registerReceiver(IApplicationThread caller, String packageName,
-            IIntentReceiver receiver,
-            IntentFilter filter, String perm, int userId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(packageName);
-        data.writeStrongBinder(receiver != null ? receiver.asBinder() : null);
-        filter.writeToParcel(data, 0);
-        data.writeString(perm);
-        data.writeInt(userId);
-        mRemote.transact(REGISTER_RECEIVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Intent intent = null;
-        int haveIntent = reply.readInt();
-        if (haveIntent != 0) {
-            intent = Intent.CREATOR.createFromParcel(reply);
-        }
-        reply.recycle();
-        data.recycle();
-        return intent;
-    }
-    public void unregisterReceiver(IIntentReceiver receiver) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(receiver.asBinder());
-        mRemote.transact(UNREGISTER_RECEIVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public int broadcastIntent(IApplicationThread caller,
-            Intent intent, String resolvedType, IIntentReceiver resultTo,
-            int resultCode, String resultData, Bundle map,
-            String[] requiredPermissions, int appOp, Bundle options, boolean serialized,
-            boolean sticky, int userId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        intent.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(resultTo != null ? resultTo.asBinder() : null);
-        data.writeInt(resultCode);
-        data.writeString(resultData);
-        data.writeBundle(map);
-        data.writeStringArray(requiredPermissions);
-        data.writeInt(appOp);
-        data.writeBundle(options);
-        data.writeInt(serialized ? 1 : 0);
-        data.writeInt(sticky ? 1 : 0);
-        data.writeInt(userId);
-        mRemote.transact(BROADCAST_INTENT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-    public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId)
-            throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        intent.writeToParcel(data, 0);
-        data.writeInt(userId);
-        mRemote.transact(UNBROADCAST_INTENT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
-            boolean abortBroadcast, int flags) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(who);
-        data.writeInt(resultCode);
-        data.writeString(resultData);
-        data.writeBundle(map);
-        data.writeInt(abortBroadcast ? 1 : 0);
-        data.writeInt(flags);
-        mRemote.transact(FINISH_RECEIVER_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void attachApplication(IApplicationThread app) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(app.asBinder());
-        mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void activityIdle(IBinder token, Configuration config, boolean stopProfiling)
-            throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        if (config != null) {
-            data.writeInt(1);
-            config.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(stopProfiling ? 1 : 0);
-        mRemote.transact(ACTIVITY_IDLE_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void activityResumed(IBinder token) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(ACTIVITY_RESUMED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void activityPaused(IBinder token) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void activityStopped(IBinder token, Bundle state,
-            PersistableBundle persistentState, CharSequence description) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeBundle(state);
-        data.writePersistableBundle(persistentState);
-        TextUtils.writeToParcel(description, data, 0);
-        mRemote.transact(ACTIVITY_STOPPED_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void activitySlept(IBinder token) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(ACTIVITY_SLEPT_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void activityDestroyed(IBinder token) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(ACTIVITY_DESTROYED_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void activityRelaunched(IBinder token) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(ACTIVITY_RELAUNCHED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public String getCallingPackage(IBinder token) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_CALLING_PACKAGE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        String res = reply.readString();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public ComponentName getCallingActivity(IBinder token)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_CALLING_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ComponentName res = ComponentName.readFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public List<IAppTask> getAppTasks(String callingPackage) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(callingPackage);
-        mRemote.transact(GET_APP_TASKS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ArrayList<IAppTask> list = null;
-        int N = reply.readInt();
-        if (N >= 0) {
-            list = new ArrayList<>();
-            while (N > 0) {
-                IAppTask task = IAppTask.Stub.asInterface(reply.readStrongBinder());
-                list.add(task);
-                N--;
-            }
-        }
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    public int addAppTask(IBinder activityToken, Intent intent,
-            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(activityToken);
-        intent.writeToParcel(data, 0);
-        description.writeToParcel(data, 0);
-        thumbnail.writeToParcel(data, 0);
-        mRemote.transact(ADD_APP_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public Point getAppTaskThumbnailSize() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_APP_TASK_THUMBNAIL_SIZE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Point size = Point.CREATOR.createFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return size;
-    }
-    public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum, int flags)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(maxNum);
-        data.writeInt(flags);
-        mRemote.transact(GET_TASKS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ArrayList<ActivityManager.RunningTaskInfo> list = null;
-        int N = reply.readInt();
-        if (N >= 0) {
-            list = new ArrayList<>();
-            while (N > 0) {
-                ActivityManager.RunningTaskInfo info =
-                        ActivityManager.RunningTaskInfo.CREATOR
-                                .createFromParcel(reply);
-                list.add(info);
-                N--;
-            }
-        }
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
-            int flags, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(maxNum);
-        data.writeInt(flags);
-        data.writeInt(userId);
-        mRemote.transact(GET_RECENT_TASKS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final ParceledListSlice<ActivityManager.RecentTaskInfo> list = ParceledListSlice.CREATOR
-                .createFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(id);
-        mRemote.transact(GET_TASK_THUMBNAIL_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ActivityManager.TaskThumbnail taskThumbnail = null;
-        if (reply.readInt() != 0) {
-            taskThumbnail = ActivityManager.TaskThumbnail.CREATOR.createFromParcel(reply);
-        }
-        data.recycle();
-        reply.recycle();
-        return taskThumbnail;
-    }
-    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(maxNum);
-        data.writeInt(flags);
-        mRemote.transact(GET_SERVICES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ArrayList<ActivityManager.RunningServiceInfo> list = null;
-        int N = reply.readInt();
-        if (N >= 0) {
-            list = new ArrayList<>();
-            while (N > 0) {
-                ActivityManager.RunningServiceInfo info =
-                        ActivityManager.RunningServiceInfo.CREATOR
-                        .createFromParcel(reply);
-                list.add(info);
-                N--;
-            }
-        }
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState()
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_PROCESSES_IN_ERROR_STATE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ArrayList<ActivityManager.ProcessErrorStateInfo> list
-            = reply.createTypedArrayList(ActivityManager.ProcessErrorStateInfo.CREATOR);
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses()
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_RUNNING_APP_PROCESSES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ArrayList<ActivityManager.RunningAppProcessInfo> list
-        = reply.createTypedArrayList(ActivityManager.RunningAppProcessInfo.CREATOR);
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    public List<ApplicationInfo> getRunningExternalApplications()
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_RUNNING_EXTERNAL_APPLICATIONS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ArrayList<ApplicationInfo> list
-        = reply.createTypedArrayList(ApplicationInfo.CREATOR);
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    public void moveTaskToFront(int task, int flags, Bundle options) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(task);
-        data.writeInt(flags);
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(MOVE_TASK_TO_FRONT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(nonRoot ? 1 : 0);
-        mRemote.transact(MOVE_ACTIVITY_TASK_TO_BACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void moveTaskBackwards(int task) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(task);
-        mRemote.transact(MOVE_TASK_BACKWARDS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        data.writeInt(stackId);
-        data.writeInt(toTop ? 1 : 0);
-        mRemote.transact(MOVE_TASK_TO_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
-            Rect initialBounds, boolean moveHomeStackFront) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        data.writeInt(createMode);
-        data.writeInt(toTop ? 1 : 0);
-        data.writeInt(animate ? 1 : 0);
-        if (initialBounds != null) {
-            data.writeInt(1);
-            initialBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(moveHomeStackFront ? 1 : 0);
-        mRemote.transact(MOVE_TASK_TO_DOCKED_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() > 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    @Override
-    public boolean moveTopActivityToPinnedStack(int stackId, Rect r)
-        throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(stackId);
-        r.writeToParcel(data, 0);
-        mRemote.transact(MOVE_TOP_ACTIVITY_TO_PINNED_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    @Override
-    public void resizeStack(int stackId, Rect r, boolean allowResizeInDockedMode,
-            boolean preserveWindows, boolean animate, int animationDuration)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(stackId);
-        if (r != null) {
-            data.writeInt(1);
-            r.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(allowResizeInDockedMode ? 1 : 0);
-        data.writeInt(preserveWindows ? 1 : 0);
-        data.writeInt(animate ? 1 : 0);
-        data.writeInt(animationDuration);
-        mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public void swapDockedAndFullscreenStack() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(SWAP_DOCKED_AND_FULLSCREEN_STACK, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
-            Rect tempDockedTaskInsetBounds,
-            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds)
-            throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        if (dockedBounds != null) {
-            data.writeInt(1);
-            dockedBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        if (tempDockedTaskBounds != null) {
-            data.writeInt(1);
-            tempDockedTaskBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        if (tempDockedTaskInsetBounds != null) {
-            data.writeInt(1);
-            tempDockedTaskInsetBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        if (tempOtherTaskBounds != null) {
-            data.writeInt(1);
-            tempOtherTaskBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        if (tempOtherTaskInsetBounds != null) {
-            data.writeInt(1);
-            tempOtherTaskInsetBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(RESIZE_DOCKED_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        if (pinnedBounds != null) {
-            data.writeInt(1);
-            pinnedBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        if (tempPinnedTaskBounds != null) {
-            data.writeInt(1);
-            tempPinnedTaskBounds.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(RESIZE_PINNED_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void positionTaskInStack(int taskId, int stackId, int position) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        data.writeInt(stackId);
-        data.writeInt(position);
-        mRemote.transact(POSITION_TASK_IN_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public List<StackInfo> getAllStackInfos() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_ALL_STACK_INFOS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ArrayList<StackInfo> list = reply.createTypedArrayList(StackInfo.CREATOR);
-        data.recycle();
-        reply.recycle();
-        return list;
-    }
-    @Override
-    public StackInfo getStackInfo(int stackId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(stackId);
-        mRemote.transact(GET_STACK_INFO_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        StackInfo info = null;
-        if (res != 0) {
-            info = StackInfo.CREATOR.createFromParcel(reply);
-        }
-        data.recycle();
-        reply.recycle();
-        return info;
-    }
-    @Override
-    public boolean isInHomeStack(int taskId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        mRemote.transact(IS_IN_HOME_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean isInHomeStack = reply.readInt() > 0;
-        data.recycle();
-        reply.recycle();
-        return isInHomeStack;
-    }
-    @Override
-    public void setFocusedStack(int stackId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(stackId);
-        mRemote.transact(SET_FOCUSED_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public int getFocusedStackId() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_FOCUSED_STACK_ID_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int focusedStackId = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return focusedStackId;
-    }
-    @Override
-    public void setFocusedTask(int taskId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        mRemote.transact(SET_FOCUSED_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    @Override
-    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(listener.asBinder());
-        mRemote.transact(REGISTER_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();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(onlyRoot ? 1 : 0);
-        mRemote.transact(GET_TASK_FOR_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public ContentProviderHolder getContentProvider(IApplicationThread caller,
-            String name, int userId, boolean stable) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(name);
-        data.writeInt(userId);
-        data.writeInt(stable ? 1 : 0);
-        mRemote.transact(GET_CONTENT_PROVIDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        ContentProviderHolder cph = null;
-        if (res != 0) {
-            cph = ContentProviderHolder.CREATOR.createFromParcel(reply);
-        }
-        data.recycle();
-        reply.recycle();
-        return cph;
-    }
-    public ContentProviderHolder getContentProviderExternal(String name, int userId, IBinder token)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(name);
-        data.writeInt(userId);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        ContentProviderHolder cph = null;
-        if (res != 0) {
-            cph = ContentProviderHolder.CREATOR.createFromParcel(reply);
-        }
-        data.recycle();
-        reply.recycle();
-        return cph;
-    }
-    public void publishContentProviders(IApplicationThread caller,
-            List<ContentProviderHolder> providers) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeTypedList(providers);
-        mRemote.transact(PUBLISH_CONTENT_PROVIDERS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public boolean refContentProvider(IBinder connection, int stable, int unstable)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(connection);
-        data.writeInt(stable);
-        data.writeInt(unstable);
-        mRemote.transact(REF_CONTENT_PROVIDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void unstableProviderDied(IBinder connection) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(connection);
-        mRemote.transact(UNSTABLE_PROVIDER_DIED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void appNotRespondingViaProvider(IBinder connection) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(connection);
-        mRemote.transact(APP_NOT_RESPONDING_VIA_PROVIDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void removeContentProvider(IBinder connection, boolean stable) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(connection);
-        data.writeInt(stable ? 1 : 0);
-        mRemote.transact(REMOVE_CONTENT_PROVIDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void removeContentProviderExternal(String name, IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(name);
-        data.writeStrongBinder(token);
-        mRemote.transact(REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public PendingIntent getRunningServiceControlPanel(ComponentName service)
-            throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        service.writeToParcel(data, 0);
-        mRemote.transact(GET_RUNNING_SERVICE_CONTROL_PANEL_TRANSACTION, data, reply, 0);
-        reply.readException();
-        PendingIntent res = PendingIntent.readPendingIntentOrNullFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public ComponentName startService(IApplicationThread caller, Intent service,
-            String resolvedType, String callingPackage, int userId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        service.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeString(callingPackage);
-        data.writeInt(userId);
-        mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ComponentName res = ComponentName.readFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public int stopService(IApplicationThread caller, Intent service,
-            String resolvedType, int userId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        service.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeInt(userId);
-        mRemote.transact(STOP_SERVICE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-    public boolean stopServiceToken(ComponentName className, IBinder token,
-            int startId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        ComponentName.writeToParcel(className, data);
-        data.writeStrongBinder(token);
-        data.writeInt(startId);
-        mRemote.transact(STOP_SERVICE_TOKEN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void setServiceForeground(ComponentName className, IBinder token,
-            int id, Notification notification, int flags) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        ComponentName.writeToParcel(className, data);
-        data.writeStrongBinder(token);
-        data.writeInt(id);
-        if (notification != null) {
-            data.writeInt(1);
-            notification.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(flags);
-        mRemote.transact(SET_SERVICE_FOREGROUND_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public int bindService(IApplicationThread caller, IBinder token,
-            Intent service, String resolvedType, IServiceConnection connection,
-            int flags,  String callingPackage, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeStrongBinder(token);
-        service.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeStrongBinder(connection.asBinder());
-        data.writeInt(flags);
-        data.writeString(callingPackage);
-        data.writeInt(userId);
-        mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public boolean unbindService(IServiceConnection connection) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(connection.asBinder());
-        mRemote.transact(UNBIND_SERVICE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void publishService(IBinder token,
-            Intent intent, IBinder service) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        intent.writeToParcel(data, 0);
-        data.writeStrongBinder(service);
-        mRemote.transact(PUBLISH_SERVICE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void unbindFinished(IBinder token, Intent intent, boolean doRebind)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        intent.writeToParcel(data, 0);
-        data.writeInt(doRebind ? 1 : 0);
-        mRemote.transact(UNBIND_FINISHED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void serviceDoneExecuting(IBinder token, int type, int startId,
-            int res) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(type);
-        data.writeInt(startId);
-        data.writeInt(res);
-        mRemote.transact(SERVICE_DONE_EXECUTING_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public IBinder peekService(Intent service, String resolvedType, String callingPackage)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        service.writeToParcel(data, 0);
-        data.writeString(resolvedType);
-        data.writeString(callingPackage);
-        mRemote.transact(PEEK_SERVICE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        IBinder binder = reply.readStrongBinder();
-        reply.recycle();
-        data.recycle();
-        return binder;
-    }
-
-    public boolean bindBackupAgent(String packageName, int backupRestoreMode, int userId)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(backupRestoreMode);
-        data.writeInt(userId);
-        mRemote.transact(START_BACKUP_AGENT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean success = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return success;
-    }
-
-    public void clearPendingBackup() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(CLEAR_PENDING_BACKUP_TRANSACTION, data, reply, 0);
-        reply.recycle();
-        data.recycle();
-    }
-
-    public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeStrongBinder(agent);
-        mRemote.transact(BACKUP_AGENT_CREATED_TRANSACTION, data, reply, 0);
-        reply.recycle();
-        data.recycle();
-    }
-
-    public void unbindBackupAgent(ApplicationInfo app) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        app.writeToParcel(data, 0);
-        mRemote.transact(UNBIND_BACKUP_AGENT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public boolean startInstrumentation(ComponentName className, String profileFile,
-            int flags, Bundle arguments, IInstrumentationWatcher watcher,
-            IUiAutomationConnection connection, int userId, String instructionSet)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        ComponentName.writeToParcel(className, data);
-        data.writeString(profileFile);
-        data.writeInt(flags);
-        data.writeBundle(arguments);
-        data.writeStrongBinder(watcher != null ? watcher.asBinder() : null);
-        data.writeStrongBinder(connection != null ? connection.asBinder() : null);
-        data.writeInt(userId);
-        data.writeString(instructionSet);
-        mRemote.transact(START_INSTRUMENTATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public void finishInstrumentation(IApplicationThread target,
-            int resultCode, Bundle results) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(target != null ? target.asBinder() : null);
-        data.writeInt(resultCode);
-        data.writeBundle(results);
-        mRemote.transact(FINISH_INSTRUMENTATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public Configuration getConfiguration() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_CONFIGURATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Configuration res = Configuration.CREATOR.createFromParcel(reply);
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-    public boolean updateConfiguration(Configuration values) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        values.writeToParcel(data, 0);
-        mRemote.transact(UPDATE_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();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(requestedOrientation);
-        mRemote.transact(SET_REQUESTED_ORIENTATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public int getRequestedOrientation(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_REQUESTED_ORIENTATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public ComponentName getActivityClassForToken(IBinder token)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_ACTIVITY_CLASS_FOR_TOKEN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ComponentName res = ComponentName.readFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public String getPackageForToken(IBinder token) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_PACKAGE_FOR_TOKEN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        String res = reply.readString();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public IIntentSender getIntentSender(int type,
-            String packageName, IBinder token, String resultWho,
-            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
-            Bundle options, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(type);
-        data.writeString(packageName);
-        data.writeStrongBinder(token);
-        data.writeString(resultWho);
-        data.writeInt(requestCode);
-        if (intents != null) {
-            data.writeInt(1);
-            data.writeTypedArray(intents, 0);
-            data.writeStringArray(resolvedTypes);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(flags);
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(userId);
-        mRemote.transact(GET_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        IIntentSender res = IIntentSender.Stub.asInterface(
-                reply.readStrongBinder());
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void cancelIntentSender(IIntentSender sender) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        mRemote.transact(CANCEL_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public String getPackageForIntentSender(IIntentSender sender) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        mRemote.transact(GET_PACKAGE_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        String res = reply.readString();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public int getUidForIntentSender(IIntentSender sender) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        mRemote.transact(GET_UID_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
-            boolean requireFull, String name, String callerPackage) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(callingPid);
-        data.writeInt(callingUid);
-        data.writeInt(userId);
-        data.writeInt(allowAll ? 1 : 0);
-        data.writeInt(requireFull ? 1 : 0);
-        data.writeString(name);
-        data.writeString(callerPackage);
-        mRemote.transact(HANDLE_INCOMING_USER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void setProcessLimit(int max) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(max);
-        mRemote.transact(SET_PROCESS_LIMIT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public int getProcessLimit() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_PROCESS_LIMIT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void setProcessForeground(IBinder token, int pid,
-            boolean isForeground) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(pid);
-        data.writeInt(isForeground ? 1 : 0);
-        mRemote.transact(SET_PROCESS_FOREGROUND_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public int checkPermission(String permission, int pid, int uid)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(permission);
-        data.writeInt(pid);
-        data.writeInt(uid);
-        mRemote.transact(CHECK_PERMISSION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(permission);
-        data.writeInt(pid);
-        data.writeInt(uid);
-        data.writeStrongBinder(callerToken);
-        mRemote.transact(CHECK_PERMISSION_WITH_TOKEN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public boolean clearApplicationUserData(final String packageName,
-            final IPackageDataObserver observer, final int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeStrongBinder((observer != null) ? observer.asBinder() : null);
-        data.writeInt(userId);
-        mRemote.transact(CLEAR_APP_DATA_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId,
-            IBinder callerToken) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        uri.writeToParcel(data, 0);
-        data.writeInt(pid);
-        data.writeInt(uid);
-        data.writeInt(mode);
-        data.writeInt(userId);
-        data.writeStrongBinder(callerToken);
-        mRemote.transact(CHECK_URI_PERMISSION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public void grantUriPermission(IApplicationThread caller, String targetPkg,
-            Uri uri, int mode, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller.asBinder());
-        data.writeString(targetPkg);
-        uri.writeToParcel(data, 0);
-        data.writeInt(mode);
-        data.writeInt(userId);
-        mRemote.transact(GRANT_URI_PERMISSION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void revokeUriPermission(IApplicationThread caller, Uri uri,
-            int mode, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller.asBinder());
-        uri.writeToParcel(data, 0);
-        data.writeInt(mode);
-        data.writeInt(userId);
-        mRemote.transact(REVOKE_URI_PERMISSION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void takePersistableUriPermission(Uri uri, int mode, int userId)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        uri.writeToParcel(data, 0);
-        data.writeInt(mode);
-        data.writeInt(userId);
-        mRemote.transact(TAKE_PERSISTABLE_URI_PERMISSION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void releasePersistableUriPermission(Uri uri, int mode, int userId)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        uri.writeToParcel(data, 0);
-        data.writeInt(mode);
-        data.writeInt(userId);
-        mRemote.transact(RELEASE_PERSISTABLE_URI_PERMISSION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public ParceledListSlice<UriPermission> getPersistedUriPermissions(
-            String packageName, boolean incoming) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(incoming ? 1 : 0);
-        mRemote.transact(GET_PERSISTED_URI_PERMISSIONS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        @SuppressWarnings("unchecked")
-        final ParceledListSlice<UriPermission> perms = ParceledListSlice.CREATOR.createFromParcel(
-                reply);
-        data.recycle();
-        reply.recycle();
-        return perms;
-    }
-
-    @Override
-    public ParceledListSlice<UriPermission> getGrantedUriPermissions(String packageName, int userId)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(userId);
-        mRemote.transact(GET_GRANTED_URI_PERMISSIONS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        @SuppressWarnings("unchecked")
-        final ParceledListSlice<UriPermission> perms = ParceledListSlice.CREATOR.createFromParcel(
-                reply);
-        data.recycle();
-        reply.recycle();
-        return perms;
-    }
-
-    @Override
-    public void clearGrantedUriPermissions(String packageName, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(userId);
-        mRemote.transact(CLEAR_GRANTED_URI_PERMISSIONS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void showWaitingForDebugger(IApplicationThread who, boolean waiting)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(who.asBinder());
-        data.writeInt(waiting ? 1 : 0);
-        mRemote.transact(SHOW_WAITING_FOR_DEBUGGER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_MEMORY_INFO_TRANSACTION, data, reply, 0);
-        reply.readException();
-        outInfo.readFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-    }
-    public void unhandledBack() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(UNHANDLED_BACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(OPEN_CONTENT_URI_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ParcelFileDescriptor pfd = null;
-        if (reply.readInt() != 0) {
-            pfd = ParcelFileDescriptor.CREATOR.createFromParcel(reply);
-        }
-        data.recycle();
-        reply.recycle();
-        return pfd;
-    }
-    public void setLockScreenShown(boolean showing, boolean occluded) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(showing ? 1 : 0);
-        data.writeInt(occluded ? 1 : 0);
-        mRemote.transact(SET_LOCK_SCREEN_SHOWN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void setDebugApp(
-        String packageName, boolean waitForDebugger, boolean persistent)
-        throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(waitForDebugger ? 1 : 0);
-        data.writeInt(persistent ? 1 : 0);
-        mRemote.transact(SET_DEBUG_APP_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void setAlwaysFinish(boolean enabled) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(enabled ? 1 : 0);
-        mRemote.transact(SET_ALWAYS_FINISH_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void setActivityController(IActivityController watcher, boolean imAMonkey)
-            throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(watcher != null ? watcher.asBinder() : null);
-        data.writeInt(imAMonkey ? 1 : 0);
-        mRemote.transact(SET_ACTIVITY_CONTROLLER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public void setLenientBackgroundCheck(boolean enabled) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(enabled ? 1 : 0);
-        mRemote.transact(SET_LENIENT_BACKGROUND_CHECK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-    public int getMemoryTrimLevel() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_MEMORY_TRIM_LEVEL_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int level = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return level;
-    }
-    public void enterSafeMode() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(ENTER_SAFE_MODE_TRANSACTION, data, null, 0);
-        data.recycle();
-    }
-    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        data.writeInt(sourceUid);
-        data.writeString(sourcePkg);
-        data.writeString(tag);
-        mRemote.transact(NOTE_WAKEUP_ALARM_TRANSACTION, data, null, 0);
-        data.recycle();
-    }
-    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        data.writeInt(sourceUid);
-        data.writeString(tag);
-        mRemote.transact(NOTE_ALARM_START_TRANSACTION, data, null, 0);
-        data.recycle();
-    }
-    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        data.writeInt(sourceUid);
-        data.writeString(tag);
-        mRemote.transact(NOTE_ALARM_FINISH_TRANSACTION, data, null, 0);
-        data.recycle();
-    }
-    public boolean killPids(int[] pids, String reason, boolean secure) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeIntArray(pids);
-        data.writeString(reason);
-        data.writeInt(secure ? 1 : 0);
-        mRemote.transact(KILL_PIDS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    @Override
-    public boolean killProcessesBelowForeground(String reason) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(reason);
-        mRemote.transact(KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION, data, reply, 0);
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-    public boolean testIsSystemReady()
-    {
-        /* this base class version is never called */
-        return true;
-    }
-    public void handleApplicationCrash(IBinder app,
-            ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(app);
-        crashInfo.writeToParcel(data, 0);
-        mRemote.transact(HANDLE_APPLICATION_CRASH_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public boolean handleApplicationWtf(IBinder app, String tag, boolean system,
-            ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(app);
-        data.writeString(tag);
-        data.writeInt(system ? 1 : 0);
-        crashInfo.writeToParcel(data, 0);
-        mRemote.transact(HANDLE_APPLICATION_WTF_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public void handleApplicationStrictModeViolation(IBinder app,
-            int violationMask,
-            StrictMode.ViolationInfo info) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(app);
-        data.writeInt(violationMask);
-        info.writeToParcel(data, 0);
-        mRemote.transact(HANDLE_APPLICATION_STRICT_MODE_VIOLATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public void signalPersistentProcesses(int sig) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(sig);
-        mRemote.transact(SIGNAL_PERSISTENT_PROCESSES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void killBackgroundProcesses(String packageName, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(userId);
-        mRemote.transact(KILL_BACKGROUND_PROCESSES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void killAllBackgroundProcesses() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void killPackageDependents(String packageName, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(userId);
-        mRemote.transact(KILL_PACKAGE_DEPENDENTS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void forceStopPackage(String packageName, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(userId);
-        mRemote.transact(FORCE_STOP_PACKAGE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo)
-            throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_MY_MEMORY_STATE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        outInfo.readFromParcel(reply);
-        reply.recycle();
-        data.recycle();
-    }
-
-    public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_DEVICE_CONFIGURATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ConfigurationInfo res = ConfigurationInfo.CREATOR.createFromParcel(reply);
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public boolean profileControl(String process, int userId, boolean start,
-            ProfilerInfo profilerInfo, int profileType) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(process);
-        data.writeInt(userId);
-        data.writeInt(start ? 1 : 0);
-        data.writeInt(profileType);
-        if (profilerInfo != null) {
-            data.writeInt(1);
-            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(PROFILE_CONTROL_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public boolean shutdown(int timeout) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(timeout);
-        mRemote.transact(SHUTDOWN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public void stopAppSwitches() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(STOP_APP_SWITCHES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public void resumeAppSwitches() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(RESUME_APP_SWITCHES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public void addPackageDependency(String packageName) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        mRemote.transact(ADD_PACKAGE_DEPENDENCY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void killApplication(String pkg, int appId, int userId, String reason)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(pkg);
-        data.writeInt(appId);
-        data.writeInt(userId);
-        data.writeString(reason);
-        mRemote.transact(KILL_APPLICATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void closeSystemDialogs(String reason) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(reason);
-        mRemote.transact(CLOSE_SYSTEM_DIALOGS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeIntArray(pids);
-        mRemote.transact(GET_PROCESS_MEMORY_INFO_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Debug.MemoryInfo[] res = reply.createTypedArray(Debug.MemoryInfo.CREATOR);
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void killApplicationProcess(String processName, int uid) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(processName);
-        data.writeInt(uid);
-        mRemote.transact(KILL_APPLICATION_PROCESS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void overridePendingTransition(IBinder token, String packageName,
-            int enterAnim, int exitAnim) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeString(packageName);
-        data.writeInt(enterAnim);
-        data.writeInt(exitAnim);
-        mRemote.transact(OVERRIDE_PENDING_TRANSITION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public boolean isUserAMonkey() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(IS_USER_A_MONKEY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void setUserIsMonkey(boolean monkey) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(monkey ? 1 : 0);
-        mRemote.transact(SET_USER_IS_MONKEY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void finishHeavyWeightApp() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(FINISH_HEAVY_WEIGHT_APP_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public boolean convertFromTranslucent(IBinder token)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(CONVERT_FROM_TRANSLUCENT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean convertToTranslucent(IBinder token, ActivityOptions options)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        if (options == null) {
-            data.writeInt(0);
-        } else {
-            data.writeInt(1);
-            data.writeBundle(options.toBundle());
-        }
-        mRemote.transact(CONVERT_TO_TRANSLUCENT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public ActivityOptions getActivityOptions(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_ACTIVITY_OPTIONS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        ActivityOptions options = ActivityOptions.fromBundle(reply.readBundle());
-        data.recycle();
-        reply.recycle();
-        return options;
-    }
-
-    public void setImmersive(IBinder token, boolean immersive)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(immersive ? 1 : 0);
-        mRemote.transact(SET_IMMERSIVE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public boolean isImmersive(IBinder token)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(IS_IMMERSIVE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() == 1;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean isTopOfTask(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(IS_TOP_OF_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() == 1;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean isTopActivityImmersive()
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(IS_TOP_ACTIVITY_IMMERSIVE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() == 1;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void crashApplication(int uid, int initialPid, String packageName,
-            String message) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(uid);
-        data.writeInt(initialPid);
-        data.writeString(packageName);
-        data.writeString(message);
-        mRemote.transact(CRASH_APPLICATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public String getProviderMimeType(Uri uri, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        uri.writeToParcel(data, 0);
-        data.writeInt(userId);
-        mRemote.transact(GET_PROVIDER_MIME_TYPE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        String res = reply.readString();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public IBinder newUriPermissionOwner(String name)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(name);
-        mRemote.transact(NEW_URI_PERMISSION_OWNER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        IBinder res = reply.readStrongBinder();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(activityToken);
-        mRemote.transact(GET_URI_PERMISSION_OWNER_FOR_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        IBinder res = reply.readStrongBinder();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void grantUriPermissionFromOwner(IBinder owner, int fromUid, String targetPkg,
-            Uri uri, int mode, int sourceUserId, int targetUserId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(owner);
-        data.writeInt(fromUid);
-        data.writeString(targetPkg);
-        uri.writeToParcel(data, 0);
-        data.writeInt(mode);
-        data.writeInt(sourceUserId);
-        data.writeInt(targetUserId);
-        mRemote.transact(GRANT_URI_PERMISSION_FROM_OWNER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void revokeUriPermissionFromOwner(IBinder owner, Uri uri,
-            int mode, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(owner);
-        if (uri != null) {
-            data.writeInt(1);
-            uri.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(mode);
-        data.writeInt(userId);
-        mRemote.transact(REVOKE_URI_PERMISSION_FROM_OWNER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public int checkGrantUriPermission(int callingUid, String targetPkg,
-            Uri uri, int modeFlags, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(callingUid);
-        data.writeString(targetPkg);
-        uri.writeToParcel(data, 0);
-        data.writeInt(modeFlags);
-        data.writeInt(userId);
-        mRemote.transact(CHECK_GRANT_URI_PERMISSION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean dumpHeap(String process, int userId, boolean managed,
-            String path, ParcelFileDescriptor fd) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(process);
-        data.writeInt(userId);
-        data.writeInt(managed ? 1 : 0);
-        data.writeString(path);
-        if (fd != null) {
-            data.writeInt(1);
-            fd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(DUMP_HEAP_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public int startActivities(IApplicationThread caller, String callingPackage,
-            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
-            Bundle options, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
-        data.writeString(callingPackage);
-        data.writeTypedArray(intents, 0);
-        data.writeStringArray(resolvedTypes);
-        data.writeStrongBinder(resultTo);
-        if (options != null) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        data.writeInt(userId);
-        mRemote.transact(START_ACTIVITIES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public int getFrontActivityScreenCompatMode() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int mode = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return mode;
-    }
-
-    public void setFrontActivityScreenCompatMode(int mode) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(mode);
-        mRemote.transact(SET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public int getPackageScreenCompatMode(String packageName) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        mRemote.transact(GET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int mode = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return mode;
-    }
-
-    public void setPackageScreenCompatMode(String packageName, int mode)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(mode);
-        mRemote.transact(SET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public boolean getPackageAskScreenCompat(String packageName) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        mRemote.transact(GET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean ask = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return ask;
-    }
-
-    public void setPackageAskScreenCompat(String packageName, boolean ask)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeInt(ask ? 1 : 0);
-        mRemote.transact(SET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        reply.recycle();
-        data.recycle();
-    }
-
-    public boolean switchUser(int userid) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(userid);
-        mRemote.transact(SWITCH_USER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public boolean startUserInBackground(int userid) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(userid);
-        mRemote.transact(START_USER_IN_BACKGROUND_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(userId);
-        data.writeByteArray(token);
-        data.writeByteArray(secret);
-        data.writeStrongInterface(listener);
-        mRemote.transact(IActivityManager.UNLOCK_USER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public int stopUser(int userid, boolean force, IStopUserCallback callback)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(userid);
-        data.writeInt(force ? 1 : 0);
-        data.writeStrongInterface(callback);
-        mRemote.transact(STOP_USER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public UserInfo getCurrentUser() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_CURRENT_USER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        UserInfo userInfo = UserInfo.CREATOR.createFromParcel(reply);
-        reply.recycle();
-        data.recycle();
-        return userInfo;
-    }
-
-    public boolean isUserRunning(int userid, int flags) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(userid);
-        data.writeInt(flags);
-        mRemote.transact(IS_USER_RUNNING_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public int[] getRunningUserIds() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_RUNNING_USER_IDS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int[] result = reply.createIntArray();
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public boolean removeTask(int taskId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        mRemote.transact(REMOVE_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return result;
-    }
-
-    public void registerProcessObserver(IProcessObserver observer) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(observer != null ? observer.asBinder() : null);
-        mRemote.transact(REGISTER_PROCESS_OBSERVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void unregisterProcessObserver(IProcessObserver observer) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(observer != null ? observer.asBinder() : null);
-        mRemote.transact(UNREGISTER_PROCESS_OBSERVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void registerUidObserver(IUidObserver observer, int which) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(observer != null ? observer.asBinder() : null);
-        data.writeInt(which);
-        mRemote.transact(REGISTER_UID_OBSERVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void unregisterUidObserver(IUidObserver observer) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(observer != null ? observer.asBinder() : null);
-        mRemote.transact(UNREGISTER_UID_OBSERVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public boolean isIntentSenderTargetedToPackage(IIntentSender sender) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        mRemote.transact(IS_INTENT_SENDER_TARGETED_TO_PACKAGE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean isIntentSenderAnActivity(IIntentSender sender) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        mRemote.transact(IS_INTENT_SENDER_AN_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public Intent getIntentForIntentSender(IIntentSender sender) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        mRemote.transact(GET_INTENT_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Intent res = reply.readInt() != 0
-                ? Intent.CREATOR.createFromParcel(reply) : null;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public String getTagForIntentSender(IIntentSender sender, String prefix)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(sender.asBinder());
-        data.writeString(prefix);
-        mRemote.transact(GET_TAG_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        String res = reply.readString();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void updatePersistentConfiguration(Configuration values) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        values.writeToParcel(data, 0);
-        mRemote.transact(UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public long[] getProcessPss(int[] pids) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeIntArray(pids);
-        mRemote.transact(GET_PROCESS_PSS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        long[] res = reply.createLongArray();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void showBootMessage(CharSequence msg, boolean always) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        TextUtils.writeToParcel(msg, data, 0);
-        data.writeInt(always ? 1 : 0);
-        mRemote.transact(SHOW_BOOT_MESSAGE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void keyguardWaitingForActivityDrawn() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(KEYGUARD_WAITING_FOR_ACTIVITY_DRAWN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void keyguardGoingAway(int flags)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(flags);
-        mRemote.transact(KEYGUARD_GOING_AWAY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public boolean shouldUpRecreateTask(IBinder token, String destAffinity)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeString(destAffinity);
-        mRemote.transact(SHOULD_UP_RECREATE_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return result;
-    }
-
-    public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent resultData)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        target.writeToParcel(data, 0);
-        data.writeInt(resultCode);
-        if (resultData != null) {
-            data.writeInt(1);
-            resultData.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(NAVIGATE_UP_TO_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean result = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return result;
-    }
-
-    public int getLaunchedFromUid(IBinder activityToken) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(activityToken);
-        mRemote.transact(GET_LAUNCHED_FROM_UID_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int result = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return result;
-    }
-
-    public String getLaunchedFromPackage(IBinder activityToken) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(activityToken);
-        mRemote.transact(GET_LAUNCHED_FROM_PACKAGE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        String result = reply.readString();
-        data.recycle();
-        reply.recycle();
-        return result;
-    }
-
-    public void registerUserSwitchObserver(IUserSwitchObserver observer,
-            String name) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(observer != null ? observer.asBinder() : null);
-        data.writeString(name);
-        mRemote.transact(REGISTER_USER_SWITCH_OBSERVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(observer != null ? observer.asBinder() : null);
-        mRemote.transact(UNREGISTER_USER_SWITCH_OBSERVER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void requestBugReport(@ActivityManager.BugreportMode int bugreportType)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(bugreportType);
-        mRemote.transact(REQUEST_BUG_REPORT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(pid);
-        data.writeInt(aboveSystem ? 1 : 0);
-        data.writeString(reason);
-        mRemote.transact(INPUT_DISPATCHING_TIMED_OUT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        long res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public Bundle getAssistContextExtras(int requestType) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(requestType);
-        mRemote.transact(GET_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Bundle res = reply.readBundle();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
-            Bundle receiverExtras,
-            IBinder activityToken, boolean focused, boolean newSessionId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(requestType);
-        data.writeStrongBinder(receiver.asBinder());
-        data.writeBundle(receiverExtras);
-        data.writeStrongBinder(activityToken);
-        data.writeInt(focused ? 1 : 0);
-        data.writeInt(newSessionId ? 1 : 0);
-        mRemote.transact(REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
-            AssistContent content, Uri referrer) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeBundle(extras);
-        structure.writeToParcel(data, 0);
-        content.writeToParcel(data, 0);
-        if (referrer != null) {
-            data.writeInt(1);
-            referrer.writeToParcel(data, 0);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
-            Bundle args) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        intent.writeToParcel(data, 0);
-        data.writeInt(requestType);
-        data.writeString(hint);
-        data.writeInt(userHandle);
-        data.writeBundle(args);
-        mRemote.transact(LAUNCH_ASSIST_INTENT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean isAssistDataAllowedOnCurrentActivity() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean showAssistFromActivity(IBinder token, Bundle args) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeBundle(args);
-        mRemote.transact(SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public void killUid(int appId, int userId, String reason) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(appId);
-        data.writeInt(userId);
-        data.writeString(reason);
-        mRemote.transact(KILL_UID_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void hang(IBinder who, boolean allowRestart) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(who);
-        data.writeInt(allowRestart ? 1 : 0);
-        mRemote.transact(HANG_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void reportActivityFullyDrawn(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void notifyActivityDrawn(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(NOTIFY_ACTIVITY_DRAWN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void restart() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(RESTART_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void performIdleMaintenance() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(PERFORM_IDLE_MAINTENANCE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public void sendIdleJobTrigger() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(SEND_IDLE_JOB_TRIGGER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
-            IActivityContainerCallback callback) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(parentActivityToken);
-        data.writeStrongBinder(callback == null ? null : callback.asBinder());
-        mRemote.transact(CREATE_VIRTUAL_ACTIVITY_CONTAINER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final int result = reply.readInt();
-        final IActivityContainer res;
-        if (result == 1) {
-            res = IActivityContainer.Stub.asInterface(reply.readStrongBinder());
-        } else {
-            res = null;
-        }
-        data.recycle();
-        reply.recycle();
-        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();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(START_BINDER_TRACKING_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        if (fd != null) {
-            data.writeInt(1);
-            fd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
-        } else {
-            data.writeInt(0);
-        }
-        mRemote.transact(STOP_BINDER_TRACKING_AND_DUMP_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean res = reply.readInt() != 0;
-        reply.recycle();
-        data.recycle();
-        return res;
-    }
-
-    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(enabled ? 1 : 0);
-        packageName.writeToParcel(data, 0);
-        mRemote.transact(SET_VR_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    public boolean isVrModePackageEnabled(ComponentName packageName)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        packageName.writeToParcel(data, 0);
-        mRemote.transact(IS_VR_PACKAGE_ENABLED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res == 1;
-    }
-
-    @Override
-    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(displayId);
-        mRemote.transact(CREATE_STACK_ON_DISPLAY, data, reply, 0);
-        reply.readException();
-        final int result = reply.readInt();
-        final IActivityContainer res;
-        if (result == 1) {
-            res = IActivityContainer.Stub.asInterface(reply.readStrongBinder());
-        } else {
-            res = null;
-        }
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    @Override
-    public int getActivityDisplayId(IBinder activityToken)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(activityToken);
-        mRemote.transact(GET_ACTIVITY_DISPLAY_ID_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final int displayId = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return displayId;
-    }
-
-    @Override
-    public void startLockTaskMode(int taskId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        mRemote.transact(START_LOCK_TASK_BY_TASK_ID_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void startLockTaskMode(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(START_LOCK_TASK_BY_TOKEN_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void startSystemLockTaskMode(int taskId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        mRemote.transact(START_SYSTEM_LOCK_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void stopLockTaskMode() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(STOP_LOCK_TASK_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void stopSystemLockTaskMode() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(STOP_SYSTEM_LOCK_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public boolean isInLockTaskMode() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(IS_IN_LOCK_TASK_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean isInLockTaskMode = reply.readInt() == 1;
-        data.recycle();
-        reply.recycle();
-        return isInLockTaskMode;
-    }
-
-    @Override
-    public int getLockTaskModeState() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_LOCK_TASK_MODE_STATE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int lockTaskModeState = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return lockTaskModeState;
-    }
-
-    @Override
-    public void showLockTaskEscapeMessage(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(SHOW_LOCK_TASK_ESCAPE_MESSAGE_TRANSACTION, data, reply,
-                IBinder.FLAG_ONEWAY);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription values)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        values.writeToParcel(data, 0);
-        mRemote.transact(SET_TASK_DESCRIPTION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void setTaskResizeable(int taskId, int resizeableMode) throws  RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        data.writeInt(resizeableMode);
-        mRemote.transact(SET_TASK_RESIZEABLE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void resizeTask(int taskId, Rect r, int resizeMode) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        data.writeInt(resizeMode);
-        r.writeToParcel(data, 0);
-        mRemote.transact(RESIZE_TASK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public Rect getTaskBounds(int taskId) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(taskId);
-        mRemote.transact(GET_TASK_BOUNDS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Rect rect = Rect.CREATOR.createFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return rect;
-    }
-
-    @Override
-    public Bitmap getTaskDescriptionIcon(String filename, int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(filename);
-        data.writeInt(userId);
-        mRemote.transact(GET_TASK_DESCRIPTION_ICON_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final Bitmap icon = reply.readInt() == 0 ? null : Bitmap.CREATOR.createFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return icon;
-    }
-
-    @Override
-    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions options)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        if (options == null) {
-            data.writeInt(0);
-        } else {
-            data.writeInt(1);
-            data.writeBundle(options.toBundle());
-        }
-        mRemote.transact(START_IN_PLACE_ANIMATION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        data.writeInt(visible ? 1 : 0);
-        mRemote.transact(REQUEST_VISIBLE_BEHIND_TRANSACTION, data, reply, 0);
-        reply.readException();
-        boolean success = reply.readInt() > 0;
-        data.recycle();
-        reply.recycle();
-        return success;
-    }
-
-    @Override
-    public boolean isBackgroundVisibleBehind(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(IS_BACKGROUND_VISIBLE_BEHIND_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final boolean visible = reply.readInt() > 0;
-        data.recycle();
-        reply.recycle();
-        return visible;
-    }
-
-    @Override
-    public void backgroundResourcesReleased(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(BACKGROUND_RESOURCES_RELEASED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void notifyLaunchTaskBehindComplete(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void notifyEnterAnimationComplete(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(NOTIFY_ENTER_ANIMATION_COMPLETE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void bootAnimationComplete() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(BOOT_ANIMATION_COMPLETE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void notifyCleartextNetwork(int uid, byte[] firstPacket) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(uid);
-        data.writeByteArray(firstPacket);
-        mRemote.transact(NOTIFY_CLEARTEXT_NETWORK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
-            String reportPackage) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(processName);
-        data.writeInt(uid);
-        data.writeLong(maxMemSize);
-        data.writeString(reportPackage);
-        mRemote.transact(SET_DUMP_HEAP_DEBUG_LIMIT_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void dumpHeapFinished(String path) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(path);
-        mRemote.transact(DUMP_HEAP_FINISHED_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(session.asBinder());
-        data.writeInt(keepAwake ? 1 : 0);
-        mRemote.transact(SET_VOICE_KEEP_AWAKE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void updateLockTaskPackages(int userId, String[] packages) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(userId);
-        data.writeStringArray(packages);
-        mRemote.transact(UPDATE_LOCK_TASK_PACKAGES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void updateDeviceOwner(String packageName) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        mRemote.transact(UPDATE_DEVICE_OWNER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public int getPackageProcessState(String packageName, String callingPackage)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(packageName);
-        data.writeString(callingPackage);
-        mRemote.transact(GET_PACKAGE_PROCESS_STATE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    @Override
-    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeString(process);
-        data.writeInt(userId);
-        data.writeInt(level);
-        mRemote.transact(SET_PROCESS_MEMORY_TRIM_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res != 0;
-    }
-
-    @Override
-    public boolean isRootVoiceInteraction(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(IS_ROOT_VOICE_INTERACTION_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res != 0;
-    }
-
-    @Override
-    public void exitFreeformMode(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(EXIT_FREEFORM_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public int getActivityStackId(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(GET_ACTIVITY_STACK_ID_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int stackId = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return stackId;
-    }
-
-    @Override
-    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
-            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        writeIntArray(horizontalSizeConfiguration, data);
-        writeIntArray(verticalSizeConfigurations, data);
-        writeIntArray(smallestSizeConfigurations, data);
-        mRemote.transact(REPORT_SIZE_CONFIGURATIONS, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    private static void writeIntArray(int[] array, Parcel data) {
-        if (array == null) {
-            data.writeInt(0);
-        } else {
-            data.writeInt(array.length);
-            data.writeIntArray(array);
-        }
-    }
-
-    @Override
-    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(suppress ? 1 : 0);
-        mRemote.transact(SUPPRESS_RESIZE_CONFIG_CHANGES_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(fromStackId);
-        data.writeInt(onTop ? 1 : 0);
-        mRemote.transact(MOVE_TASKS_TO_FULLSCREEN_STACK_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public int getAppStartMode(int uid, String packageName) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(uid);
-        data.writeString(packageName);
-        mRemote.transact(GET_APP_START_MODE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    @Override
-    public boolean isInMultiWindowMode(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(IN_MULTI_WINDOW_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final boolean multiWindowMode = reply.readInt() == 1 ? true : false;
-        data.recycle();
-        reply.recycle();
-        return multiWindowMode;
-    }
-
-    @Override
-    public boolean isInPictureInPictureMode(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(IN_PICTURE_IN_PICTURE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final boolean pipMode = reply.readInt() == 1 ? true : false;
-        data.recycle();
-        reply.recycle();
-        return pipMode;
-    }
-
-    @Override
-    public void enterPictureInPictureMode(IBinder token) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(token);
-        mRemote.transact(ENTER_PICTURE_IN_PICTURE_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public Rect getDefaultPictureInPictureBounds() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_DEFAULT_PICTURE_IN_PICTURE_BOUNDS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Rect rect = Rect.CREATOR.createFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return rect;
-    }
-
-    @Override
-    public Rect getPictureInPictureMovementBounds() throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(GET_PICTURE_IN_PICTURE_MOVEMENT_BOUNDS_TRANSACTION, data, reply, 0);
-        reply.readException();
-        Rect rect = Rect.CREATOR.createFromParcel(reply);
-        data.recycle();
-        reply.recycle();
-        return rect;
-    }
-
-    @Override
-    public boolean isAppForeground(int uid) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(uid);
-        mRemote.transact(IS_APP_FOREGROUND_TRANSACTION, data, reply, 0);
-        final boolean isForeground = reply.readInt() == 1 ? true : false;
-        data.recycle();
-        reply.recycle();
-        return isForeground;
-    };
-
-    @Override
-    public void notifyPinnedStackAnimationEnded() throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        mRemote.transact(NOTIFY_PINNED_STACK_ANIMATION_ENDED_TRANSACTION, data, reply, 0);
-        data.recycle();
-        reply.recycle();
-    };
-
-    @Override
-    public void removeStack(int stackId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(stackId);
-        mRemote.transact(REMOVE_STACK, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void notifyLockedProfile(@UserIdInt int userId) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(userId);
-        mRemote.transact(NOTIFY_LOCKED_PROFILE, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public void startConfirmDeviceCredentialIntent(Intent intent) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        intent.writeToParcel(data, 0);
-        mRemote.transact(START_CONFIRM_DEVICE_CREDENTIAL_INTENT, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-    }
-
-    @Override
-    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
-            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeStrongBinder(target.asBinder());
-        data.writeInt(code);
-        if ((intent!=null)) {
-            data.writeInt(1);
-            intent.writeToParcel(data, 0);
-        }
-        else {
-            data.writeInt(0);
-        }
-        data.writeString(resolvedType);
-        data.writeStrongBinder((((finishedReceiver!=null))?(finishedReceiver.asBinder()):(null)));
-        data.writeString(requiredPermission);
-        if ((options!=null)) {
-            data.writeInt(1);
-            options.writeToParcel(data, 0);
-        }
-        else {
-            data.writeInt(0);
-        }
-        mRemote.transact(SEND_INTENT_SENDER_TRANSACTION, data, reply, 0);
-        reply.readException();
-        final int res = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return res;
-    }
-
-    @Override
-    public void setVrThread(int tid)
-        throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(tid);
-        mRemote.transact(SET_VR_THREAD_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-        return;
-    }
-
-    public void setRenderThread(int tid)
-        throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(tid);
-        mRemote.transact(SET_RENDER_THREAD_TRANSACTION, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-        return;
-    }
-
-    public void setHasTopUi(boolean hasTopUi)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(hasTopUi ? 1 : 0);
-        mRemote.transact(SET_HAS_TOP_UI, data, reply, 0);
-        reply.readException();
-        data.recycle();
-        reply.recycle();
-        return;
-    }
-    @Override
-    public boolean canBypassWorkChallenge(PendingIntent intent)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IActivityManager.descriptor);
-        intent.writeToParcel(data, 0);
-        mRemote.transact(CAN_BYPASS_WORK_CHALLENGE, data, reply, 0);
-        reply.readException();
-        final int result = reply.readInt();
-        data.recycle();
-        reply.recycle();
-        return result != 0;
-    }
-
-    private IBinder mRemote;
-}
+}
\ No newline at end of file
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index fbbfec3..3e8d90b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -421,11 +421,10 @@
         final String[] mNames;
         final IContentProvider mProvider;
         final ContentProvider mLocalProvider;
-        final IActivityManager.ContentProviderHolder mHolder;
+        final ContentProviderHolder mHolder;
 
         ProviderClientRecord(String[] names, IContentProvider provider,
-                ContentProvider localProvider,
-                IActivityManager.ContentProviderHolder holder) {
+                ContentProvider localProvider, ContentProviderHolder holder) {
             mNames = names;
             mProvider = provider;
             mLocalProvider = localProvider;
@@ -978,6 +977,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 +1432,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 +1489,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 +1744,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 +3015,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>();
 
     /**
@@ -3809,7 +3824,7 @@
     }
 
     private static final class ProviderRefCount {
-        public final IActivityManager.ContentProviderHolder holder;
+        public final ContentProviderHolder holder;
         public final ProviderClientRecord client;
         public int stableCount;
         public int unstableCount;
@@ -3821,7 +3836,7 @@
         // here.
         public boolean removePending;
 
-        ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
+        ProviderRefCount(ContentProviderHolder inHolder,
                 ProviderClientRecord inClient, int sCount, int uCount) {
             holder = inHolder;
             client = inClient;
@@ -5464,8 +5479,7 @@
 
     private void installContentProviders(
             Context context, List<ProviderInfo> providers) {
-        final ArrayList<IActivityManager.ContentProviderHolder> results =
-            new ArrayList<IActivityManager.ContentProviderHolder>();
+        final ArrayList<ContentProviderHolder> results = new ArrayList<>();
 
         for (ProviderInfo cpi : providers) {
             if (DEBUG_PROVIDER) {
@@ -5476,7 +5490,7 @@
                 buf.append(cpi.name);
                 Log.i(TAG, buf.toString());
             }
-            IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
+            ContentProviderHolder cph = installProvider(context, null, cpi,
                     false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
             if (cph != null) {
                 cph.noReleaseNeeded = true;
@@ -5505,7 +5519,7 @@
         // Note that we cannot hold the lock while acquiring and installing the
         // provider since it might take a long time to run and it could also potentially
         // be re-entrant in the case where the provider is in the same process.
-        IActivityManager.ContentProviderHolder holder = null;
+        ContentProviderHolder holder = null;
         try {
             holder = ActivityManagerNative.getDefault().getContentProvider(
                     getApplicationThread(), auth, userId, stable);
@@ -5805,7 +5819,7 @@
     }
 
     private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
-            ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
+            ContentProvider localProvider, ContentProviderHolder holder) {
         final String auths[] = holder.info.authority.split(";");
         final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
 
@@ -5838,8 +5852,8 @@
      * and returns the existing provider.  This can happen due to concurrent
      * attempts to acquire the same provider.
      */
-    private IActivityManager.ContentProviderHolder installProvider(Context context,
-            IActivityManager.ContentProviderHolder holder, ProviderInfo info,
+    private ContentProviderHolder installProvider(Context context,
+            ContentProviderHolder holder, ProviderInfo info,
             boolean noisy, boolean noReleaseNeeded, boolean stable) {
         ContentProvider localProvider = null;
         IContentProvider provider;
@@ -5899,7 +5913,7 @@
                     + info.name);
         }
 
-        IActivityManager.ContentProviderHolder retHolder;
+        ContentProviderHolder retHolder;
 
         synchronized (mProviderMap) {
             if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
@@ -5915,7 +5929,7 @@
                     }
                     provider = pr.mProvider;
                 } else {
-                    holder = new IActivityManager.ContentProviderHolder(info);
+                    holder = new ContentProviderHolder(info);
                     holder.provider = provider;
                     holder.noReleaseNeeded = true;
                     pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
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/ActivityView.java b/core/java/android/app/ActivityView.java
index c075ed6..cada1b8 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -448,13 +448,6 @@
             mGuard.open("release");
         }
 
-        void attachToDisplay(int displayId) {
-            try {
-                mIActivityContainer.attachToDisplay(displayId);
-            } catch (RemoteException e) {
-            }
-        }
-
         void setSurface(Surface surface, int width, int height, int density)
                 throws RemoteException {
             mIActivityContainer.setSurface(surface, width, height, density);
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/core/java/android/app/ApplicationErrorReport.aidl
similarity index 71%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to core/java/android/app/ApplicationErrorReport.aidl
index 5f66d16..5b57457 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/core/java/android/app/ApplicationErrorReport.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
+/**
+ * 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
+ *     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,
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.app;
 
-parcelable PublishConfig;
+/** @hide */
+parcelable ApplicationErrorReport.ParcelableCrashInfo;
\ No newline at end of file
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index 9fa8a5d..6cfa362 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -451,6 +451,47 @@
     }
 
     /**
+     * Parcelable version of {@link CrashInfo}
+     *
+     * @hide
+     */
+    public static class ParcelableCrashInfo extends CrashInfo implements Parcelable {
+        /**
+         * Create an uninitialized instance of CrashInfo.
+         */
+        public ParcelableCrashInfo() {
+        }
+
+        /**
+         * Create an instance of CrashInfo initialized from an exception.
+         */
+        public ParcelableCrashInfo(Throwable tr) {
+            super(tr);
+        }
+
+        public ParcelableCrashInfo(Parcel in) {
+            super(in);
+        }
+
+        public int describeContents() {
+            return 0;
+        }
+
+        public static final Parcelable.Creator<ParcelableCrashInfo> CREATOR =
+                new Parcelable.Creator<ParcelableCrashInfo>() {
+                    @Override
+                    public ParcelableCrashInfo createFromParcel(Parcel in) {
+                        return new ParcelableCrashInfo(in);
+                    }
+
+                    @Override
+                    public ParcelableCrashInfo[] newArray(int size) {
+                        return new ParcelableCrashInfo[size];
+                    }
+                };
+    }
+
+    /**
      * Describes an application not responding error.
      */
     public static class AnrInfo {
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/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/core/java/android/app/ContentProviderHolder.aidl
similarity index 89%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to core/java/android/app/ContentProviderHolder.aidl
index 5f66d16..bd56775 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/core/java/android/app/ContentProviderHolder.aidl
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.app;
 
-parcelable PublishConfig;
+/** @hide */
+parcelable ContentProviderHolder;
\ No newline at end of file
diff --git a/core/java/android/app/ContentProviderHolder.java b/core/java/android/app/ContentProviderHolder.java
new file mode 100644
index 0000000..f9998f4
--- /dev/null
+++ b/core/java/android/app/ContentProviderHolder.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.app;
+
+import android.content.ContentProviderNative;
+import android.content.IContentProvider;
+import android.content.pm.ProviderInfo;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information you can retrieve about a particular application.
+ *
+ * @hide
+ */
+public class ContentProviderHolder implements Parcelable {
+    public final ProviderInfo info;
+    public IContentProvider provider;
+    public IBinder connection;
+    public boolean noReleaseNeeded;
+
+    public ContentProviderHolder(ProviderInfo _info) {
+        info = _info;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        info.writeToParcel(dest, 0);
+        if (provider != null) {
+            dest.writeStrongBinder(provider.asBinder());
+        } else {
+            dest.writeStrongBinder(null);
+        }
+        dest.writeStrongBinder(connection);
+        dest.writeInt(noReleaseNeeded ? 1 : 0);
+    }
+
+    public static final Parcelable.Creator<ContentProviderHolder> CREATOR
+            = new Parcelable.Creator<ContentProviderHolder>() {
+        @Override
+        public ContentProviderHolder createFromParcel(Parcel source) {
+            return new ContentProviderHolder(source);
+        }
+
+        @Override
+        public ContentProviderHolder[] newArray(int size) {
+            return new ContentProviderHolder[size];
+        }
+    };
+
+    private ContentProviderHolder(Parcel source) {
+        info = ProviderInfo.CREATOR.createFromParcel(source);
+        provider = ContentProviderNative.asInterface(
+                source.readStrongBinder());
+        connection = source.readStrongBinder();
+        noReleaseNeeded = source.readInt() != 0;
+    }
+}
\ No newline at end of file
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/IActivityContainer.aidl b/core/java/android/app/IActivityContainer.aidl
index 170aff3..1ff3c87 100644
--- a/core/java/android/app/IActivityContainer.aidl
+++ b/core/java/android/app/IActivityContainer.aidl
@@ -25,7 +25,7 @@
 
 /** @hide */
 interface IActivityContainer {
-    void attachToDisplay(int displayId);
+    void addToDisplay(int displayId);
     void setSurface(in Surface surface, int width, int height, int density);
     int startActivity(in Intent intent);
     int startActivityIntentSender(in IIntentSender intentSender);
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
new file mode 100644
index 0000000..92d67b7
--- /dev/null
+++ b/core/java/android/app/IActivityManager.aidl
@@ -0,0 +1,567 @@
+/*
+ * 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.app.ActivityManager;
+import android.app.ApplicationErrorReport;
+import android.app.ContentProviderHolder;
+import android.app.IApplicationThread;
+import android.app.IActivityContainer;
+import android.app.IActivityContainerCallback;
+import android.app.IActivityController;
+import android.app.IAppTask;
+import android.app.IInstrumentationWatcher;
+import android.app.IProcessObserver;
+import android.app.IServiceConnection;
+import android.app.IStopUserCallback;
+import android.app.ITaskStackListener;
+import android.app.IUiAutomationConnection;
+import android.app.IUidObserver;
+import android.app.IUserSwitchObserver;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.app.ProfilerInfo;
+import android.app.WaitResult;
+import android.app.assist.AssistContent;
+import android.app.assist.AssistStructure;
+import android.content.ComponentName;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ConfigurationInfo;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.ProviderInfo;
+import android.content.pm.UserInfo;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.IBinder;
+import android.os.IProgressListener;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
+import android.os.StrictMode;
+import android.service.voice.IVoiceInteractionSession;
+import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.os.IResultReceiver;
+
+import java.util.List;
+
+/**
+ * System private API for talking with the activity manager service.  This
+ * provides calls from the application back to the activity manager.
+ *
+ * {@hide}
+ */
+interface IActivityManager {
+    // Please keep these transaction codes the same -- they are also
+    // sent by C++ code. when a new method is added, use the next available transaction id.
+
+    // Special low-level communication with activity manager.
+    void handleApplicationCrash(in IBinder app,
+            in ApplicationErrorReport.ParcelableCrashInfo crashInfo) = 1;
+    int startActivity(in IApplicationThread caller, in String callingPackage, in Intent intent,
+            in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode,
+            int flags, in ProfilerInfo profilerInfo, in Bundle options) = 2;
+    void unhandledBack() = 3;
+    ParcelFileDescriptor openContentUri(in String uriString) = 4;
+
+    boolean finishActivity(in IBinder token, int code, in Intent data, int finishTask) = 10;
+    Intent registerReceiver(in IApplicationThread caller, in String callerPackage,
+            in IIntentReceiver receiver, in IntentFilter filter,
+            in String requiredPermission, int userId) = 11;
+    void unregisterReceiver(in IIntentReceiver receiver) = 12;
+    int broadcastIntent(in IApplicationThread caller, in Intent intent,
+            in String resolvedType, in IIntentReceiver resultTo, int resultCode,
+            in String resultData, in Bundle map, in String[] requiredPermissions,
+            int appOp, in Bundle options, boolean serialized, boolean sticky, int userId) = 13;
+    void unbroadcastIntent(in IApplicationThread caller, in Intent intent, int userId) = 14;
+    oneway void finishReceiver(in IBinder who, int resultCode, in String resultData, in Bundle map,
+            boolean abortBroadcast, int flags) = 15;
+    void attachApplication(in IApplicationThread app) = 16;
+    oneway void activityIdle(in IBinder token, in Configuration config,
+            in boolean stopProfiling) = 17;
+    void activityPaused(in IBinder token) = 18;
+    oneway void activityStopped(in IBinder token, in Bundle state,
+            in PersistableBundle persistentState, in CharSequence description) = 19;
+    String getCallingPackage(in IBinder token) = 20;
+    ComponentName getCallingActivity(in IBinder token) = 21;
+    List<ActivityManager.RunningTaskInfo> getTasks(int maxNum, int flags) = 22;
+    void moveTaskToFront(int task, int flags, in Bundle options) = 23;
+    void moveTaskBackwards(int task) = 25;
+    int getTaskForActivity(in IBinder token, in boolean onlyRoot) = 26;
+    ContentProviderHolder getContentProvider(in IApplicationThread caller,
+            in String name, int userId, boolean stable) = 28;
+    void publishContentProviders(in IApplicationThread caller,
+            in List<ContentProviderHolder> providers) = 29;
+    boolean refContentProvider(in IBinder connection, int stableDelta, int unstableDelta) = 30;
+    void finishSubActivity(in IBinder token, in String resultWho, int requestCode) = 31;
+    PendingIntent getRunningServiceControlPanel(in ComponentName service) = 32;
+    ComponentName startService(in IApplicationThread caller, in Intent service,
+            in String resolvedType, in String callingPackage, int userId) = 33;
+    int stopService(in IApplicationThread caller, in Intent service,
+            in String resolvedType, int userId) = 34;
+    int bindService(in IApplicationThread caller, in IBinder token, in Intent service,
+            in String resolvedType, in IServiceConnection connection, int flags,
+            in String callingPackage, int userId) = 35;
+    boolean unbindService(in IServiceConnection connection) = 36;
+    void publishService(in IBinder token, in Intent intent, in IBinder service) = 37;
+    void activityResumed(in IBinder token) = 38;
+    void setDebugApp(in String packageName, boolean waitForDebugger, boolean persistent) = 41;
+    void setAlwaysFinish(boolean enabled) = 42;
+    boolean startInstrumentation(in ComponentName className, in String profileFile,
+            int flags, in Bundle arguments, in IInstrumentationWatcher watcher,
+            in IUiAutomationConnection connection, int userId,
+            in String abiOverride) = 43;
+    void finishInstrumentation(in IApplicationThread target, int resultCode,
+            in Bundle results) = 44;
+    /**
+     * @return A copy of global {@link Configuration}, contains general settings for the entire
+     *         system. Corresponds to the configuration of the default display.
+     * @throws RemoteException
+     */
+    Configuration getConfiguration() = 45;
+    /**
+     * Updates global configuration and applies changes to the entire system.
+     * @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.
+     */
+    boolean updateConfiguration(in Configuration values) = 46;
+    boolean stopServiceToken(in ComponentName className, in IBinder token, int startId) = 47;
+    ComponentName getActivityClassForToken(in IBinder token) = 48;
+    String getPackageForToken(in IBinder token) = 49;
+    void setProcessLimit(int max) = 50;
+    int getProcessLimit() = 51;
+    int checkPermission(in String permission, int pid, int uid) = 52;
+    int checkUriPermission(in Uri uri, int pid, int uid, int mode, int userId,
+            in IBinder callerToken) = 53;
+    void grantUriPermission(in IApplicationThread caller, in String targetPkg, in Uri uri,
+            int mode, int userId) = 54;
+    void revokeUriPermission(in IApplicationThread caller, in Uri uri, int mode, int userId) = 55;
+    void setActivityController(in IActivityController watcher, boolean imAMonkey) = 56;
+    void showWaitingForDebugger(in IApplicationThread who, boolean waiting) = 57;
+    /*
+     * This will deliver the specified signal to all the persistent processes. Currently only
+     * SIGUSR1 is delivered. All others are ignored.
+     */
+    void signalPersistentProcesses(int signal) = 58;
+    ParceledListSlice getRecentTasks(int maxNum,
+            int flags, int userId) = 59;
+    oneway void serviceDoneExecuting(in IBinder token, int type, int startId, int res) = 60;
+    oneway void activityDestroyed(in IBinder token) = 61;
+    IIntentSender getIntentSender(int type, in String packageName, in IBinder token,
+            in String resultWho, int requestCode, in Intent[] intents, in String[] resolvedTypes,
+            int flags, in Bundle options, int userId) = 62;
+    void cancelIntentSender(in IIntentSender sender) = 63;
+    String getPackageForIntentSender(in IIntentSender sender) = 64;
+    void enterSafeMode() = 65;
+    boolean startNextMatchingActivity(in IBinder callingActivity,
+            in Intent intent, in Bundle options) = 66;
+    void noteWakeupAlarm(in IIntentSender sender, int sourceUid,
+            in String sourcePkg, in String tag) = 67;
+    void removeContentProvider(in IBinder connection, boolean stable) = 68;
+    void setRequestedOrientation(in IBinder token, int requestedOrientation) = 69;
+    int getRequestedOrientation(in IBinder token) = 70;
+    void unbindFinished(in IBinder token, in Intent service, boolean doRebind) = 71;
+    void setProcessForeground(in IBinder token, int pid, boolean isForeground) = 72;
+    void setServiceForeground(in ComponentName className, in IBinder token,
+            int id, in Notification notification, int flags) = 73;
+    boolean moveActivityTaskToBack(in IBinder token, boolean nonRoot) = 74;
+    void getMemoryInfo(out ActivityManager.MemoryInfo outInfo) = 75;
+    List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() = 76;
+    boolean clearApplicationUserData(in String packageName,
+            in IPackageDataObserver observer, int userId) = 77;
+    void forceStopPackage(in String packageName, int userId) = 78;
+    boolean killPids(in int[] pids, in String reason, boolean secure) = 79;
+    List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags) = 80;
+    ActivityManager.TaskThumbnail getTaskThumbnail(int taskId) = 81;
+    // Retrieve running application processes in the system
+    List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() = 82;
+    // Get device configuration
+    ConfigurationInfo getDeviceConfigurationInfo() = 83;
+    IBinder peekService(in Intent service, in String resolvedType, in String callingPackage) = 84;
+    // Turn on/off profiling in a particular process.
+    boolean profileControl(in String process, int userId, boolean start,
+            in ProfilerInfo profilerInfo, int profileType) = 85;
+    boolean shutdown(int timeout) = 86;
+    void stopAppSwitches() = 87;
+    void resumeAppSwitches() = 88;
+    boolean bindBackupAgent(in String packageName, int backupRestoreMode, int userId) = 89;
+    void backupAgentCreated(in String packageName, in IBinder agent) = 90;
+    void unbindBackupAgent(in ApplicationInfo appInfo) = 91;
+    int getUidForIntentSender(in IIntentSender sender) = 92;
+    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
+            boolean requireFull, in String name, in String callerPackage) = 93;
+    void addPackageDependency(in String packageName) = 94;
+    void killApplication(in String pkg, int appId, int userId, in String reason) = 95;
+    void closeSystemDialogs(in String reason) = 96;
+    Debug.MemoryInfo[] getProcessMemoryInfo(in int[] pids) = 97;
+    void killApplicationProcess(in String processName, int uid) = 98;
+    int startActivityIntentSender(in IApplicationThread caller,
+            in IntentSender intent, in Intent fillInIntent, in String resolvedType,
+            in IBinder resultTo, in String resultWho, int requestCode,
+            int flagsMask, int flagsValues, in Bundle options) = 99;
+    void overridePendingTransition(in IBinder token, in String packageName,
+            int enterAnim, int exitAnim) = 100;
+    // Special low-level communication with activity manager.
+    boolean handleApplicationWtf(in IBinder app, in String tag, boolean system,
+            in ApplicationErrorReport.ParcelableCrashInfo crashInfo) = 101;
+    void killBackgroundProcesses(in String packageName, int userId) = 102;
+    boolean isUserAMonkey() = 103;
+    WaitResult startActivityAndWait(in IApplicationThread caller, in String callingPackage,
+            in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
+            int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options,
+            int userId) = 104;
+    boolean willActivityBeVisible(in IBinder token) = 105;
+    int startActivityWithConfig(in IApplicationThread caller, in String callingPackage,
+            in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
+            int requestCode, int startFlags, in Configuration newConfig,
+            in Bundle options, int userId) = 106;
+    // Retrieve info of applications installed on external media that are currently
+    // running.
+    List<ApplicationInfo> getRunningExternalApplications() = 107;
+    void finishHeavyWeightApp() = 108;
+    // A StrictMode violation to be handled.  The violationMask is a
+    // subset of the original StrictMode policy bitmask, with only the
+    // bit violated and penalty bits to be executed by the
+    // ActivityManagerService remaining set.
+    void handleApplicationStrictModeViolation(in IBinder app, int violationMask,
+            in StrictMode.ViolationInfo crashInfo) = 109;
+    boolean isImmersive(in IBinder token) = 110;
+    void setImmersive(in IBinder token, boolean immersive) = 111;
+    boolean isTopActivityImmersive() = 112;
+    void crashApplication(int uid, int initialPid, in String packageName, in String message) = 113;
+    String getProviderMimeType(in Uri uri, int userId) = 114;
+    IBinder newUriPermissionOwner(in String name) = 115;
+    void grantUriPermissionFromOwner(in IBinder owner, int fromUid, in String targetPkg,
+            in Uri uri, int mode, int sourceUserId, int targetUserId) = 116;
+    void revokeUriPermissionFromOwner(in IBinder owner, in Uri uri, int mode, int userId) = 117;
+    int checkGrantUriPermission(int callingUid, in String targetPkg, in Uri uri,
+            int modeFlags, int userId) = 118;
+    // Cause the specified process to dump the specified heap.
+    boolean dumpHeap(in String process, int userId, boolean managed, in String path,
+            in ParcelFileDescriptor fd) = 119;
+    int startActivities(in IApplicationThread caller, in String callingPackage,
+            in Intent[] intents, in String[] resolvedTypes, in IBinder resultTo,
+            in Bundle options, int userId) = 120;
+    boolean isUserRunning(int userid, int flags) = 121;
+    oneway void activitySlept(in IBinder token) = 122;
+    int getFrontActivityScreenCompatMode() = 123;
+    void setFrontActivityScreenCompatMode(int mode) = 124;
+    int getPackageScreenCompatMode(in String packageName) = 125;
+    void setPackageScreenCompatMode(in String packageName, int mode) = 126;
+    boolean getPackageAskScreenCompat(in String packageName) = 127;
+    void setPackageAskScreenCompat(in String packageName, boolean ask) = 128;
+    boolean switchUser(int userid) = 129;
+    void setFocusedTask(int taskId) = 130;
+    boolean removeTask(int taskId) = 131;
+    void registerProcessObserver(in IProcessObserver observer) = 132;
+    void unregisterProcessObserver(in IProcessObserver observer) = 133;
+    boolean isIntentSenderTargetedToPackage(in IIntentSender sender) = 134;
+    void updatePersistentConfiguration(in Configuration values) = 135;
+    long[] getProcessPss(in int[] pids) = 136;
+    void showBootMessage(in CharSequence msg, boolean always) = 137;
+    void killAllBackgroundProcesses() = 139;
+    ContentProviderHolder getContentProviderExternal(in String name, int userId,
+            in IBinder token) = 140;
+    void removeContentProviderExternal(in String name, in IBinder token) = 141;
+    // Get memory information about the calling process.
+    void getMyMemoryState(out ActivityManager.RunningAppProcessInfo outInfo) = 142;
+    boolean killProcessesBelowForeground(in String reason) = 143;
+    UserInfo getCurrentUser() = 144;
+    boolean shouldUpRecreateTask(in IBinder token, in String destAffinity) = 145;
+    boolean navigateUpTo(in IBinder token, in Intent target, int resultCode,
+            in Intent resultData) = 146;
+    void setLockScreenShown(boolean showing) = 147;
+    boolean finishActivityAffinity(in IBinder token) = 148;
+    // This is not public because you need to be very careful in how you
+    // manage your activity to make sure it is always the uid you expect.
+    int getLaunchedFromUid(in IBinder activityToken) = 149;
+    void unstableProviderDied(in IBinder connection) = 150;
+    boolean isIntentSenderAnActivity(in IIntentSender sender) = 151;
+    int startActivityAsUser(in IApplicationThread caller, in String callingPackage,
+            in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
+            int requestCode, int flags, in ProfilerInfo profilerInfo,
+            in Bundle options, int userId) = 152;
+    int stopUser(int userid, boolean force, in IStopUserCallback callback) = 153;
+    void registerUserSwitchObserver(in IUserSwitchObserver observer, in String name) = 154;
+    void unregisterUserSwitchObserver(in IUserSwitchObserver observer) = 155;
+    int[] getRunningUserIds() = 156;
+    void requestBugReport(int bugreportType) = 157;
+    long inputDispatchingTimedOut(int pid, boolean aboveSystem, in String reason) = 158;
+    void clearPendingBackup() = 159;
+    Intent getIntentForIntentSender(in IIntentSender sender) = 160;
+    Bundle getAssistContextExtras(int requestType) = 161;
+    void reportAssistContextExtras(in IBinder token, in Bundle extras,
+            in AssistStructure structure, in AssistContent content, in Uri referrer) = 162;
+    // This is not public because you need to be very careful in how you
+    // manage your activity to make sure it is always the uid you expect.
+    String getLaunchedFromPackage(in IBinder activityToken) = 163;
+    void killUid(int appId, int userId, in String reason) = 164;
+    void setUserIsMonkey(boolean monkey) = 165;
+    void hang(in IBinder who, boolean allowRestart) = 166;
+    IActivityContainer createVirtualActivityContainer(in IBinder parentActivityToken,
+            in IActivityContainerCallback callback) = 167;
+    void moveTaskToStack(int taskId, int stackId, boolean toTop) = 168;
+    /**
+     * Resizes the input stack id to the given bounds.
+     *
+     * @param stackId Id of the stack to resize.
+     * @param bounds Bounds to resize the stack to or {@code null} for fullscreen.
+     * @param allowResizeInDockedMode True if the resize should be allowed when the docked stack is
+     *                                active.
+     * @param preserveWindows True if the windows of activities contained in the stack should be
+     *                        preserved.
+     * @param animate True if the stack resize should be animated.
+     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
+     *                          default animation duration should be used.
+     * @throws RemoteException
+     */
+    void resizeStack(int stackId, in Rect bounds, boolean allowResizeInDockedMode,
+            boolean preserveWindows, boolean animate, int animationDuration) = 169;
+    List<ActivityManager.StackInfo> getAllStackInfos() = 170;
+    void setFocusedStack(int stackId) = 171;
+    ActivityManager.StackInfo getStackInfo(int stackId) = 172;
+    boolean convertFromTranslucent(in IBinder token) = 173;
+    boolean convertToTranslucent(in IBinder token, in Bundle options) = 174;
+    void notifyActivityDrawn(in IBinder token) = 175;
+    void reportActivityFullyDrawn(in IBinder token) = 176;
+    void restart() = 177;
+    void performIdleMaintenance() = 178;
+    void takePersistableUriPermission(in Uri uri, int modeFlags, int userId) = 179;
+    void releasePersistableUriPermission(in Uri uri, int modeFlags, int userId) = 180;
+    ParceledListSlice getPersistedUriPermissions(in String packageName, boolean incoming) = 181;
+    void appNotRespondingViaProvider(in IBinder connection) = 182;
+    Rect getTaskBounds(int taskId) = 183;
+    int getActivityDisplayId(in IBinder activityToken) = 184;
+    boolean setProcessMemoryTrimLevel(in String process, int uid, int level) = 186;
+
+
+    // Start of L transactions
+    String getTagForIntentSender(in IIntentSender sender, in String prefix) = 210;
+    boolean startUserInBackground(int userid) = 211;
+    boolean isInHomeStack(int taskId) = 212;
+    void startLockTaskModeById(int taskId) = 213;
+    void startLockTaskModeByToken(in IBinder token) = 214;
+    void stopLockTaskMode() = 215;
+    boolean isInLockTaskMode() = 216;
+    void setTaskDescription(in IBinder token, in ActivityManager.TaskDescription values) = 217;
+    int startVoiceActivity(in String callingPackage, int callingPid, int callingUid,
+            in Intent intent, in String resolvedType, in IVoiceInteractionSession session,
+            in IVoiceInteractor interactor, int flags, in ProfilerInfo profilerInfo,
+            in Bundle options, int userId) = 218;
+    Bundle getActivityOptions(in IBinder token) = 219;
+    List<IBinder> getAppTasks(in String callingPackage) = 220;
+    void startSystemLockTaskMode(int taskId) = 221;
+    void stopSystemLockTaskMode() = 222;
+    void finishVoiceTask(in IVoiceInteractionSession session) = 223;
+    boolean isTopOfTask(in IBinder token) = 224;
+    boolean requestVisibleBehind(in IBinder token, boolean visible) = 225;
+    boolean isBackgroundVisibleBehind(in IBinder token) = 226;
+    void backgroundResourcesReleased(in IBinder token) = 227;
+    void notifyLaunchTaskBehindComplete(in IBinder token) = 228;
+    int startActivityFromRecents(int taskId, in Bundle options) = 229;
+    void notifyEnterAnimationComplete(in IBinder token) = 230;
+    int startActivityAsCaller(in IApplicationThread caller, in String callingPackage,
+            in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
+            int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options,
+            boolean ignoreTargetSecurity, int userId) = 232;
+    int addAppTask(in IBinder activityToken, in Intent intent,
+            in ActivityManager.TaskDescription description, in Bitmap thumbnail) = 233;
+    Point getAppTaskThumbnailSize() = 234;
+    boolean releaseActivityInstance(in IBinder token) = 235;
+    void releaseSomeActivities(in IApplicationThread app) = 236;
+    void bootAnimationComplete() = 237;
+    Bitmap getTaskDescriptionIcon(in String filename, int userId) = 238;
+    boolean launchAssistIntent(in Intent intent, int requestType, in String hint, int userHandle,
+            in Bundle args) = 239;
+    void startInPlaceAnimationOnFrontMostApplication(in Bundle opts) = 240;
+    int checkPermissionWithToken(in String permission, int pid, int uid,
+            in IBinder callerToken) = 241;
+    void registerTaskStackListener(in ITaskStackListener listener) = 242;
+
+
+    // Start of M transactions
+    void notifyCleartextNetwork(int uid, in byte[] firstPacket) = 280;
+    IActivityContainer createStackOnDisplay(int displayId) = 281;
+    int getFocusedStackId() = 282;
+    void setTaskResizeable(int taskId, int resizeableMode) = 283;
+    boolean requestAssistContextExtras(int requestType, in IResultReceiver receiver,
+            in Bundle receiverExtras, in IBinder activityToken,
+            boolean focused, boolean newSessionId) = 284;
+    void resizeTask(int taskId, in Rect bounds, int resizeMode) = 285;
+    int getLockTaskModeState() = 286;
+    void setDumpHeapDebugLimit(in String processName, int uid, long maxMemSize,
+            in String reportPackage) = 287;
+    void dumpHeapFinished(in String path) = 288;
+    void setVoiceKeepAwake(in IVoiceInteractionSession session, boolean keepAwake) = 289;
+    void updateLockTaskPackages(int userId, in String[] packages) = 290;
+    void noteAlarmStart(in IIntentSender sender, int sourceUid, in String tag) = 291;
+    void noteAlarmFinish(in IIntentSender sender, int sourceUid, in String tag) = 292;
+    int getPackageProcessState(in String packageName, in String callingPackage) = 293;
+    oneway void showLockTaskEscapeMessage(in IBinder token) = 294;
+    void updateDeviceOwner(in String packageName) = 295;
+    /**
+     * Notify the system that the keyguard is going away.
+     *
+     * @param flags See {@link android.view.WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
+     *              etc.
+     */
+    void keyguardGoingAway(int flags) = 296;
+    void registerUidObserver(in IUidObserver observer, int which, String callingPackage) = 297;
+    void unregisterUidObserver(in IUidObserver observer) = 298;
+    boolean isAssistDataAllowedOnCurrentActivity() = 299;
+    boolean showAssistFromActivity(in IBinder token, in Bundle args) = 300;
+    boolean isRootVoiceInteraction(in IBinder token) = 301;
+
+
+    // Start of N transactions
+    // Start Binder transaction tracking for all applications.
+    boolean startBinderTracking() = 340;
+    // Stop Binder transaction tracking for all applications and dump trace data to the given file
+    // descriptor.
+    boolean stopBinderTrackingAndDump(in ParcelFileDescriptor fd) = 341;
+    void positionTaskInStack(int taskId, int stackId, int position) = 342;
+    int getActivityStackId(in IBinder token) = 343;
+    void exitFreeformMode(in IBinder token) = 344;
+    void reportSizeConfigurations(in IBinder token, in int[] horizontalSizeConfiguration,
+            in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations) = 345;
+    boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
+            in Rect initialBounds, boolean moveHomeStackFront) = 346;
+    void suppressResizeConfigChanges(boolean suppress) = 347;
+    void moveTasksToFullscreenStack(int fromStackId, boolean onTop) = 348;
+    boolean moveTopActivityToPinnedStack(int stackId, in Rect bounds) = 349;
+    int getAppStartMode(int uid, in String packageName) = 350;
+    boolean unlockUser(int userid, in byte[] token, in byte[] secret,
+            in IProgressListener listener) = 351;
+    boolean isInMultiWindowMode(in IBinder token) = 352;
+    boolean isInPictureInPictureMode(in IBinder token) = 353;
+    void killPackageDependents(in String packageName, int userId) = 354;
+    void enterPictureInPictureMode(in IBinder token) = 355;
+    void activityRelaunched(in IBinder token) = 356;
+    IBinder getUriPermissionOwnerForActivity(in IBinder activityToken) = 357;
+    /**
+     * Resizes the docked stack, and all other stacks as the result of the dock stack bounds change.
+     *
+     * @param dockedBounds The bounds for the docked stack.
+     * @param tempDockedTaskBounds The temporary bounds for the tasks in the docked stack, which
+     *                             might be different from the stack bounds to allow more
+     *                             flexibility while resizing, or {@code null} if they should be the
+     *                             same as the stack bounds.
+     * @param tempDockedTaskInsetBounds The temporary bounds for the tasks to calculate the insets.
+     *                                  When resizing, we usually "freeze" the layout of a task. To
+     *                                  achieve that, we also need to "freeze" the insets, which
+     *                                  gets achieved by changing task bounds but not bounds used
+     *                                  to calculate the insets in this transient state
+     * @param tempOtherTaskBounds The temporary bounds for the tasks in all other stacks, or
+     *                            {@code null} if they should be the same as the stack bounds.
+     * @param tempOtherTaskInsetBounds Like {@code tempDockedTaskInsetBounds}, but for the other
+     *                                 stacks.
+     * @throws RemoteException
+     */
+    void resizeDockedStack(in Rect dockedBounds, in Rect tempDockedTaskBounds,
+            in Rect tempDockedTaskInsetBounds,
+            in Rect tempOtherTaskBounds, in Rect tempOtherTaskInsetBounds) = 358;
+    int setVrMode(in IBinder token, boolean enabled, in ComponentName packageName) = 359;
+    // Gets the URI permissions granted to an arbitrary package.
+    // NOTE: this is different from getPersistedUriPermissions(), which returns the URIs the package
+    // granted to another packages (instead of those granted to it).
+    ParceledListSlice getGrantedUriPermissions(in String packageName, int userId) = 360;
+    // Clears the URI permissions granted to an arbitrary package.
+    void clearGrantedUriPermissions(in String packageName, int userId) = 361;
+    boolean isAppForeground(int uid) = 362;
+    void startLocalVoiceInteraction(in IBinder token, in Bundle options) = 363;
+    void stopLocalVoiceInteraction(in IBinder token) = 364;
+    boolean supportsLocalVoiceInteraction() = 365;
+    void notifyPinnedStackAnimationEnded() = 366;
+    void removeStack(int stackId) = 367;
+    void setLenientBackgroundCheck(boolean enabled) = 368;
+    int getMemoryTrimLevel() = 369;
+    /**
+     * Resizes the pinned stack.
+     *
+     * @param pinnedBounds The bounds for the pinned stack.
+     * @param tempPinnedTaskBounds The temporary bounds for the tasks in the pinned stack, which
+     *                             might be different from the stack bounds to allow more
+     *                             flexibility while resizing, or {@code null} if they should be the
+     *                             same as the stack bounds.
+     */
+    void resizePinnedStack(in Rect pinnedBounds, in Rect tempPinnedTaskBounds) = 370;
+    boolean isVrModePackageEnabled(in ComponentName packageName) = 371;
+    /**
+     * Moves all tasks from the docked stack in the fullscreen stack and puts the top task of the
+     * fullscreen stack into the docked stack.
+     */
+    void swapDockedAndFullscreenStack() = 372;
+    void notifyLockedProfile(int userId) = 373;
+    void startConfirmDeviceCredentialIntent(in Intent intent) = 374;
+    void sendIdleJobTrigger() = 375;
+    int sendIntentSender(in IIntentSender target, int code, in Intent intent,
+            in String resolvedType, in IIntentReceiver finishedReceiver,
+            in String requiredPermission, in Bundle options) = 376;
+
+
+    // Start of N MR1 transactions
+    void setVrThread(int tid) = 377;
+    void setRenderThread(int tid) = 378;
+    /**
+     * Lets activity manager know whether the calling process is currently showing "top-level" UI
+     * that is not an activity, i.e. windows on the screen the user is currently interacting with.
+     *
+     * <p>This flag can only be set for persistent processes.
+     *
+     * @param hasTopUi Whether the calling process has "top-level" UI.
+     */
+    void setHasTopUi(boolean hasTopUi) = 379;
+    /**
+     * Returns if the target of the PendingIntent can be fired directly, without triggering
+     * a work profile challenge. This can happen if the PendingIntent is to start direct-boot
+     * aware activities, and the target user is in RUNNING_LOCKED state, i.e. we should allow
+     * direct-boot aware activity to bypass work challenge when the user hasn't unlocked yet.
+     * @param intent the {@link  PendingIntent} to be tested.
+     * @return {@code true} if the intent should not trigger a work challenge, {@code false}
+     *     otherwise.
+     * @throws RemoteException
+     */
+    boolean canBypassWorkChallenge(in PendingIntent intent) = 380;
+
+    // Start of O transactions
+    void requestActivityRelaunch(in IBinder token) = 400;
+    /**
+     * 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.
+     */
+    boolean updateDisplayOverrideConfiguration(in Configuration values, int displayId) = 401;
+    void unregisterTaskStackListener(ITaskStackListener listener) = 402;
+    void moveStackToDisplay(int stackId, int displayId) = 403;
+
+    // Please keep these transaction codes the same -- they are also
+    // sent by C++ code. when a new method is added, use the next available transaction id.
+}
\ No newline at end of file
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
deleted file mode 100644
index 1253e69..0000000
--- a/core/java/android/app/IActivityManager.java
+++ /dev/null
@@ -1,1106 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.app;
-
-import android.annotation.UserIdInt;
-import android.app.ActivityManager.RunningServiceInfo;
-import android.app.ActivityManager.RunningTaskInfo;
-import android.app.ActivityManager.StackInfo;
-import android.app.assist.AssistContent;
-import android.app.assist.AssistStructure;
-import android.content.ComponentName;
-import android.content.ContentProviderNative;
-import android.content.IContentProvider;
-import android.content.IIntentReceiver;
-import android.content.IIntentSender;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.UriPermission;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.ConfigurationInfo;
-import android.content.pm.IPackageDataObserver;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ParceledListSlice;
-import android.content.pm.ProviderInfo;
-import android.content.pm.UserInfo;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Debug;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.IProgressListener;
-import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
-import android.os.PersistableBundle;
-import android.os.RemoteException;
-import android.os.StrictMode;
-import android.service.voice.IVoiceInteractionSession;
-import com.android.internal.app.IVoiceInteractor;
-import com.android.internal.os.IResultReceiver;
-
-import java.util.List;
-
-/**
- * System private API for talking with the activity manager service.  This
- * provides calls from the application back to the activity manager.
- *
- * {@hide}
- */
-public interface IActivityManager extends IInterface {
-    public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
-            String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags,
-            ProfilerInfo profilerInfo, Bundle options) throws RemoteException;
-    public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent,
-            String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags,
-            ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException;
-    public int startActivityAsCaller(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
-            int flags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
-            int userId) throws RemoteException;
-    public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
-            int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options,
-            int userId) throws RemoteException;
-    public int startActivityWithConfig(IApplicationThread caller, String callingPackage,
-            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
-            int requestCode, int startFlags, Configuration newConfig,
-            Bundle options, int userId) throws RemoteException;
-    public int startActivityIntentSender(IApplicationThread caller,
-            IntentSender intent, Intent fillInIntent, String resolvedType,
-            IBinder resultTo, String resultWho, int requestCode,
-            int flagsMask, int flagsValues, Bundle options) throws RemoteException;
-    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
-            Intent intent, String resolvedType, IVoiceInteractionSession session,
-            IVoiceInteractor interactor, int flags, ProfilerInfo profilerInfo, Bundle options,
-            int userId) throws RemoteException;
-    public boolean startNextMatchingActivity(IBinder callingActivity,
-            Intent intent, Bundle options) throws RemoteException;
-    public int startActivityFromRecents(int taskId, Bundle options)
-            throws RemoteException;
-    public boolean finishActivity(IBinder token, int code, Intent data, int finishTask)
-            throws RemoteException;
-    public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException;
-    public boolean finishActivityAffinity(IBinder token) throws RemoteException;
-    public void finishVoiceTask(IVoiceInteractionSession session) throws RemoteException;
-    public void requestActivityRelaunch(IBinder token) throws RemoteException;
-    public boolean releaseActivityInstance(IBinder token) throws RemoteException;
-    public void releaseSomeActivities(IApplicationThread app) throws RemoteException;
-    public boolean willActivityBeVisible(IBinder token) throws RemoteException;
-    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
-            IIntentReceiver receiver, IntentFilter filter,
-            String requiredPermission, int userId) throws RemoteException;
-    public void unregisterReceiver(IIntentReceiver receiver) throws RemoteException;
-    public int broadcastIntent(IApplicationThread caller, Intent intent,
-            String resolvedType, IIntentReceiver resultTo, int resultCode,
-            String resultData, Bundle map, String[] requiredPermissions,
-            int appOp, Bundle options, boolean serialized, boolean sticky, int userId) throws RemoteException;
-    public void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) throws RemoteException;
-    public void finishReceiver(IBinder who, int resultCode, String resultData, Bundle map,
-            boolean abortBroadcast, int flags) throws RemoteException;
-    public void attachApplication(IApplicationThread app) throws RemoteException;
-    public void activityResumed(IBinder token) throws RemoteException;
-    public void activityIdle(IBinder token, Configuration config,
-            boolean stopProfiling) throws RemoteException;
-    public void activityPaused(IBinder token) throws RemoteException;
-    public void activityStopped(IBinder token, Bundle state,
-            PersistableBundle persistentState, CharSequence description) throws RemoteException;
-    public void activitySlept(IBinder token) throws RemoteException;
-    public void activityDestroyed(IBinder token) throws RemoteException;
-    public void activityRelaunched(IBinder token) throws RemoteException;
-    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
-            int[] verticalSizeConfigurations, int[] smallestWidthConfigurations)
-            throws RemoteException;
-    public String getCallingPackage(IBinder token) throws RemoteException;
-    public ComponentName getCallingActivity(IBinder token) throws RemoteException;
-    public List<IAppTask> getAppTasks(String callingPackage) throws RemoteException;
-    public int addAppTask(IBinder activityToken, Intent intent,
-            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException;
-    public Point getAppTaskThumbnailSize() throws RemoteException;
-    public List<RunningTaskInfo> getTasks(int maxNum, int flags) throws RemoteException;
-    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
-            int flags, int userId) throws RemoteException;
-    public ActivityManager.TaskThumbnail getTaskThumbnail(int taskId) throws RemoteException;
-    public List<RunningServiceInfo> getServices(int maxNum, int flags) throws RemoteException;
-    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState()
-            throws RemoteException;
-    public void moveTaskToFront(int task, int flags, Bundle options) throws RemoteException;
-    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) throws RemoteException;
-    public void moveTaskBackwards(int task) throws RemoteException;
-    public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException;
-    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
-            Rect initialBounds, boolean moveHomeStackFront) throws RemoteException;
-    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) throws RemoteException;
-
-    /**
-     * Resizes the input stack id to the given bounds.
-     *
-     * @param stackId Id of the stack to resize.
-     * @param bounds Bounds to resize the stack to or {@code null} for fullscreen.
-     * @param allowResizeInDockedMode True if the resize should be allowed when the docked stack is
-     *                                active.
-     * @param preserveWindows True if the windows of activities contained in the stack should be
-     *                        preserved.
-     * @param animate True if the stack resize should be animated.
-     * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
-     *                          default animation duration should be used.
-     * @throws RemoteException
-     */
-    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
-            boolean preserveWindows, boolean animate, int animationDuration) throws RemoteException;
-
-    /**
-     * Moves all tasks from the docked stack in the fullscreen stack and puts the top task of the
-     * fullscreen stack into the docked stack.
-     */
-    public void swapDockedAndFullscreenStack() throws RemoteException;
-
-    /**
-     * Resizes the docked stack, and all other stacks as the result of the dock stack bounds change.
-     *
-     * @param dockedBounds The bounds for the docked stack.
-     * @param tempDockedTaskBounds The temporary bounds for the tasks in the docked stack, which
-     *                             might be different from the stack bounds to allow more
-     *                             flexibility while resizing, or {@code null} if they should be the
-     *                             same as the stack bounds.
-     * @param tempDockedTaskInsetBounds The temporary bounds for the tasks to calculate the insets.
-     *                                  When resizing, we usually "freeze" the layout of a task. To
-     *                                  achieve that, we also need to "freeze" the insets, which
-     *                                  gets achieved by changing task bounds but not bounds used
-     *                                  to calculate the insets in this transient state
-     * @param tempOtherTaskBounds The temporary bounds for the tasks in all other stacks, or
-     *                            {@code null} if they should be the same as the stack bounds.
-     * @param tempOtherTaskInsetBounds Like {@code tempDockedTaskInsetBounds}, but for the other
-     *                                 stacks.
-     * @throws RemoteException
-     */
-    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
-            Rect tempDockedTaskInsetBounds,
-            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) throws RemoteException;
-    /**
-     * Resizes the pinned stack.
-     *
-     * @param pinnedBounds The bounds for the pinned stack.
-     * @param tempPinnedTaskBounds The temporary bounds for the tasks in the pinned stack, which
-     *                             might be different from the stack bounds to allow more
-     *                             flexibility while resizing, or {@code null} if they should be the
-     *                             same as the stack bounds.
-     */
-    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) throws RemoteException;
-    public void positionTaskInStack(int taskId, int stackId, int position) throws RemoteException;
-    public List<StackInfo> getAllStackInfos() throws RemoteException;
-    public StackInfo getStackInfo(int stackId) throws RemoteException;
-    public boolean isInHomeStack(int taskId) throws RemoteException;
-    public void setFocusedStack(int stackId) throws RemoteException;
-    public int getFocusedStackId() throws RemoteException;
-    public void setFocusedTask(int taskId) throws RemoteException;
-    public void registerTaskStackListener(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;
-    public ContentProviderHolder getContentProviderExternal(String name, int userId, IBinder token)
-            throws RemoteException;
-    public void removeContentProvider(IBinder connection, boolean stable) throws RemoteException;
-    public void removeContentProviderExternal(String name, IBinder token) throws RemoteException;
-    public void publishContentProviders(IApplicationThread caller,
-            List<ContentProviderHolder> providers) throws RemoteException;
-    public boolean refContentProvider(IBinder connection, int stableDelta, int unstableDelta)
-            throws RemoteException;
-    public void unstableProviderDied(IBinder connection) throws RemoteException;
-    public void appNotRespondingViaProvider(IBinder connection) throws RemoteException;
-    public PendingIntent getRunningServiceControlPanel(ComponentName service)
-            throws RemoteException;
-    public ComponentName startService(IApplicationThread caller, Intent service,
-            String resolvedType, String callingPackage, int userId) throws RemoteException;
-    public int stopService(IApplicationThread caller, Intent service,
-            String resolvedType, int userId) throws RemoteException;
-    public boolean stopServiceToken(ComponentName className, IBinder token,
-            int startId) throws RemoteException;
-    public void setServiceForeground(ComponentName className, IBinder token,
-            int id, Notification notification, int flags) throws RemoteException;
-    public int bindService(IApplicationThread caller, IBinder token, Intent service,
-            String resolvedType, IServiceConnection connection, int flags,
-            String callingPackage, int userId) throws RemoteException;
-    public boolean unbindService(IServiceConnection connection) throws RemoteException;
-    public void publishService(IBinder token,
-            Intent intent, IBinder service) throws RemoteException;
-    public void unbindFinished(IBinder token, Intent service,
-            boolean doRebind) throws RemoteException;
-    /* oneway */
-    public void serviceDoneExecuting(IBinder token, int type, int startId,
-            int res) throws RemoteException;
-    public IBinder peekService(Intent service, String resolvedType, String callingPackage)
-            throws RemoteException;
-
-    public boolean bindBackupAgent(String packageName, int backupRestoreMode, int userId)
-            throws RemoteException;
-    public void clearPendingBackup() throws RemoteException;
-    public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException;
-    public void unbindBackupAgent(ApplicationInfo appInfo) throws RemoteException;
-    public void killApplicationProcess(String processName, int uid) throws RemoteException;
-
-    public boolean startInstrumentation(ComponentName className, String profileFile,
-            int flags, Bundle arguments, IInstrumentationWatcher watcher,
-            IUiAutomationConnection connection, int userId,
-            String abiOverride) throws RemoteException;
-    public void finishInstrumentation(IApplicationThread target,
-            int resultCode, Bundle results) throws RemoteException;
-
-    /**
-     * @return A copy of global {@link Configuration}, contains general settings for the entire
-     *         system. Corresponds to the configuration of the default display.
-     * @throws RemoteException
-     */
-    public Configuration getConfiguration() throws RemoteException;
-
-    /**
-     * Updates global configuration and applies changes to the entire system.
-     * @param values Update values for global configuration.
-     * @throws RemoteException
-     * @return Returns true if the configuration was updated.
-     */
-    public boolean updateConfiguration(Configuration values) throws RemoteException;
-
-    public void setRequestedOrientation(IBinder token,
-            int requestedOrientation) throws RemoteException;
-    public int getRequestedOrientation(IBinder token) throws RemoteException;
-
-    public ComponentName getActivityClassForToken(IBinder token) throws RemoteException;
-    public String getPackageForToken(IBinder token) throws RemoteException;
-
-    public IIntentSender getIntentSender(int type,
-            String packageName, IBinder token, String resultWho,
-            int requestCode, Intent[] intents, String[] resolvedTypes,
-            int flags, Bundle options, int userId) throws RemoteException;
-    public void cancelIntentSender(IIntentSender sender) throws RemoteException;
-    public boolean clearApplicationUserData(final String packageName,
-            final IPackageDataObserver observer, int userId) throws RemoteException;
-    public String getPackageForIntentSender(IIntentSender sender) throws RemoteException;
-    public int getUidForIntentSender(IIntentSender sender) throws RemoteException;
-
-    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
-            boolean requireFull, String name, String callerPackage) throws RemoteException;
-
-    public void setProcessLimit(int max) throws RemoteException;
-    public int getProcessLimit() throws RemoteException;
-
-    public void setProcessForeground(IBinder token, int pid,
-            boolean isForeground) throws RemoteException;
-
-    public int checkPermission(String permission, int pid, int uid)
-            throws RemoteException;
-    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken)
-            throws RemoteException;
-
-    public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId,
-            IBinder callerToken) throws RemoteException;
-    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
-            int mode, int userId) throws RemoteException;
-    public void revokeUriPermission(IApplicationThread caller, Uri uri, int mode, int userId)
-            throws RemoteException;
-    public void takePersistableUriPermission(Uri uri, int modeFlags, int userId)
-            throws RemoteException;
-    public void releasePersistableUriPermission(Uri uri, int modeFlags, int userId)
-            throws RemoteException;
-    public ParceledListSlice<UriPermission> getPersistedUriPermissions(
-            String packageName, boolean incoming) throws RemoteException;
-
-    // Gets the URI permissions granted to an arbitrary package.
-    // NOTE: this is different from getPersistedUriPermissions(), which returns the URIs the package
-    // granted to another packages (instead of those granted to it).
-    public ParceledListSlice<UriPermission> getGrantedUriPermissions(String packageName, int userId)
-            throws RemoteException;
-
-    // Clears the URI permissions granted to an arbitrary package.
-    public void clearGrantedUriPermissions(String packageName, int userId) throws RemoteException;
-
-    public void showWaitingForDebugger(IApplicationThread who, boolean waiting)
-            throws RemoteException;
-
-    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) throws RemoteException;
-
-    public void killBackgroundProcesses(final String packageName, int userId)
-            throws RemoteException;
-    public void killAllBackgroundProcesses() throws RemoteException;
-    public void killPackageDependents(final String packageName, int userId) throws RemoteException;
-    public void forceStopPackage(final String packageName, int userId) throws RemoteException;
-
-    // Note: probably don't want to allow applications access to these.
-    public void setLockScreenShown(boolean showing, boolean occluded) throws RemoteException;
-
-    public void unhandledBack() throws RemoteException;
-    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException;
-    public void setDebugApp(
-        String packageName, boolean waitForDebugger, boolean persistent)
-        throws RemoteException;
-    public void setAlwaysFinish(boolean enabled) throws RemoteException;
-    public void setActivityController(IActivityController watcher, boolean imAMonkey)
-        throws RemoteException;
-    public void setLenientBackgroundCheck(boolean enabled) throws RemoteException;
-    public int getMemoryTrimLevel() throws RemoteException;
-
-    public void enterSafeMode() throws RemoteException;
-
-    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag)
-            throws RemoteException;
-    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag)
-            throws RemoteException;
-    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag)
-            throws RemoteException;
-
-    public boolean killPids(int[] pids, String reason, boolean secure) throws RemoteException;
-    public boolean killProcessesBelowForeground(String reason) throws RemoteException;
-
-    // Special low-level communication with activity manager.
-    public void handleApplicationCrash(IBinder app,
-            ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException;
-    public boolean handleApplicationWtf(IBinder app, String tag, boolean system,
-            ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException;
-
-    // A StrictMode violation to be handled.  The violationMask is a
-    // subset of the original StrictMode policy bitmask, with only the
-    // bit violated and penalty bits to be executed by the
-    // ActivityManagerService remaining set.
-    public void handleApplicationStrictModeViolation(IBinder app, int violationMask,
-            StrictMode.ViolationInfo crashInfo) throws RemoteException;
-
-    /*
-     * This will deliver the specified signal to all the persistent processes. Currently only
-     * SIGUSR1 is delivered. All others are ignored.
-     */
-    public void signalPersistentProcesses(int signal) throws RemoteException;
-    // Retrieve running application processes in the system
-    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses()
-            throws RemoteException;
-    // Retrieve info of applications installed on external media that are currently
-    // running.
-    public List<ApplicationInfo> getRunningExternalApplications()
-            throws RemoteException;
-    // Get memory information about the calling process.
-    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo)
-            throws RemoteException;
-    // Get device configuration
-    public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException;
-
-    // Turn on/off profiling in a particular process.
-    public boolean profileControl(String process, int userId, boolean start,
-            ProfilerInfo profilerInfo, int profileType) throws RemoteException;
-
-    public boolean shutdown(int timeout) throws RemoteException;
-
-    public void stopAppSwitches() throws RemoteException;
-    public void resumeAppSwitches() throws RemoteException;
-
-    public void addPackageDependency(String packageName) throws RemoteException;
-
-    public void killApplication(String pkg, int appId, int userId, String reason)
-            throws RemoteException;
-
-    public void closeSystemDialogs(String reason) throws RemoteException;
-
-    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
-            throws RemoteException;
-
-    public void overridePendingTransition(IBinder token, String packageName,
-            int enterAnim, int exitAnim) throws RemoteException;
-
-    public boolean isUserAMonkey() throws RemoteException;
-
-    public void setUserIsMonkey(boolean monkey) throws RemoteException;
-
-    public void finishHeavyWeightApp() throws RemoteException;
-
-    public boolean convertFromTranslucent(IBinder token) throws RemoteException;
-    public boolean convertToTranslucent(IBinder token, ActivityOptions options) throws RemoteException;
-    public void notifyActivityDrawn(IBinder token) throws RemoteException;
-    public ActivityOptions getActivityOptions(IBinder token) throws RemoteException;
-
-    public void bootAnimationComplete() throws RemoteException;
-
-    public void setImmersive(IBinder token, boolean immersive) throws RemoteException;
-    public boolean isImmersive(IBinder token) throws RemoteException;
-    public boolean isTopActivityImmersive() throws RemoteException;
-    public boolean isTopOfTask(IBinder token) throws RemoteException;
-
-    public void crashApplication(int uid, int initialPid, String packageName,
-            String message) throws RemoteException;
-
-    public String getProviderMimeType(Uri uri, int userId) throws RemoteException;
-
-    public IBinder newUriPermissionOwner(String name) throws RemoteException;
-    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) throws RemoteException;
-    public void grantUriPermissionFromOwner(IBinder owner, int fromUid, String targetPkg,
-            Uri uri, int mode, int sourceUserId, int targetUserId) throws RemoteException;
-    public void revokeUriPermissionFromOwner(IBinder owner, Uri uri,
-            int mode, int userId) throws RemoteException;
-
-    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
-            int modeFlags, int userId) throws RemoteException;
-
-    // Cause the specified process to dump the specified heap.
-    public boolean dumpHeap(String process, int userId, boolean managed, String path,
-        ParcelFileDescriptor fd) throws RemoteException;
-
-    public int startActivities(IApplicationThread caller, String callingPackage,
-            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
-            Bundle options, int userId) throws RemoteException;
-
-    public int getFrontActivityScreenCompatMode() throws RemoteException;
-    public void setFrontActivityScreenCompatMode(int mode) throws RemoteException;
-    public int getPackageScreenCompatMode(String packageName) throws RemoteException;
-    public void setPackageScreenCompatMode(String packageName, int mode)
-            throws RemoteException;
-    public boolean getPackageAskScreenCompat(String packageName) throws RemoteException;
-    public void setPackageAskScreenCompat(String packageName, boolean ask)
-            throws RemoteException;
-
-    // Multi-user APIs
-    public boolean switchUser(int userid) throws RemoteException;
-    public boolean startUserInBackground(int userid) throws RemoteException;
-    public boolean unlockUser(int userid, byte[] token, byte[] secret, IProgressListener listener)
-            throws RemoteException;
-    public int stopUser(int userid, boolean force, IStopUserCallback callback) throws RemoteException;
-    public UserInfo getCurrentUser() throws RemoteException;
-    public boolean isUserRunning(int userid, int flags) throws RemoteException;
-    public int[] getRunningUserIds() throws RemoteException;
-
-    public boolean removeTask(int taskId) throws RemoteException;
-
-    public void registerProcessObserver(IProcessObserver observer) throws RemoteException;
-    public void unregisterProcessObserver(IProcessObserver observer) throws RemoteException;
-
-    public void registerUidObserver(IUidObserver observer, int which) throws RemoteException;
-    public void unregisterUidObserver(IUidObserver observer) throws RemoteException;
-
-    public boolean isIntentSenderTargetedToPackage(IIntentSender sender) throws RemoteException;
-
-    public boolean isIntentSenderAnActivity(IIntentSender sender) throws RemoteException;
-
-    public Intent getIntentForIntentSender(IIntentSender sender) throws RemoteException;
-
-    public String getTagForIntentSender(IIntentSender sender, String prefix) throws RemoteException;
-
-    public void updatePersistentConfiguration(Configuration values) throws RemoteException;
-
-    public long[] getProcessPss(int[] pids) throws RemoteException;
-
-    public void showBootMessage(CharSequence msg, boolean always) throws RemoteException;
-
-    public void keyguardWaitingForActivityDrawn() throws RemoteException;
-
-    /**
-     * Notify the system that the keyguard is going away.
-     *
-     * @param flags See {@link android.view.WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
-     *              etc.
-     */
-    public void keyguardGoingAway(int flags) throws RemoteException;
-
-    public boolean shouldUpRecreateTask(IBinder token, String destAffinity)
-            throws RemoteException;
-
-    public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent resultData)
-            throws RemoteException;
-
-    // These are not public because you need to be very careful in how you
-    // manage your activity to make sure it is always the uid you expect.
-    public int getLaunchedFromUid(IBinder activityToken) throws RemoteException;
-    public String getLaunchedFromPackage(IBinder activityToken) throws RemoteException;
-
-    public void registerUserSwitchObserver(IUserSwitchObserver observer,
-            String name) throws RemoteException;
-    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException;
-
-    public void requestBugReport(int bugreportType) throws RemoteException;
-
-    public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason)
-            throws RemoteException;
-
-    public Bundle getAssistContextExtras(int requestType) throws RemoteException;
-
-    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
-            Bundle receiverExtras,
-            IBinder activityToken, boolean focused, boolean newSessionId) throws RemoteException;
-
-    public void reportAssistContextExtras(IBinder token, Bundle extras,
-            AssistStructure structure, AssistContent content, Uri referrer) throws RemoteException;
-
-    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
-            Bundle args) throws RemoteException;
-
-    public boolean isAssistDataAllowedOnCurrentActivity() throws RemoteException;
-
-    public boolean showAssistFromActivity(IBinder token, Bundle args) throws RemoteException;
-
-    public void killUid(int appId, int userId, String reason) throws RemoteException;
-
-    public void hang(IBinder who, boolean allowRestart) throws RemoteException;
-
-    public void reportActivityFullyDrawn(IBinder token) throws RemoteException;
-
-    public void restart() throws RemoteException;
-
-    public void performIdleMaintenance() throws RemoteException;
-
-    public void sendIdleJobTrigger() throws RemoteException;
-
-    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
-            IActivityContainerCallback callback) throws RemoteException;
-
-    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;
-
-    public void startLockTaskMode(int taskId) throws RemoteException;
-
-    public void startLockTaskMode(IBinder token) throws RemoteException;
-
-    public void stopLockTaskMode() throws RemoteException;
-
-    public void stopSystemLockTaskMode() throws RemoteException;
-
-    public boolean isInLockTaskMode() throws RemoteException;
-
-    public int getLockTaskModeState() throws RemoteException;
-
-    public void showLockTaskEscapeMessage(IBinder token) throws RemoteException;
-
-    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription values)
-            throws RemoteException;
-    public void setTaskResizeable(int taskId, int resizeableMode) throws RemoteException;
-    public void resizeTask(int taskId, Rect bounds, int resizeMode) throws RemoteException;
-
-    public Rect getTaskBounds(int taskId) throws RemoteException;
-    public Bitmap getTaskDescriptionIcon(String filename, int userId) throws RemoteException;
-
-    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
-            throws RemoteException;
-
-    public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException;
-    public boolean isBackgroundVisibleBehind(IBinder token) throws RemoteException;
-    public void backgroundResourcesReleased(IBinder token) throws RemoteException;
-
-    public void notifyLaunchTaskBehindComplete(IBinder token) throws RemoteException;
-    public void notifyEnterAnimationComplete(IBinder token) throws RemoteException;
-
-    public void notifyCleartextNetwork(int uid, byte[] firstPacket) throws RemoteException;
-
-    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
-            String reportPackage) throws RemoteException;
-    public void dumpHeapFinished(String path) throws RemoteException;
-
-    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake)
-            throws RemoteException;
-    public void updateLockTaskPackages(int userId, String[] packages) throws RemoteException;
-    public void updateDeviceOwner(String packageName) throws RemoteException;
-
-    public int getPackageProcessState(String packageName, String callingPackage)
-            throws RemoteException;
-
-    public boolean setProcessMemoryTrimLevel(String process, int uid, int level)
-            throws RemoteException;
-
-    public boolean isRootVoiceInteraction(IBinder token) throws RemoteException;
-
-    // Start Binder transaction tracking for all applications.
-    public boolean startBinderTracking() throws RemoteException;
-
-    // Stop Binder transaction tracking for all applications and dump trace data to the given file
-    // descriptor.
-    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException;
-
-    public int getActivityStackId(IBinder token) throws RemoteException;
-    public void exitFreeformMode(IBinder token) throws RemoteException;
-
-    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException;
-
-    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) throws RemoteException;
-
-    public int getAppStartMode(int uid, String packageName) throws RemoteException;
-
-    public boolean isInMultiWindowMode(IBinder token) throws RemoteException;
-
-    public boolean isInPictureInPictureMode(IBinder token) throws RemoteException;
-
-    public void enterPictureInPictureMode(IBinder token) throws RemoteException;
-
-    /**
-     * @return the default bounds of the PIP on the default display.
-     */
-    public Rect getDefaultPictureInPictureBounds() throws RemoteException;
-
-    /**
-     * @return the movement bounds of the PIP on the default display.
-     */
-    public Rect getPictureInPictureMovementBounds() throws RemoteException;
-
-    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName)
-            throws RemoteException;
-
-    public boolean isVrModePackageEnabled(ComponentName packageName) throws RemoteException;
-
-    public boolean isAppForeground(int uid) throws RemoteException;
-
-    public void startLocalVoiceInteraction(IBinder token, Bundle options) throws RemoteException;
-
-    public void stopLocalVoiceInteraction(IBinder token) throws RemoteException;
-
-    public boolean supportsLocalVoiceInteraction() throws RemoteException;
-
-    public void notifyPinnedStackAnimationEnded() throws RemoteException;
-
-    public void removeStack(int stackId) throws RemoteException;
-
-    public void notifyLockedProfile(@UserIdInt int userId) throws RemoteException;
-
-    public void startConfirmDeviceCredentialIntent(Intent intent) throws RemoteException;
-
-    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
-            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)
-            throws RemoteException;
-
-    public void setVrThread(int tid) throws RemoteException;
-    public void setRenderThread(int tid) throws RemoteException;
-
-    /**
-     * Lets activity manager know whether the calling process is currently showing "top-level" UI
-     * that is not an activity, i.e. windows on the screen the user is currently interacting with.
-     *
-     * <p>This flag can only be set for persistent processes.
-     *
-     * @param hasTopUi Whether the calling process has "top-level" UI.
-     */
-    public void setHasTopUi(boolean hasTopUi) throws RemoteException;
-
-    /**
-     * Returns if the target of the PendingIntent can be fired directly, without triggering
-     * a work profile challenge. This can happen if the PendingIntent is to start direct-boot
-     * aware activities, and the target user is in RUNNING_LOCKED state, i.e. we should allow
-     * direct-boot aware activity to bypass work challenge when the user hasn't unlocked yet.
-     * @param intent the {@link  PendingIntent} to be tested.
-     * @return {@code true} if the intent should not trigger a work challenge, {@code false}
-     *     otherwise.
-     * @throws RemoteException
-     */
-    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException;
-
-    /*
-     * Private non-Binder interfaces
-     */
-    /* package */ boolean testIsSystemReady();
-
-    /** Information you can retrieve about a particular application. */
-    public static class ContentProviderHolder implements Parcelable {
-        public final ProviderInfo info;
-        public IContentProvider provider;
-        public IBinder connection;
-        public boolean noReleaseNeeded;
-
-        public ContentProviderHolder(ProviderInfo _info) {
-            info = _info;
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            info.writeToParcel(dest, 0);
-            if (provider != null) {
-                dest.writeStrongBinder(provider.asBinder());
-            } else {
-                dest.writeStrongBinder(null);
-            }
-            dest.writeStrongBinder(connection);
-            dest.writeInt(noReleaseNeeded ? 1 : 0);
-        }
-
-        public static final Parcelable.Creator<ContentProviderHolder> CREATOR
-                = new Parcelable.Creator<ContentProviderHolder>() {
-            @Override
-            public ContentProviderHolder createFromParcel(Parcel source) {
-                return new ContentProviderHolder(source);
-            }
-
-            @Override
-            public ContentProviderHolder[] newArray(int size) {
-                return new ContentProviderHolder[size];
-            }
-        };
-
-        private ContentProviderHolder(Parcel source) {
-            info = ProviderInfo.CREATOR.createFromParcel(source);
-            provider = ContentProviderNative.asInterface(
-                    source.readStrongBinder());
-            connection = source.readStrongBinder();
-            noReleaseNeeded = source.readInt() != 0;
-        }
-    }
-
-    /** Information returned after waiting for an activity start. */
-    public static class WaitResult implements Parcelable {
-        public int result;
-        public boolean timeout;
-        public ComponentName who;
-        public long thisTime;
-        public long totalTime;
-
-        public WaitResult() {
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(result);
-            dest.writeInt(timeout ? 1 : 0);
-            ComponentName.writeToParcel(who, dest);
-            dest.writeLong(thisTime);
-            dest.writeLong(totalTime);
-        }
-
-        public static final Parcelable.Creator<WaitResult> CREATOR
-                = new Parcelable.Creator<WaitResult>() {
-            @Override
-            public WaitResult createFromParcel(Parcel source) {
-                return new WaitResult(source);
-            }
-
-            @Override
-            public WaitResult[] newArray(int size) {
-                return new WaitResult[size];
-            }
-        };
-
-        private WaitResult(Parcel source) {
-            result = source.readInt();
-            timeout = source.readInt() != 0;
-            who = ComponentName.readFromParcel(source);
-            thisTime = source.readLong();
-            totalTime = source.readLong();
-        }
-    }
-
-    String descriptor = "android.app.IActivityManager";
-
-    // Please keep these transaction codes the same -- they are also
-    // sent by C++ code.
-    int HANDLE_APPLICATION_CRASH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+1;
-    int START_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+2;
-    int UNHANDLED_BACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+3;
-    int OPEN_CONTENT_URI_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+4;
-
-    // Remaining non-native transaction codes.
-    int FINISH_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+10;
-    int REGISTER_RECEIVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+11;
-    int UNREGISTER_RECEIVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+12;
-    int BROADCAST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+13;
-    int UNBROADCAST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+14;
-    int FINISH_RECEIVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+15;
-    int ATTACH_APPLICATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+16;
-    int ACTIVITY_IDLE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+17;
-    int ACTIVITY_PAUSED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+18;
-    int ACTIVITY_STOPPED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+19;
-    int GET_CALLING_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+20;
-    int GET_CALLING_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+21;
-    int GET_TASKS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+22;
-    int MOVE_TASK_TO_FRONT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+23;
-
-    int MOVE_TASK_BACKWARDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+25;
-    int GET_TASK_FOR_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+26;
-
-    int GET_CONTENT_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
-    int PUBLISH_CONTENT_PROVIDERS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
-    int REF_CONTENT_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
-    int FINISH_SUB_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
-    int GET_RUNNING_SERVICE_CONTROL_PANEL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
-    int START_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+33;
-    int STOP_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+34;
-    int BIND_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+35;
-    int UNBIND_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+36;
-    int PUBLISH_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+37;
-    int ACTIVITY_RESUMED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+38;
-    int SET_DEBUG_APP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+41;
-    int SET_ALWAYS_FINISH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+42;
-    int START_INSTRUMENTATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+43;
-    int FINISH_INSTRUMENTATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+44;
-    int GET_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+45;
-    int UPDATE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+46;
-    int STOP_SERVICE_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+47;
-    int GET_ACTIVITY_CLASS_FOR_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+48;
-    int GET_PACKAGE_FOR_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+49;
-    int SET_PROCESS_LIMIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+50;
-    int GET_PROCESS_LIMIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+51;
-    int CHECK_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+52;
-    int CHECK_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+53;
-    int GRANT_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+54;
-    int REVOKE_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+55;
-    int SET_ACTIVITY_CONTROLLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+56;
-    int SHOW_WAITING_FOR_DEBUGGER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+57;
-    int SIGNAL_PERSISTENT_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+58;
-    int GET_RECENT_TASKS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+59;
-    int SERVICE_DONE_EXECUTING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+60;
-    int ACTIVITY_DESTROYED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+61;
-    int GET_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+62;
-    int CANCEL_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+63;
-    int GET_PACKAGE_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+64;
-    int ENTER_SAFE_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+65;
-    int START_NEXT_MATCHING_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+66;
-    int NOTE_WAKEUP_ALARM_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+67;
-    int REMOVE_CONTENT_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+68;
-    int SET_REQUESTED_ORIENTATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+69;
-    int GET_REQUESTED_ORIENTATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+70;
-    int UNBIND_FINISHED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+71;
-    int SET_PROCESS_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+72;
-    int SET_SERVICE_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+73;
-    int MOVE_ACTIVITY_TASK_TO_BACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+74;
-    int GET_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+75;
-    int GET_PROCESSES_IN_ERROR_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+76;
-    int CLEAR_APP_DATA_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+77;
-    int FORCE_STOP_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+78;
-    int KILL_PIDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+79;
-    int GET_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+80;
-    int GET_TASK_THUMBNAIL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+81;
-    int GET_RUNNING_APP_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+82;
-    int GET_DEVICE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+83;
-    int PEEK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+84;
-    int PROFILE_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+85;
-    int SHUTDOWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+86;
-    int STOP_APP_SWITCHES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+87;
-    int RESUME_APP_SWITCHES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+88;
-    int START_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+89;
-    int BACKUP_AGENT_CREATED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+90;
-    int UNBIND_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+91;
-    int GET_UID_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+92;
-    int HANDLE_INCOMING_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+93;
-    int ADD_PACKAGE_DEPENDENCY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+94;
-    int KILL_APPLICATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+95;
-    int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96;
-    int GET_PROCESS_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+97;
-    int KILL_APPLICATION_PROCESS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+98;
-    int START_ACTIVITY_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+99;
-    int OVERRIDE_PENDING_TRANSITION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+100;
-    int HANDLE_APPLICATION_WTF_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+101;
-    int KILL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+102;
-    int IS_USER_A_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+103;
-    int START_ACTIVITY_AND_WAIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+104;
-    int WILL_ACTIVITY_BE_VISIBLE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+105;
-    int START_ACTIVITY_WITH_CONFIG_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+106;
-    int GET_RUNNING_EXTERNAL_APPLICATIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+107;
-    int FINISH_HEAVY_WEIGHT_APP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+108;
-    int HANDLE_APPLICATION_STRICT_MODE_VIOLATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+109;
-    int IS_IMMERSIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+110;
-    int SET_IMMERSIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+111;
-    int IS_TOP_ACTIVITY_IMMERSIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+112;
-    int CRASH_APPLICATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+113;
-    int GET_PROVIDER_MIME_TYPE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+114;
-    int NEW_URI_PERMISSION_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+115;
-    int GRANT_URI_PERMISSION_FROM_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+116;
-    int REVOKE_URI_PERMISSION_FROM_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+117;
-    int CHECK_GRANT_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+118;
-    int DUMP_HEAP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+119;
-    int START_ACTIVITIES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+120;
-    int IS_USER_RUNNING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+121;
-    int ACTIVITY_SLEPT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+122;
-    int GET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+123;
-    int SET_FRONT_ACTIVITY_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+124;
-    int GET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+125;
-    int SET_PACKAGE_SCREEN_COMPAT_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+126;
-    int GET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+127;
-    int SET_PACKAGE_ASK_SCREEN_COMPAT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+128;
-    int SWITCH_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+129;
-    int SET_FOCUSED_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+130;
-    int REMOVE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+131;
-    int REGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+132;
-    int UNREGISTER_PROCESS_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+133;
-    int IS_INTENT_SENDER_TARGETED_TO_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+134;
-    int UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+135;
-    int GET_PROCESS_PSS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+136;
-    int SHOW_BOOT_MESSAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+137;
-    int KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+139;
-    int GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+140;
-    int REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+141;
-    int GET_MY_MEMORY_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+142;
-    int KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+143;
-    int GET_CURRENT_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+144;
-    int SHOULD_UP_RECREATE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+145;
-    int NAVIGATE_UP_TO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+146;
-    int SET_LOCK_SCREEN_SHOWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+147;
-    int FINISH_ACTIVITY_AFFINITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+148;
-    int GET_LAUNCHED_FROM_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+149;
-    int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+150;
-    int IS_INTENT_SENDER_AN_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+151;
-    int START_ACTIVITY_AS_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+152;
-    int STOP_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+153;
-    int REGISTER_USER_SWITCH_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+154;
-    int UNREGISTER_USER_SWITCH_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+155;
-    int GET_RUNNING_USER_IDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+156;
-    int REQUEST_BUG_REPORT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+157;
-    int INPUT_DISPATCHING_TIMED_OUT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+158;
-    int CLEAR_PENDING_BACKUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+159;
-    int GET_INTENT_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+160;
-    int GET_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+161;
-    int REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+162;
-    int GET_LAUNCHED_FROM_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+163;
-    int KILL_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+164;
-    int SET_USER_IS_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+165;
-    int HANG_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+166;
-    int CREATE_VIRTUAL_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+167;
-    int MOVE_TASK_TO_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+168;
-    int RESIZE_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+169;
-    int GET_ALL_STACK_INFOS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170;
-    int SET_FOCUSED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+171;
-    int GET_STACK_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+172;
-    int CONVERT_FROM_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+173;
-    int CONVERT_TO_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+174;
-    int NOTIFY_ACTIVITY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+175;
-    int REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+176;
-    int RESTART_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+177;
-    int PERFORM_IDLE_MAINTENANCE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+178;
-    int TAKE_PERSISTABLE_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+179;
-    int RELEASE_PERSISTABLE_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+180;
-    int GET_PERSISTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+181;
-    int APP_NOT_RESPONDING_VIA_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+182;
-    int GET_TASK_BOUNDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+183;
-    int GET_ACTIVITY_DISPLAY_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+184;
-    int DELETE_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+185;
-    int SET_PROCESS_MEMORY_TRIM_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+186;
-
-    // Start of L transactions
-    int GET_TAG_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+210;
-    int START_USER_IN_BACKGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+211;
-    int IS_IN_HOME_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+212;
-    int START_LOCK_TASK_BY_TASK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+213;
-    int START_LOCK_TASK_BY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+214;
-    int STOP_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+215;
-    int IS_IN_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+216;
-    int SET_TASK_DESCRIPTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+217;
-    int START_VOICE_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+218;
-    int GET_ACTIVITY_OPTIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+219;
-    int GET_APP_TASKS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+220;
-    int START_SYSTEM_LOCK_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+221;
-    int STOP_SYSTEM_LOCK_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+222;
-    int FINISH_VOICE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+223;
-    int IS_TOP_OF_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+224;
-    int REQUEST_VISIBLE_BEHIND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+225;
-    int IS_BACKGROUND_VISIBLE_BEHIND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+226;
-    int BACKGROUND_RESOURCES_RELEASED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+227;
-    int NOTIFY_LAUNCH_TASK_BEHIND_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+228;
-    int START_ACTIVITY_FROM_RECENTS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 229;
-    int NOTIFY_ENTER_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+230;
-    int KEYGUARD_WAITING_FOR_ACTIVITY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+231;
-    int START_ACTIVITY_AS_CALLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+232;
-    int ADD_APP_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+233;
-    int GET_APP_TASK_THUMBNAIL_SIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+234;
-    int RELEASE_ACTIVITY_INSTANCE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+235;
-    int RELEASE_SOME_ACTIVITIES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+236;
-    int BOOT_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+237;
-    int GET_TASK_DESCRIPTION_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+238;
-    int LAUNCH_ASSIST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+239;
-    int START_IN_PLACE_ANIMATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+240;
-    int CHECK_PERMISSION_WITH_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+241;
-    int REGISTER_TASK_STACK_LISTENER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+242;
-
-    // Start of M transactions
-    int NOTIFY_CLEARTEXT_NETWORK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+280;
-    int CREATE_STACK_ON_DISPLAY = IBinder.FIRST_CALL_TRANSACTION+281;
-    int GET_FOCUSED_STACK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+282;
-    int SET_TASK_RESIZEABLE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+283;
-    int REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+284;
-    int RESIZE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+285;
-    int GET_LOCK_TASK_MODE_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+286;
-    int SET_DUMP_HEAP_DEBUG_LIMIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+287;
-    int DUMP_HEAP_FINISHED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+288;
-    int SET_VOICE_KEEP_AWAKE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+289;
-    int UPDATE_LOCK_TASK_PACKAGES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+290;
-    int NOTE_ALARM_START_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+291;
-    int NOTE_ALARM_FINISH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+292;
-    int GET_PACKAGE_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+293;
-    int SHOW_LOCK_TASK_ESCAPE_MESSAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+294;
-    int UPDATE_DEVICE_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+295;
-    int KEYGUARD_GOING_AWAY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+296;
-    int REGISTER_UID_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+297;
-    int UNREGISTER_UID_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+298;
-    int IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION
-            = IBinder.FIRST_CALL_TRANSACTION+299;
-    int SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+300;
-    int IS_ROOT_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+301;
-
-    // Start of N transactions
-    int START_BINDER_TRACKING_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 340;
-    int STOP_BINDER_TRACKING_AND_DUMP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 341;
-    int POSITION_TASK_IN_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 342;
-    int GET_ACTIVITY_STACK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 343;
-    int EXIT_FREEFORM_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 344;
-    int REPORT_SIZE_CONFIGURATIONS = IBinder.FIRST_CALL_TRANSACTION + 345;
-    int MOVE_TASK_TO_DOCKED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 346;
-    int SUPPRESS_RESIZE_CONFIG_CHANGES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 347;
-    int MOVE_TASKS_TO_FULLSCREEN_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 348;
-    int MOVE_TOP_ACTIVITY_TO_PINNED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 349;
-    int GET_APP_START_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 350;
-    int UNLOCK_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 351;
-    int IN_MULTI_WINDOW_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 352;
-    int IN_PICTURE_IN_PICTURE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 353;
-    int KILL_PACKAGE_DEPENDENTS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 354;
-    int ENTER_PICTURE_IN_PICTURE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 355;
-    int ACTIVITY_RELAUNCHED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 356;
-    int GET_URI_PERMISSION_OWNER_FOR_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 357;
-    int RESIZE_DOCKED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 358;
-    int SET_VR_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 359;
-    int GET_GRANTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 360;
-    int CLEAR_GRANTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 361;
-    int IS_APP_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 362;
-    int START_LOCAL_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 363;
-    int STOP_LOCAL_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 364;
-    int SUPPORTS_LOCAL_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 365;
-    int NOTIFY_PINNED_STACK_ANIMATION_ENDED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 366;
-    int REMOVE_STACK = IBinder.FIRST_CALL_TRANSACTION + 367;
-    int SET_LENIENT_BACKGROUND_CHECK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+368;
-    int GET_MEMORY_TRIM_LEVEL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+369;
-    int RESIZE_PINNED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 370;
-    int IS_VR_PACKAGE_ENABLED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 371;
-    int SWAP_DOCKED_AND_FULLSCREEN_STACK = IBinder.FIRST_CALL_TRANSACTION + 372;
-    int NOTIFY_LOCKED_PROFILE = IBinder.FIRST_CALL_TRANSACTION + 373;
-    int START_CONFIRM_DEVICE_CREDENTIAL_INTENT = IBinder.FIRST_CALL_TRANSACTION + 374;
-    int SEND_IDLE_JOB_TRIGGER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 375;
-    int SEND_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 376;
-
-    // Start of N MR1 transactions
-    int SET_VR_THREAD_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 377;
-    int SET_RENDER_THREAD_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 378;
-    int SET_HAS_TOP_UI = IBinder.FIRST_CALL_TRANSACTION + 379;
-    int CAN_BYPASS_WORK_CHALLENGE = IBinder.FIRST_CALL_TRANSACTION + 380;
-
-    // Start of O transactions
-    int REQUEST_ACTIVITY_RELAUNCH = IBinder.FIRST_CALL_TRANSACTION+400;
-    int GET_DEFAULT_PICTURE_IN_PICTURE_BOUNDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 401;
-    int GET_PICTURE_IN_PICTURE_MOVEMENT_BOUNDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 402;
-}
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 2dd3b1a..c2b5b93 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -56,30 +56,30 @@
      * When adding a new method, assign the next available transaction id.
      */
     void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
-            int configChanges, boolean dontReport) = 1;
+            int configChanges, boolean dontReport) = 0;
     void scheduleStopActivity(IBinder token, boolean showWindow,
-            int configChanges) = 3;
-    void scheduleWindowVisibility(IBinder token, boolean showWindow) = 4;
+            int configChanges) = 2;
+    void scheduleWindowVisibility(IBinder token, boolean showWindow) = 3;
     void scheduleResumeActivity(IBinder token, int procState, boolean isForward,
-            in Bundle resumeArgs) = 5;
-    void scheduleSendResult(IBinder token, in List<ResultInfo> results) = 6;
+            in Bundle resumeArgs) = 4;
+    void scheduleSendResult(IBinder token, in List<ResultInfo> results) = 5;
     void scheduleLaunchActivity(in Intent intent, IBinder token, int ident,
             in ActivityInfo info, in Configuration curConfig, in Configuration overrideConfig,
             in CompatibilityInfo compatInfo, in String referrer, IVoiceInteractor voiceInteractor,
             int procState, in Bundle state, in PersistableBundle persistentState,
             in List<ResultInfo> pendingResults, in List<ReferrerIntent> pendingNewIntents,
-            boolean notResumed, boolean isForward, in ProfilerInfo profilerInfo) = 7;
+            boolean notResumed, boolean isForward, in ProfilerInfo profilerInfo) = 6;
     void scheduleNewIntent(
-            in List<ReferrerIntent> intent, IBinder token, boolean andPause) = 8;
+            in List<ReferrerIntent> intent, IBinder token, boolean andPause) = 7;
     void scheduleDestroyActivity(IBinder token, boolean finished,
-            int configChanges) = 9;
+            int configChanges) = 8;
     void scheduleReceiver(in Intent intent, in ActivityInfo info,
             in CompatibilityInfo compatInfo,
             int resultCode, in String data, in Bundle extras, boolean sync,
-            int sendingUser, int processState) = 10;
+            int sendingUser, int processState) = 9;
     void scheduleCreateService(IBinder token, in ServiceInfo info,
-            in CompatibilityInfo compatInfo, int processState) = 11;
-    void scheduleStopService(IBinder token) = 12;
+            in CompatibilityInfo compatInfo, int processState) = 10;
+    void scheduleStopService(IBinder token) = 11;
     void bindApplication(in String packageName, in ApplicationInfo info,
             in List<ProviderInfo> providers, in ComponentName testName,
             in ProfilerInfo profilerInfo, in Bundle testArguments,
@@ -87,74 +87,75 @@
             int debugMode, boolean enableBinderTracking, boolean trackAllocation,
             boolean restrictedBackupMode, boolean persistent, in Configuration config,
             in CompatibilityInfo compatInfo, in Map services,
-            in Bundle coreSettings, in String buildSerial) = 13;
-    void scheduleExit() = 14;
-    void scheduleConfigurationChanged(in Configuration config) = 16;
+            in Bundle coreSettings, in String buildSerial) = 12;
+    void scheduleExit() = 13;
+    void scheduleConfigurationChanged(in Configuration config) = 15;
     void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
-            int flags, in Intent args) = 17;
-    void updateTimeZone() = 18;
-    void processInBackground() = 19;
+            int flags, in Intent args) = 16;
+    void updateTimeZone() = 17;
+    void processInBackground() = 18;
     void scheduleBindService(IBinder token,
-            in Intent intent, boolean rebind, int processState) = 20;
+            in Intent intent, boolean rebind, int processState) = 19;
     void scheduleUnbindService(IBinder token,
-            in Intent intent) = 21;
+            in Intent intent) = 20;
     void dumpService(in ParcelFileDescriptor fd, IBinder servicetoken,
-            in String[] args) = 22;
+            in String[] args) = 21;
     void scheduleRegisteredReceiver(IIntentReceiver receiver, in Intent intent,
             int resultCode, in String data, in Bundle extras, boolean ordered,
-            boolean sticky, int sendingUser, int processState) = 23;
-    void scheduleLowMemory() = 24;
+            boolean sticky, int sendingUser, int processState) = 22;
+    void scheduleLowMemory() = 23;
     void scheduleActivityConfigurationChanged(IBinder token, in Configuration overrideConfig,
-            boolean reportToActivity) = 25;
+            boolean reportToActivity) = 24;
     void scheduleRelaunchActivity(IBinder token, in List<ResultInfo> pendingResults,
             in List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed,
-            in Configuration config, in Configuration overrideConfig, boolean preserveWindow) = 26;
-    void scheduleSleeping(IBinder token, boolean sleeping) = 27;
-    void profilerControl(boolean start, in ProfilerInfo profilerInfo, int profileType) = 28;
-    void setSchedulingGroup(int group) = 29;
+            in Configuration config, in Configuration overrideConfig, boolean preserveWindow) = 25;
+    void scheduleSleeping(IBinder token, boolean sleeping) = 26;
+    void profilerControl(boolean start, in ProfilerInfo profilerInfo, int profileType) = 27;
+    void setSchedulingGroup(int group) = 28;
     void scheduleCreateBackupAgent(in ApplicationInfo app, in CompatibilityInfo compatInfo,
-            int backupMode) = 30;
+            int backupMode) = 29;
     void scheduleDestroyBackupAgent(in ApplicationInfo app,
-            in CompatibilityInfo compatInfo) = 31;
-    void scheduleOnNewActivityOptions(IBinder token, in Bundle options) = 32;
-    void scheduleSuicide() = 33;
-    void dispatchPackageBroadcast(int cmd, in String[] packages) = 34;
-    void scheduleCrash(in String msg) = 35;
-    void dumpHeap(boolean managed, in String path, in ParcelFileDescriptor fd) = 36;
+            in CompatibilityInfo compatInfo) = 30;
+    void scheduleOnNewActivityOptions(IBinder token, in Bundle options) = 31;
+    void scheduleSuicide() = 32;
+    void dispatchPackageBroadcast(int cmd, in String[] packages) = 33;
+    void scheduleCrash(in String msg) = 34;
+    void dumpHeap(boolean managed, in String path, in ParcelFileDescriptor fd) = 35;
     void dumpActivity(in ParcelFileDescriptor fd, IBinder servicetoken, in String prefix,
-            in String[] args) = 37;
-    void clearDnsCache() = 38;
+            in String[] args) = 36;
+    void clearDnsCache() = 37;
     void setHttpProxy(in String proxy, in String port, in String exclList,
-            in Uri pacFileUrl) = 39;
-    void setCoreSettings(in Bundle coreSettings) = 40;
-    void updatePackageCompatibilityInfo(in String pkg, in CompatibilityInfo info) = 41;
-    void scheduleTrimMemory(int level) = 42;
+            in Uri pacFileUrl) = 38;
+    void setCoreSettings(in Bundle coreSettings) = 39;
+    void updatePackageCompatibilityInfo(in String pkg, in CompatibilityInfo info) = 40;
+    void scheduleTrimMemory(int level) = 41;
     void dumpMemInfo(in ParcelFileDescriptor fd, in Debug.MemoryInfo mem, boolean checkin,
             boolean dumpInfo, boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable,
-            in String[] args) = 43;
-    void dumpGfxInfo(in ParcelFileDescriptor fd, in String[] args) = 44;
+            in String[] args) = 42;
+    void dumpGfxInfo(in ParcelFileDescriptor fd, in String[] args) = 43;
     void dumpProvider(in ParcelFileDescriptor fd, IBinder servicetoken,
-            in String[] args) = 45;
-    void dumpDbInfo(in ParcelFileDescriptor fd, in String[] args) = 46;
-    void unstableProviderDied(IBinder provider) = 47;
+            in String[] args) = 44;
+    void dumpDbInfo(in ParcelFileDescriptor fd, in String[] args) = 45;
+    void unstableProviderDied(IBinder provider) = 46;
     void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
-            int requestType, int sessionId) = 48;
-    void scheduleTranslucentConversionComplete(IBinder token, boolean timeout) = 49;
-    void setProcessState(int state) = 50;
-    void scheduleInstallProvider(in ProviderInfo provider) = 51;
-    void updateTimePrefs(boolean is24Hour) = 52;
-    void scheduleCancelVisibleBehind(IBinder token) = 53;
-    void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled) = 54;
-    void scheduleEnterAnimationComplete(IBinder token) = 55;
-    void notifyCleartextNetwork(in byte[] firstPacket) = 56;
-    void startBinderTracking() = 57;
-    void stopBinderTrackingAndDump(in ParcelFileDescriptor fd) = 58;
-    void scheduleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode) = 59;
+            int requestType, int sessionId) = 47;
+    void scheduleTranslucentConversionComplete(IBinder token, boolean timeout) = 48;
+    void setProcessState(int state) = 49;
+    void scheduleInstallProvider(in ProviderInfo provider) = 50;
+    void updateTimePrefs(boolean is24Hour) = 51;
+    void scheduleCancelVisibleBehind(IBinder token) = 52;
+    void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled) = 53;
+    void scheduleEnterAnimationComplete(IBinder token) = 54;
+    void notifyCleartextNetwork(in byte[] firstPacket) = 55;
+    void startBinderTracking() = 56;
+    void stopBinderTrackingAndDump(in ParcelFileDescriptor fd) = 57;
+    void scheduleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode) = 58;
     void schedulePictureInPictureModeChanged(IBinder token,
-            boolean isInPictureInPictureMode) = 60;
+            boolean isInPictureInPictureMode) = 59;
     void scheduleLocalVoiceInteractionStarted(IBinder token,
-            IVoiceInteractor voiceInteractor) = 61;
-    void handleTrustStorageUpdate() = 62;
+            IVoiceInteractor voiceInteractor) = 60;
+    void handleTrustStorageUpdate() = 61;
+    void attachAgent(String path) = 62;
     /**
      * 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/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index c87eef9..ee81c58 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -59,7 +59,6 @@
     int getPackageImportance(String pkg);
 
     void createNotificationChannel(String pkg, in NotificationChannel channel);
-    void updateNotificationChannel(String pkg, in NotificationChannel channel);
     void updateNotificationChannelForPackage(String pkg, int uid, in NotificationChannel channel);
     NotificationChannel getNotificationChannel(String pkg, String channelId);
     NotificationChannel getNotificationChannelForPackage(String pkg, int uid, String channelId);
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/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 4150172..f259c6d 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -1,3 +1,18 @@
+/*
+ * 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 org.json.JSONException;
@@ -33,12 +48,45 @@
     private static final String ATT_IMPORTANCE = "importance";
     private static final String ATT_LIGHTS = "lights";
     private static final String ATT_VIBRATION = "vibration";
-    private static final String ATT_DEFAULT_RINGTONE = "ringtone";
+    private static final String ATT_RINGTONE = "ringtone";
+    private static final String ATT_USER_APPROVED = "approved";
+    private static final String ATT_USER_LOCKED = "locked";
+
+    /**
+     * @hide
+     */
+    @SystemApi
+    public static final int USER_LOCKED_PRIORITY = 0x00000001;
+    /**
+     * @hide
+     */
+    @SystemApi
+    public static final int USER_LOCKED_VISIBILITY = 0x00000002;
+    /**
+     * @hide
+     */
+    @SystemApi
+    public static final int USER_LOCKED_IMPORTANCE = 0x00000004;
+    /**
+     * @hide
+     */
+    @SystemApi
+    public static final int USER_LOCKED_LIGHTS = 0x00000008;
+    /**
+     * @hide
+     */
+    @SystemApi
+    public static final int USER_LOCKED_VIBRATION = 0x00000010;
+    /**
+     * @hide
+     */
+    @SystemApi
+    public static final int USER_LOCKED_RINGTONE = 0x00000020;
 
     private static final int DEFAULT_VISIBILITY =
-            NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
+            NotificationManager.VISIBILITY_NO_OVERRIDE;
     private static final int DEFAULT_IMPORTANCE =
-            NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
+            NotificationManager.IMPORTANCE_UNSPECIFIED;
 
     private final String mId;
     private CharSequence mName;
@@ -48,16 +96,21 @@
     private Uri mRingtone;
     private boolean mLights;
     private boolean mVibration;
+    private int mUserLockedFields;
 
     /**
      * Creates a notification channel.
      *
      * @param id The id of the channel. Must be unique per package.
      * @param name The user visible name of the channel.
+     * @param importance The importance of the channel. This controls how interruptive notifications
+     *                   posted to this channel are. See e.g.
+     *                   {@link NotificationManager#IMPORTANCE_DEFAULT}.
      */
-    public NotificationChannel(String id, CharSequence name) {
+    public NotificationChannel(String id, CharSequence name, int importance) {
         this.mId = id;
         this.mName = name;
+        this.mImportance = importance;
     }
 
     protected NotificationChannel(Parcel in) {
@@ -77,6 +130,7 @@
         }
         mLights = in.readByte() != 0;
         mVibration = in.readByte() != 0;
+        mUserLockedFields = in.readInt();
     }
 
     @Override
@@ -99,54 +153,67 @@
         }
         dest.writeByte(mLights ? (byte) 1 : (byte) 0);
         dest.writeByte(mVibration ? (byte) 1 : (byte) 0);
-    }
-
-    // Only modifiable by users.
-    /**
-     * @hide
-     */
-    @SystemApi
-    public void setName(CharSequence name) {
-        this.mName = name;
+        dest.writeInt(mUserLockedFields);
     }
 
     /**
      * @hide
      */
     @SystemApi
-    public void setImportance(int importance) {
-        this.mImportance = importance;
+    public void lockFields(int field) {
+        mUserLockedFields |= field;
     }
 
+    // Modifiable by a notification ranker.
+
     /**
-     * @hide
+     * Only modifiable by the system and notification ranker.
+     *
+     * Sets whether or not this notification can interrupt the user in
+     * {@link android.app.NotificationManager.Policy#INTERRUPTION_FILTER_PRIORITY} mode.
      */
-    @SystemApi
     public void setBypassDnd(boolean bypassDnd) {
         this.mBypassDnd = bypassDnd;
     }
 
     /**
-     * @hide
+     * Only modifiable by the system and notification ranker.
+     *
+     * Sets whether this notification appears on the lockscreen or not, and if so, whether it
+     * appears in a redacted form. See e.g. {@link Notification#VISIBILITY_SECRET}.
      */
-    @SystemApi
     public void setLockscreenVisibility(int lockscreenVisibility) {
         this.mLockscreenVisibility = lockscreenVisibility;
     }
 
+    /**
+     * Only modifiable by the system and notification ranker.
+     *
+     * Sets the level of interruption of this notification channel.
+     *
+     * @param importance the amount the user should be interrupted by notifications from this
+     *                   channel. See e.g.
+     *                   {@link android.app.NotificationManager#IMPORTANCE_DEFAULT}.
+     */
+    public void setImportance(int importance) {
+        this.mImportance = importance;
+    }
+
     // Modifiable by apps on channel creation.
 
     /**
      * Sets the ringtone that should be played for notifications posted to this channel if
-     * the notifications don't supply a ringtone. Only modifiable on channel creation.
+     * the notifications don't supply a ringtone. Only modifiable before the channel is submitted
+     * to the NotificationManager.
      */
-    public void setDefaultRingtone(Uri defaultRingtone) {
-        this.mRingtone = defaultRingtone;
+    public void setRingtone(Uri ringtone) {
+        this.mRingtone = ringtone;
     }
 
     /**
      * Sets whether notifications posted to this channel should display notification lights,
-     * on devices that support that feature. Only modifiable on channel creation.
+     * on devices that support that feature. Only modifiable before the channel is submitted to
+     * the NotificationManager.
      */
     public void setLights(boolean lights) {
         this.mLights = lights;
@@ -154,7 +221,8 @@
 
     /**
      * Sets whether notification posted to this channel should vibrate, even if individual
-     * notifications are marked as having vibration only modifiable on channel creation.
+     * notifications are marked as having vibration only modifiable before the channel is submitted
+     * to the NotificationManager.
      */
     public void setVibration(boolean vibration) {
         this.mVibration = vibration;
@@ -193,7 +261,7 @@
     /**
      * Returns the notification sound for this channel.
      */
-    public Uri getDefaultRingtone() {
+    public Uri getRingtone() {
         return mRingtone;
     }
 
@@ -212,9 +280,9 @@
     }
 
     /**
-     * @hide
+     * Returns whether or not notifications posted to this channel are shown on the lockscreen in
+     * full or redacted form.
      */
-    @SystemApi
     public int getLockscreenVisibility() {
         return mLockscreenVisibility;
     }
@@ -223,15 +291,23 @@
      * @hide
      */
     @SystemApi
+    public int getUserLockedFields() {
+        return mUserLockedFields;
+    }
+
+    /**
+     * @hide
+     */
+    @SystemApi
     public void populateFromXml(XmlPullParser parser) {
-        // Name and id are set in the constructor.
-        setImportance(safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE));
+        // Name, id, and importance are set in the constructor.
         setBypassDnd(Notification.PRIORITY_DEFAULT
                 != safeInt(parser, ATT_PRIORITY, Notification.PRIORITY_DEFAULT));
         setLockscreenVisibility(safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY));
-        setDefaultRingtone(safeUri(parser, ATT_DEFAULT_RINGTONE));
+        setRingtone(safeUri(parser, ATT_RINGTONE));
         setLights(safeBool(parser, ATT_LIGHTS, false));
         setVibration(safeBool(parser, ATT_VIBRATION, false));
+        lockFields(safeInt(parser, ATT_USER_LOCKED, 0));
     }
 
     /**
@@ -254,8 +330,8 @@
             out.attribute(null, ATT_VISIBILITY,
                     Integer.toString(getLockscreenVisibility()));
         }
-        if (getDefaultRingtone() != null) {
-            out.attribute(null, ATT_DEFAULT_RINGTONE, getDefaultRingtone().toString());
+        if (getRingtone() != null) {
+            out.attribute(null, ATT_RINGTONE, getRingtone().toString());
         }
         if (shouldShowLights()) {
             out.attribute(null, ATT_LIGHTS, Boolean.toString(shouldShowLights()));
@@ -263,6 +339,10 @@
         if (shouldVibrate()) {
             out.attribute(null, ATT_VIBRATION, Boolean.toString(shouldVibrate()));
         }
+        if (getUserLockedFields() != 0) {
+            out.attribute(null, ATT_USER_LOCKED, Integer.toString(getUserLockedFields()));
+        }
+
         out.endTag(null, TAG_CHANNEL);
     }
 
@@ -284,11 +364,12 @@
         if (getLockscreenVisibility() != DEFAULT_VISIBILITY) {
             record.put(ATT_VISIBILITY, Notification.visibilityToString(getLockscreenVisibility()));
         }
-        if (getDefaultRingtone() != null) {
-            record.put(ATT_DEFAULT_RINGTONE, getDefaultRingtone().toString());
+        if (getRingtone() != null) {
+            record.put(ATT_RINGTONE, getRingtone().toString());
         }
         record.put(ATT_LIGHTS, Boolean.toString(shouldShowLights()));
         record.put(ATT_VIBRATION, Boolean.toString(shouldVibrate()));
+        record.put(ATT_USER_LOCKED, Integer.toString(getUserLockedFields()));
 
         return record;
     }
@@ -342,15 +423,32 @@
 
         NotificationChannel that = (NotificationChannel) o;
 
-        if (mImportance != that.mImportance) return false;
+        if (getImportance() != that.getImportance()) return false;
         if (mBypassDnd != that.mBypassDnd) return false;
-        if (mLockscreenVisibility != that.mLockscreenVisibility) return false;
+        if (getLockscreenVisibility() != that.getLockscreenVisibility()) return false;
         if (mLights != that.mLights) return false;
         if (mVibration != that.mVibration) return false;
-        if (!mId.equals(that.mId)) return false;
-        if (mName != null ? !mName.equals(that.mName) : that.mName != null) return false;
-        return mRingtone != null ? mRingtone.equals(
-                that.mRingtone) : that.mRingtone == null;
+        if (getUserLockedFields() != that.getUserLockedFields()) return false;
+        if (getId() != null ? !getId().equals(that.getId()) : that.getId() != null) return false;
+        if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null)
+            return false;
+        return getRingtone() != null ? getRingtone().equals(
+                that.getRingtone()) : that.getRingtone() == null;
+
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getId() != null ? getId().hashCode() : 0;
+        result = 31 * result + (getName() != null ? getName().hashCode() : 0);
+        result = 31 * result + getImportance();
+        result = 31 * result + (mBypassDnd ? 1 : 0);
+        result = 31 * result + getLockscreenVisibility();
+        result = 31 * result + (getRingtone() != null ? getRingtone().hashCode() : 0);
+        result = 31 * result + (mLights ? 1 : 0);
+        result = 31 * result + (mVibration ? 1 : 0);
+        result = 31 * result + getUserLockedFields();
+        return result;
     }
 
     @Override
@@ -361,22 +459,10 @@
                 ", mImportance=" + mImportance +
                 ", mBypassDnd=" + mBypassDnd +
                 ", mLockscreenVisibility=" + mLockscreenVisibility +
-                ", mRingtone='" + mRingtone + '\'' +
+                ", mRingtone=" + mRingtone +
                 ", mLights=" + mLights +
                 ", mVibration=" + mVibration +
+                ", mUserLockedFields=" + mUserLockedFields +
                 '}';
     }
-
-    @Override
-    public int hashCode() {
-        int result = mId.hashCode();
-        result = 31 * result + (mName != null ? mName.hashCode() : 0);
-        result = 31 * result + mImportance;
-        result = 31 * result + (mBypassDnd ? 1 : 0);
-        result = 31 * result + mLockscreenVisibility;
-        result = 31 * result + (mRingtone != null ? mRingtone.hashCode() : 0);
-        result = 31 * result + (mLights ? 1 : 0);
-        result = 31 * result + (mVibration ? 1 : 0);
-        return result;
-    }
 }
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 39cd2b5..2234a38 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -181,15 +181,15 @@
     public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
 
     /** @hide */
-    @IntDef({VISIBILITY_NO_OVERRIDE, IMPORTANCE_UNSPECIFIED, IMPORTANCE_NONE,
-            IMPORTANCE_MIN, IMPORTANCE_LOW, IMPORTANCE_DEFAULT, IMPORTANCE_HIGH,
-            IMPORTANCE_MAX})
+    @IntDef({IMPORTANCE_UNSPECIFIED, IMPORTANCE_NONE,
+            IMPORTANCE_MIN, IMPORTANCE_LOW, IMPORTANCE_DEFAULT, IMPORTANCE_HIGH})
     @Retention(RetentionPolicy.SOURCE)
     public @interface Importance {}
 
     /** Value signifying that the user has not expressed a per-app visibility override value.
      * @hide */
     public static final int VISIBILITY_NO_OVERRIDE = -1000;
+
     /**
      * Value signifying that the user has not expressed an importance.
      *
@@ -214,19 +214,19 @@
     public static final int IMPORTANCE_LOW = 2;
 
     /**
-     * Default notification importance: shows everywhere, allowed to makes noise,
-     * but does not visually intrude.
+     * Default notification importance: shows everywhere, makes noise, but does not visually
+     * intrude.
      */
     public static final int IMPORTANCE_DEFAULT = 3;
 
     /**
-     * Higher notification importance: shows everywhere, allowed to makes noise and peek.
+     * Higher notification importance: shows everywhere, makes noise and peeks. May use full screen
+     * intents.
      */
     public static final int IMPORTANCE_HIGH = 4;
 
     /**
-     * Highest notification importance: shows everywhere, allowed to makes noise, peek, and
-     * use full screen intents.
+     * Unused.
      */
     public static final int IMPORTANCE_MAX = 5;
 
@@ -402,7 +402,7 @@
     }
 
     /**
-     * Returns all notification channels created by the calling app.
+     * Returns all notification channels belonging to the calling app.
      */
     public List<NotificationChannel> getNotificationChannels() {
         INotificationManager service = getService();
@@ -414,18 +414,6 @@
     }
 
     /**
-     * Updates settings for a given channel.
-     */
-    public void updateNotificationChannel(NotificationChannel channel) {
-        INotificationManager service = getService();
-        try {
-            service.updateNotificationChannel(mContext.getPackageName(), channel);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Deletes the given notification channel.
      */
     public void deleteNotificationChannel(String channelId) {
diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java
index 70007f5..af55788 100644
--- a/core/java/android/app/Presentation.java
+++ b/core/java/android/app/Presentation.java
@@ -16,13 +16,21 @@
 
 package android.app;
 
+import static android.content.Context.DISPLAY_SERVICE;
+import static android.content.Context.WINDOW_SERVICE;
+import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
+
 import android.content.Context;
 import android.content.res.Resources;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
+import android.os.Binder;
+import android.os.IBinder;
 import android.view.ContextThemeWrapper;
 import android.view.Display;
 import android.view.Gravity;
+import android.view.Window;
+import android.view.WindowManager;
 import android.view.WindowManagerImpl;
 import android.os.Handler;
 import android.os.Message;
@@ -145,6 +153,7 @@
 
     private final Display mDisplay;
     private final DisplayManager mDisplayManager;
+    private final IBinder mToken = new Binder();
 
     /**
      * Creates a new presentation that is attached to the specified display
@@ -177,9 +186,14 @@
         super(createPresentationContext(outerContext, display, theme), theme, false);
 
         mDisplay = display;
-        mDisplayManager = (DisplayManager)getContext().getSystemService(Context.DISPLAY_SERVICE);
+        mDisplayManager = (DisplayManager)getContext().getSystemService(DISPLAY_SERVICE);
 
-        getWindow().setGravity(Gravity.FILL);
+        final Window w = getWindow();
+        final WindowManager.LayoutParams attr = w.getAttributes();
+        attr.token = mToken;
+        w.setAttributes(attr);
+        w.setGravity(Gravity.FILL);
+        w.setType(TYPE_PRESENTATION);
         setCanceledOnTouchOutside(false);
     }
 
@@ -308,13 +322,13 @@
         // such as the parent window, which is important if the presentation uses
         // an application window type.
         final WindowManagerImpl outerWindowManager =
-                (WindowManagerImpl)outerContext.getSystemService(Context.WINDOW_SERVICE);
+                (WindowManagerImpl)outerContext.getSystemService(WINDOW_SERVICE);
         final WindowManagerImpl displayWindowManager =
                 outerWindowManager.createPresentationWindowManager(displayContext);
         return new ContextThemeWrapper(displayContext, theme) {
             @Override
             public Object getSystemService(String name) {
-                if (Context.WINDOW_SERVICE.equals(name)) {
+                if (WINDOW_SERVICE.equals(name)) {
                     return displayWindowManager;
                 }
                 return super.getSystemService(name);
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 2d46495..f38c0d8 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -81,8 +81,8 @@
 import android.net.wifi.RttManager;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiScanner;
-import android.net.wifi.nan.IWifiNanManager;
-import android.net.wifi.nan.WifiNanManager;
+import android.net.wifi.aware.IWifiAwareManager;
+import android.net.wifi.aware.WifiAwareManager;
 import android.net.wifi.p2p.IWifiP2pManager;
 import android.net.wifi.p2p.WifiP2pManager;
 import android.nfc.NfcManager;
@@ -510,16 +510,16 @@
                 return new WifiP2pManager(service);
             }});
 
-        registerService(Context.WIFI_NAN_SERVICE, WifiNanManager.class,
-                new CachedServiceFetcher<WifiNanManager>() {
+        registerService(Context.WIFI_AWARE_SERVICE, WifiAwareManager.class,
+                new CachedServiceFetcher<WifiAwareManager>() {
             @Override
-            public WifiNanManager createService(ContextImpl ctx) throws ServiceNotFoundException {
-                IBinder b = ServiceManager.getService(Context.WIFI_NAN_SERVICE);
-                IWifiNanManager service = IWifiNanManager.Stub.asInterface(b);
+            public WifiAwareManager createService(ContextImpl ctx) throws ServiceNotFoundException {
+                IBinder b = ServiceManager.getService(Context.WIFI_AWARE_SERVICE);
+                IWifiAwareManager service = IWifiAwareManager.Stub.asInterface(b);
                 if (service == null) {
                     return null;
                 }
-                return new WifiNanManager(ctx.getOuterContext(), service);
+                return new WifiAwareManager(ctx.getOuterContext(), service);
             }});
 
         registerService(Context.WIFI_SCANNING_SERVICE, WifiScanner.class,
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/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/core/java/android/app/WaitResult.aidl
similarity index 90%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to core/java/android/app/WaitResult.aidl
index 5f66d16..22a6558 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/core/java/android/app/WaitResult.aidl
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.app;
 
-parcelable PublishConfig;
+/** @hide */
+parcelable WaitResult;
\ No newline at end of file
diff --git a/core/java/android/app/WaitResult.java b/core/java/android/app/WaitResult.java
new file mode 100644
index 0000000..af196cf
--- /dev/null
+++ b/core/java/android/app/WaitResult.java
@@ -0,0 +1,72 @@
+/*
+ * 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.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information returned after waiting for an activity start.
+ *
+ * @hide
+ */
+public class WaitResult implements Parcelable {
+    public int result;
+    public boolean timeout;
+    public ComponentName who;
+    public long thisTime;
+    public long totalTime;
+
+    public WaitResult() {
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(result);
+        dest.writeInt(timeout ? 1 : 0);
+        ComponentName.writeToParcel(who, dest);
+        dest.writeLong(thisTime);
+        dest.writeLong(totalTime);
+    }
+
+    public static final Parcelable.Creator<WaitResult> CREATOR
+            = new Parcelable.Creator<WaitResult>() {
+        @Override
+        public WaitResult createFromParcel(Parcel source) {
+            return new WaitResult(source);
+        }
+
+        @Override
+        public WaitResult[] newArray(int size) {
+            return new WaitResult[size];
+        }
+    };
+
+    private WaitResult(Parcel source) {
+        result = source.readInt();
+        timeout = source.readInt() != 0;
+        who = ComponentName.readFromParcel(source);
+        thisTime = source.readLong();
+        totalTime = source.readLong();
+    }
+}
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/core/java/android/app/admin/ConnectEvent.aidl
similarity index 89%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to core/java/android/app/admin/ConnectEvent.aidl
index 5f66d16..bab40f5 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/core/java/android/app/admin/ConnectEvent.aidl
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.app.admin;
 
-parcelable PublishConfig;
+/** {@hide} */
+parcelable ConnectEvent;
+
diff --git a/core/java/android/app/admin/ConnectEvent.java b/core/java/android/app/admin/ConnectEvent.java
new file mode 100644
index 0000000..e05feaf
--- /dev/null
+++ b/core/java/android/app/admin/ConnectEvent.java
@@ -0,0 +1,87 @@
+/*
+ * 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.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class that represents a connect library call event.
+ * @hide
+ */
+public final class ConnectEvent extends NetworkEvent implements Parcelable {
+
+    /** The destination IP address. */
+    private final String ipAddress;
+
+    /** The destination port number. */
+    private final int port;
+
+    public ConnectEvent(String ipAddress, int port, String packageName, long timestamp) {
+        super(packageName, timestamp);
+        this.ipAddress = ipAddress;
+        this.port = port;
+    }
+
+    private ConnectEvent(Parcel in) {
+        this.ipAddress = in.readString();
+        this.port = in.readInt();
+        this.packageName = in.readString();
+        this.timestamp = in.readLong();
+    }
+
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("ConnectEvent(%s, %d, %d, %s)", ipAddress, port, timestamp,
+                packageName);
+    }
+
+    public static final Parcelable.Creator<ConnectEvent> CREATOR
+            = new Parcelable.Creator<ConnectEvent>() {
+        @Override
+        public ConnectEvent createFromParcel(Parcel in) {
+            if (in.readInt() != PARCEL_TOKEN_CONNECT_EVENT) {
+                return null;
+            }
+            return new ConnectEvent(in);
+        }
+
+        @Override
+        public ConnectEvent[] newArray(int size) {
+            return new ConnectEvent[size];
+        }
+    };
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        // write parcel token first
+        out.writeInt(PARCEL_TOKEN_CONNECT_EVENT);
+        out.writeString(ipAddress);
+        out.writeInt(port);
+        out.writeString(packageName);
+        out.writeLong(timestamp);
+    }
+}
+
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index dd70b5d..360087c 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -276,6 +276,15 @@
             = "android.app.action.SECURITY_LOGS_AVAILABLE";
 
     /**
+     * Broadcast action: notify that a new batch of network logs is ready to be collected.
+     * @see DeviceAdminReceiver#onNetworkLogsAvailable
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_NETWORK_LOGS_AVAILABLE
+            = "android.app.action.NETWORK_LOGS_AVAILABLE";
+
+    /**
      * A string containing the SHA-256 hash of the bugreport file.
      *
      * @see #ACTION_BUGREPORT_SHARE
@@ -635,6 +644,22 @@
     }
 
     /**
+     * Called when a new batch of network logs can be retrieved. This callback method will only ever
+     * be called when network logging is enabled. The logs can only be retrieved while network
+     * logging is enabled.
+     *
+     * <p>This callback is only applicable to device owners.
+     *
+     * @param context The running context as per {@link #onReceive}.
+     * @param intent The received intent as per {@link #onReceive}.
+     * @see DevicePolicyManager#retrieveNetworkLogs(ComponentName)
+     *
+     * @hide
+     */
+    public void onNetworkLogsAvailable(Context context, Intent intent) {
+    }
+
+    /**
      * Intercept standard device administrator broadcasts.  Implementations
      * should not override this method; it is better to implement the
      * convenience callbacks for each action.
@@ -688,6 +713,8 @@
             onBugreportFailed(context, intent, failureCode);
         } else if (ACTION_SECURITY_LOGS_AVAILABLE.equals(action)) {
             onSecurityLogsAvailable(context, intent);
+        } else if (ACTION_NETWORK_LOGS_AVAILABLE.equals(action)) {
+            onNetworkLogsAvailable(context, intent);
         }
     }
 }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 9ce9dec..538e52b 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.NetworkEvent;
 import android.app.admin.PasswordMetrics;
 import android.app.admin.SecurityLog.SecurityEvent;
 import android.content.ComponentName;
@@ -1056,6 +1057,7 @@
      *         otherwise
      */
     public boolean isAdminActive(@NonNull ComponentName admin) {
+        throwIfParentInstance("isAdminActive");
         return isAdminActiveAsUser(admin, myUserId());
     }
 
@@ -1095,7 +1097,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());
     }
@@ -1104,7 +1106,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);
@@ -2500,7 +2502,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) {
@@ -2584,7 +2586,7 @@
      *         if no admin has set the proxy.
      * @hide
      */
-    public ComponentName getGlobalProxyAdmin() {
+    public @Nullable ComponentName getGlobalProxyAdmin() {
         if (mService != null) {
             try {
                 return mService.getGlobalProxyAdmin(myUserId());
@@ -2894,8 +2896,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 {
@@ -3108,7 +3110,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 {
@@ -3177,7 +3180,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 {
@@ -3798,7 +3801,7 @@
      * @hide
      */
     @SystemApi
-    public String getDeviceOwner() {
+    public @Nullable String getDeviceOwner() {
         throwIfParentInstance("getDeviceOwner");
         final ComponentName name = getDeviceOwnerComponentOnCallingUser();
         return name != null ? name.getPackageName() : null;
@@ -3843,7 +3846,7 @@
      */
     @Deprecated
     @SystemApi
-    public String getDeviceInitializerApp() {
+    public @Nullable String getDeviceInitializerApp() {
         return null;
     }
 
@@ -3854,7 +3857,7 @@
      */
     @Deprecated
     @SystemApi
-    public ComponentName getDeviceInitializerComponent() {
+    public @Nullable ComponentName getDeviceInitializerComponent() {
         return null;
     }
 
@@ -4020,8 +4023,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 {
@@ -4128,7 +4131,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());
     }
@@ -4137,7 +4140,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);
@@ -4154,7 +4158,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());
@@ -4173,7 +4177,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 {
@@ -4278,7 +4282,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 {
@@ -4416,14 +4421,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,
@@ -4738,7 +4743,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 {
@@ -4786,7 +4791,7 @@
      * @hide
      */
      @SystemApi
-     public List<String> getPermittedAccessibilityServices(int userId) {
+     public @Nullable List<String> getPermittedAccessibilityServices(int userId) {
         throwIfParentInstance("getPermittedAccessibilityServices");
         if (mService != null) {
             try {
@@ -4840,7 +4845,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 {
@@ -4886,7 +4891,7 @@
      * @hide
      */
     @SystemApi
-    public List<String> getPermittedInputMethodsForCurrentUser() {
+    public @Nullable List<String> getPermittedInputMethodsForCurrentUser() {
         throwIfParentInstance("getPermittedInputMethodsForCurrentUser");
         if (mService != null) {
             try {
@@ -4907,7 +4912,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 {
@@ -4959,7 +4964,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;
     }
 
@@ -4992,7 +4997,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;
     }
@@ -5037,7 +5042,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");
@@ -5104,7 +5110,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 {
@@ -5171,7 +5178,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) {
@@ -5311,7 +5318,7 @@
      *
      * @see #setAccountManagementDisabled
      */
-    public String[] getAccountTypesWithManagementDisabled() {
+    public @Nullable String[] getAccountTypesWithManagementDisabled() {
         throwIfParentInstance("getAccountTypesWithManagementDisabled");
         return getAccountTypesWithManagementDisabledAsUser(myUserId());
     }
@@ -5320,7 +5327,7 @@
      * @see #getAccountTypesWithManagementDisabled()
      * @hide
      */
-    public String[] getAccountTypesWithManagementDisabledAsUser(int userId) {
+    public @Nullable String[] getAccountTypesWithManagementDisabledAsUser(int userId) {
         if (mService != null) {
             try {
                 return mService.getAccountTypesWithManagementDisabledAsUser(userId);
@@ -5366,7 +5373,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 {
@@ -5651,7 +5658,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 {
@@ -5709,7 +5716,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 {
@@ -5948,7 +5955,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);
@@ -6057,7 +6064,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 {
@@ -6078,7 +6085,7 @@
      *
      * @hide
      */
-    public CharSequence getShortSupportMessageForUser(@NonNull ComponentName admin,
+    public @Nullable CharSequence getShortSupportMessageForUser(@NonNull ComponentName admin,
             int userHandle) {
         if (mService != null) {
             try {
@@ -6100,7 +6107,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);
@@ -6139,6 +6147,7 @@
      * <li>{@link #getPasswordExpirationTimeout}</li>
      * <li>{@link #setPasswordExpirationTimeout}</li>
      * <li>{@link #getPasswordExpiration}</li>
+     * <li>{@link #getPasswordMaximumLength}</li>
      * <li>{@link #isActivePasswordSufficient}</li>
      * <li>{@link #getCurrentFailedPasswordAttempts}</li>
      * <li>{@link #getMaximumFailedPasswordsForWipe}</li>
@@ -6155,7 +6164,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)) {
@@ -6225,7 +6234,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);
@@ -6246,7 +6255,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()) {
@@ -6272,7 +6281,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);
@@ -6391,7 +6401,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);
@@ -6408,7 +6418,7 @@
      *
      * @hide
      */
-    public CharSequence getOrganizationNameForUser(int userHandle) {
+    public @Nullable CharSequence getOrganizationNameForUser(int userHandle) {
         try {
             return mService.getOrganizationNameForUser(userHandle);
         } catch (RemoteException re) {
@@ -6628,4 +6638,74 @@
             throw re.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Called by a device owner to control the network logging feature. Logging can only be
+     * enabled on single user devices where the sole user is managed by the device owner. If a new
+     * user is added on the device, logging is disabled.
+     *
+     * <p> Network logs contain DNS lookup and connect() library call events.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param enabled whether network logging should be enabled or not.
+     * @throws {@link SecurityException} if {@code admin} is not a device owner.
+     * @throws {@link RemoteException} if network logging could not be enabled or disabled due to
+     *         the logging service not being available
+     * @see #retrieveNetworkLogs
+     *
+     * @hide
+     */
+    public void setNetworkLoggingEnabled(@NonNull ComponentName admin, boolean enabled) {
+        throwIfParentInstance("setNetworkLoggingEnabled");
+        try {
+            mService.setNetworkLoggingEnabled(admin, enabled);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return whether network logging is enabled by a device owner.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @return {@code true} if network logging is enabled by device owner, {@code false} otherwise.
+     * @throws {@link SecurityException} if {@code admin} is not a device owner.
+     *
+     * @hide
+     */
+    public boolean isNetworkLoggingEnabled(@NonNull ComponentName admin) {
+        throwIfParentInstance("isNetworkLoggingEnabled");
+        try {
+            return mService.isNetworkLoggingEnabled(admin);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Called by device owner to retrieve a new batch of network logging events.
+     *
+     * <p> {@link NetworkEvent} can be one of {@link DnsEvent} or {@link ConnectEvent}.
+     *
+     * <p> The list of network events is sorted chronologically, and contains at most 1200 events.
+     *
+     * <p> Access to the logs is rate limited and this method will only return a new batch of logs
+     * after the device device owner has been notified via
+     * {@link DeviceAdminReceiver#onNetworkLogsAvailable}.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @return A new batch of network logs which is a list of {@link NetworkEvent}. Returns
+     * {@code null} if there's no batch currently awaiting for retrieval or if logging is disabled.
+     * @throws {@link SecurityException} if {@code admin} is not a device owner.
+     *
+     * @hide
+     */
+    public List<NetworkEvent> retrieveNetworkLogs(@NonNull ComponentName admin) {
+        throwIfParentInstance("retrieveNetworkLogs");
+        try {
+            return mService.retrieveNetworkLogs(admin);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/core/java/android/app/admin/DnsEvent.aidl
similarity index 89%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to core/java/android/app/admin/DnsEvent.aidl
index 5f66d16..6da962a 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/core/java/android/app/admin/DnsEvent.aidl
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.app.admin;
 
-parcelable PublishConfig;
+/** {@hide} */
+parcelable DnsEvent;
+
diff --git a/core/java/android/app/admin/DnsEvent.java b/core/java/android/app/admin/DnsEvent.java
new file mode 100644
index 0000000..0ec134a
--- /dev/null
+++ b/core/java/android/app/admin/DnsEvent.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.app.admin;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class that represents a DNS lookup event.
+ * @hide
+ */
+public final class DnsEvent extends NetworkEvent implements Parcelable {
+
+    /** The hostname that was looked up. */
+    private final String hostname;
+
+    /** Contains (possibly a subset of) the IP addresses returned. */
+    private final String[] ipAddresses;
+
+    /**
+     * The number of IP addresses returned from the DNS lookup event. May be different from the
+     * length of ipAddresses if there were too many addresses to log.
+     */
+    private final int ipAddressesCount;
+
+    public DnsEvent(String hostname, String[] ipAddresses, int ipAddressesCount,
+            String packageName, long timestamp) {
+        super(packageName, timestamp);
+        this.hostname = hostname;
+        this.ipAddresses = ipAddresses;
+        this.ipAddressesCount = ipAddressesCount;
+    }
+
+    private DnsEvent(Parcel in) {
+        this.hostname = in.readString();
+        this.ipAddresses = in.createStringArray();
+        this.ipAddressesCount = in.readInt();
+        this.packageName = in.readString();
+        this.timestamp = in.readLong();
+    }
+
+    /** Returns the hostname that was looked up. */
+    public String getHostname() {
+        return hostname;
+    }
+
+    /** Returns (possibly a subset of) the IP addresses returned. */
+    public String[] getIpAddresses() {
+        return ipAddresses;
+    }
+
+    /**
+     * Returns the number of IP addresses returned from the DNS lookup event. May be different from
+     * the length of ipAddresses if there were too many addresses to log.
+     */
+    public int getIpAddressesCount() {
+        return ipAddressesCount;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("DnsEvent(%s, %s, %d, %d, %s)", hostname,
+                (ipAddresses == null) ? "NONE" : String.join(" ", ipAddresses),
+                ipAddressesCount, timestamp, packageName);
+    }
+
+    public static final Parcelable.Creator<DnsEvent> CREATOR
+            = new Parcelable.Creator<DnsEvent>() {
+        @Override
+        public DnsEvent createFromParcel(Parcel in) {
+            if (in.readInt() != PARCEL_TOKEN_DNS_EVENT) {
+                return null;
+            }
+            return new DnsEvent(in);
+        }
+
+        @Override
+        public DnsEvent[] newArray(int size) {
+            return new DnsEvent[size];
+        }
+    };
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        // write parcel token first
+        out.writeInt(PARCEL_TOKEN_DNS_EVENT);
+        out.writeString(hostname);
+        out.writeStringArray(ipAddresses);
+        out.writeInt(ipAddressesCount);
+        out.writeString(packageName);
+        out.writeLong(timestamp);
+    }
+}
+
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 22219d7..b0aec8c 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -17,6 +17,7 @@
 
 package android.app.admin;
 
+import android.app.admin.NetworkEvent;
 import android.app.admin.SystemUpdatePolicy;
 import android.app.admin.PasswordMetrics;
 import android.content.ComponentName;
@@ -314,4 +315,8 @@
 
     void setBackupServiceEnabled(in ComponentName admin, boolean enabled);
     boolean isBackupServiceEnabled(in ComponentName admin);
+
+    void setNetworkLoggingEnabled(in ComponentName admin, boolean enabled);
+    boolean isNetworkLoggingEnabled(in ComponentName admin);
+    List<NetworkEvent> retrieveNetworkLogs(in ComponentName admin);
 }
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/core/java/android/app/admin/NetworkEvent.aidl
similarity index 89%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to core/java/android/app/admin/NetworkEvent.aidl
index 5f66d16..5fa5dbf 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/core/java/android/app/admin/NetworkEvent.aidl
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.app.admin;
 
-parcelable PublishConfig;
+/** {@hide} */
+parcelable NetworkEvent;
+
diff --git a/core/java/android/app/admin/NetworkEvent.java b/core/java/android/app/admin/NetworkEvent.java
new file mode 100644
index 0000000..ec7ed00
--- /dev/null
+++ b/core/java/android/app/admin/NetworkEvent.java
@@ -0,0 +1,85 @@
+/*
+ * 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.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelFormatException;
+
+/**
+ * An abstract class that represents a network event.
+ * @hide
+ */
+public abstract class NetworkEvent implements Parcelable {
+
+    protected static final int PARCEL_TOKEN_DNS_EVENT = 1;
+    protected static final int PARCEL_TOKEN_CONNECT_EVENT = 2;
+
+    /** The package name of the UID that performed the query. */
+    protected String packageName;
+
+    /** The timestamp of the event being reported in milliseconds. */
+    protected long timestamp;
+
+    protected NetworkEvent() {
+        //empty constructor
+    }
+
+    protected NetworkEvent(String packageName, long timestamp) {
+        this.packageName = packageName;
+        this.timestamp = timestamp;
+    }
+
+    /** Returns the package name of the UID that performed the query. */
+    public String getPackageName() {
+        return packageName;
+    }
+
+    /** Returns the timestamp of the event being reported in milliseconds. */
+    public long getTimestamp() {
+        return timestamp;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<NetworkEvent> CREATOR
+            = new Parcelable.Creator<NetworkEvent>() {
+        public NetworkEvent createFromParcel(Parcel in) {
+            final int initialPosition = in.dataPosition();
+            final int parcelToken = in.readInt();
+            // we need to move back to the position from before we read parcelToken
+            in.setDataPosition(initialPosition);
+            switch (parcelToken) {
+                case PARCEL_TOKEN_DNS_EVENT:
+                    return DnsEvent.CREATOR.createFromParcel(in);
+                case PARCEL_TOKEN_CONNECT_EVENT:
+                    return ConnectEvent.CREATOR.createFromParcel(in);
+                default:
+                    throw new ParcelFormatException("Unexpected NetworkEvent token in parcel: "
+                            + parcelToken);
+            }
+        }
+
+        public NetworkEvent[] newArray(int size) {
+            return new NetworkEvent[size];
+        }
+    };
+}
+
diff --git a/core/java/android/app/usage/NetworkStats.java b/core/java/android/app/usage/NetworkStats.java
index 226aa8f..3670b91 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;
@@ -232,6 +256,15 @@
             return tag;
         }
 
+        private static @Metered int convertMetered(int metered) {
+            switch (metered) {
+                case android.net.NetworkStats.METERED_ALL : return METERED_ALL;
+                case android.net.NetworkStats.METERED_NO: return METERED_NO;
+                case android.net.NetworkStats.METERED_YES: return METERED_YES;
+            }
+            return 0;
+        }
+
         private static @Roaming int convertRoaming(int roaming) {
             switch (roaming) {
                 case android.net.NetworkStats.ROAMING_ALL : return ROAMING_ALL;
@@ -279,6 +312,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 +539,7 @@
         bucketOut.mUid = Bucket.convertUid(mRecycledSummaryEntry.uid);
         bucketOut.mTag = Bucket.convertTag(mRecycledSummaryEntry.tag);
         bucketOut.mState = Bucket.convertState(mRecycledSummaryEntry.set);
+        bucketOut.mMetered = Bucket.convertMetered(mRecycledSummaryEntry.metered);
         bucketOut.mRoaming = Bucket.convertRoaming(mRecycledSummaryEntry.roaming);
         bucketOut.mBeginTimeStamp = mStartTimeStamp;
         bucketOut.mEndTimeStamp = mEndTimeStamp;
@@ -539,6 +588,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/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index e805fab..da5aa61 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -52,16 +52,17 @@
  * {@link #querySummaryForUser} <p />
  * {@link #querySummary} <p />
  * These queries aggregate network usage across the whole interval. Therefore there will be only one
- * bucket for a particular key and state and roaming combination. In case of the user-wide and
- * device-wide summaries a single bucket containing the totalised network usage is returned.
+ * bucket for a particular key, state, metered and roaming combination. In case of the user-wide
+ * and device-wide summaries a single bucket containing the totalised network usage is returned.
  * <h3>
  * History queries
  * </h3>
  * {@link #queryDetailsForUid} <p />
  * {@link #queryDetails} <p />
- * These queries do not aggregate over time but do aggregate over state and roaming. Therefore there
- * can be multiple buckets for a particular key but all Bucket's state is going to be
- * {@link NetworkStats.Bucket#STATE_ALL} and all Bucket's roaming is going to be
+ * These queries do not aggregate over time but do aggregate over state, metered and roaming.
+ * Therefore there can be multiple buckets for a particular key but all Bucket's state is going to
+ * be {@link NetworkStats.Bucket#STATE_ALL}, all Bucket's metered is going to be
+ * {@link NetworkStats.Bucket#METERED_ALL}, and all Bucket's roaming is going to be
  * {@link NetworkStats.Bucket#ROAMING_ALL}.
  * <p />
  * <b>NOTE:</b> Calling {@link #querySummaryForDevice} or accessing stats for apps other than the
@@ -104,10 +105,11 @@
 
     /**
      * Query network usage statistics summaries. Result is summarised data usage for the whole
-     * device. Result is a single Bucket aggregated over time, state, uid, tag and roaming. This
-     * means the bucket's start and end timestamp are going to be the same as the 'startTime' and
-     * 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid
-     * {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE}
+     * device. Result is a single Bucket aggregated over time, state, uid, tag, metered, and
+     * roaming. This means the bucket's start and end timestamp are going to be the same as the
+     * 'startTime' and 'endTime' parameters. State is going to be
+     * {@link NetworkStats.Bucket#STATE_ALL}, uid {@link NetworkStats.Bucket#UID_ALL},
+     * tag {@link NetworkStats.Bucket#TAG_NONE}, metered {@link NetworkStats.Bucket#METERED_ALL},
      * and roaming {@link NetworkStats.Bucket#ROAMING_ALL}.
      *
      * @param networkType As defined in {@link ConnectivityManager}, e.g.
@@ -143,8 +145,10 @@
      * Query network usage statistics summaries. Result is summarised data usage for all uids
      * belonging to calling user. Result is a single Bucket aggregated over time, state and uid.
      * This means the bucket's start and end timestamp are going to be the same as the 'startTime'
-     * and 'endTime' parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid
-     * {@link NetworkStats.Bucket#UID_ALL}.
+     * and 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL},
+     * uid {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE},
+     * metered {@link NetworkStats.Bucket#METERED_ALL}, and roaming
+     * {@link NetworkStats.Bucket#ROAMING_ALL}.
      *
      * @param networkType As defined in {@link ConnectivityManager}, e.g.
      *            {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
@@ -178,9 +182,10 @@
     /**
      * Query network usage statistics summaries. Result filtered to include only uids belonging to
      * calling user. Result is aggregated over time, hence all buckets will have the same start and
-     * end timestamps. Not aggregated over state or uid. This means buckets' start and end
-     * timestamps are going to be the same as the 'startTime' and 'endTime' parameters.
-     * State and uid are going to vary, and tag is going to be the same.
+     * end timestamps. State is going to be {@link NetworkStats.Bucket#STATE_ALL},
+     * uid {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE},
+     * metered {@link NetworkStats.Bucket#METERED_ALL}, and roaming
+     * {@link NetworkStats.Bucket#ROAMING_ALL}.
      *
      * @param networkType As defined in {@link ConnectivityManager}, e.g.
      *            {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
@@ -263,10 +268,12 @@
 
     /**
      * Query network usage statistics details. Result filtered to include only uids belonging to
-     * calling user. Result is aggregated over state but not aggregated over time or uid. This means
-     * buckets' start and end timestamps are going to be between 'startTime' and 'endTime'
-     * parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid will vary,
-     * tag {@link NetworkStats.Bucket#TAG_NONE} and roaming is going to be
+     * calling user. Result is aggregated over state but not aggregated over time, uid, tag,
+     * metered, nor roaming. This means buckets' start and end timestamps are going to be between
+     * 'startTime' and 'endTime' parameters. State is going to be
+     * {@link NetworkStats.Bucket#STATE_ALL}, uid will vary,
+     * tag {@link NetworkStats.Bucket#TAG_NONE}, metered is going to be
+     * {@link NetworkStats.Bucket#METERED_ALL}, and roaming is going to be
      * {@link NetworkStats.Bucket#ROAMING_ALL}.
      * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
      * interpolate across partial buckets. Since bucket length is in the order of hours, this
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..bb344a6 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);
@@ -1982,6 +1976,9 @@
         } else if (profile == BluetoothProfile.PBAP_CLIENT) {
             BluetoothPbapClient pbapClient = new BluetoothPbapClient(context, listener);
             return true;
+        } else if (profile == BluetoothProfile.MAP_CLIENT) {
+            BluetoothMapClient mapClient = new BluetoothMapClient(context, listener);
+            return true;
         } else {
             return false;
         }
@@ -2054,6 +2051,10 @@
                 BluetoothPbapClient pbapClient = (BluetoothPbapClient)proxy;
                 pbapClient.close();
                 break;
+            case BluetoothProfile.MAP_CLIENT:
+                BluetoothMapClient mapClient = (BluetoothMapClient)proxy;
+                mapClient.close();
+                break;
         }
     }
 
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 0763149..12ebdac 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -135,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
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/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java
new file mode 100644
index 0000000..4252482
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothMapClient.java
@@ -0,0 +1,415 @@
+/*
+ * 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;
+
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.net.Uri;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class provides the APIs to control the Bluetooth MAP MCE Profile.
+ *
+ * @hide
+ */
+public final class BluetoothMapClient implements BluetoothProfile {
+
+    private static final String TAG = "BluetoothMapClient";
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
+
+    public static final String ACTION_CONNECTION_STATE_CHANGED =
+            "android.bluetooth.mapmce.profile.action.CONNECTION_STATE_CHANGED";
+    public static final String ACTION_MESSAGE_RECEIVED =
+            "android.bluetooth.mapmce.profile.action.MESSAGE_RECEIVED";
+    /* Actions to be used for pending intents */
+    public static final String ACTION_MESSAGE_SENT_SUCCESSFULLY =
+            "android.bluetooth.mapmce.profile.action.MESSAGE_SENT_SUCCESSFULLY";
+    public static final String ACTION_MESSAGE_DELIVERED_SUCCESSFULLY =
+            "android.bluetooth.mapmce.profile.action.MESSAGE_DELIVERED_SUCCESSFULLY";
+
+    private IBluetoothMapClient mService;
+    private final Context mContext;
+    private ServiceListener mServiceListener;
+    private BluetoothAdapter mAdapter;
+
+    /** There was an error trying to obtain the state */
+    public static final int STATE_ERROR = -1;
+
+    public static final int RESULT_FAILURE = 0;
+    public static final int RESULT_SUCCESS = 1;
+    /** Connection canceled before completion. */
+    public static final int RESULT_CANCELED = 2;
+
+    final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+            new IBluetoothStateChangeCallback.Stub() {
+                public void onBluetoothStateChange(boolean up) {
+                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
+                    if (!up) {
+                        if (VDBG) Log.d(TAG, "Unbinding service...");
+                        synchronized (mConnection) {
+                            try {
+                                mService = null;
+                                mContext.unbindService(mConnection);
+                            } catch (Exception re) {
+                                Log.e(TAG, "", re);
+                            }
+                        }
+                    } else {
+                        synchronized (mConnection) {
+                            try {
+                                if (mService == null) {
+                                    if (VDBG) Log.d(TAG, "Binding service...");
+                                    doBind();
+                                }
+                            } catch (Exception re) {
+                                Log.e(TAG, "", re);
+                            }
+                        }
+                    }
+                }
+            };
+
+    /**
+     * Create a BluetoothMapClient proxy object.
+     */
+    /*package*/ BluetoothMapClient(Context context, ServiceListener l) {
+        if (DBG) Log.d(TAG, "Create BluetoothMapClient proxy object");
+        mContext = context;
+        mServiceListener = l;
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (RemoteException e) {
+                Log.e(TAG, "", e);
+            }
+        }
+        doBind();
+    }
+
+    boolean doBind() {
+        Intent intent = new Intent(IBluetoothMapClient.class.getName());
+        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+        intent.setComponent(comp);
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
+            Log.e(TAG, "Could not bind to Bluetooth MAP MCE Service with " + intent);
+            return false;
+        }
+        return true;
+    }
+
+    protected void finalize() throws Throwable {
+        try {
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Close the connection to the backing service.
+     * Other public functions of BluetoothMap will return default error
+     * results once close() has been called. Multiple invocations of close()
+     * are ok.
+     */
+    public void close() {
+        IBluetoothManager mgr = mAdapter.getBluetoothManager();
+        if (mgr != null) {
+            try {
+                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
+            } catch (Exception e) {
+                Log.e(TAG, "", e);
+            }
+        }
+
+        synchronized (mConnection) {
+            if (mService != null) {
+                try {
+                    mService = null;
+                    mContext.unbindService(mConnection);
+                } catch (Exception re) {
+                    Log.e(TAG, "", re);
+                }
+            }
+        }
+        mServiceListener = null;
+    }
+
+    /**
+     * Returns true if the specified Bluetooth device is connected.
+     * Returns false if not connected, or if this proxy object is not
+     * currently connected to the Map service.
+     */
+    public boolean isConnected(BluetoothDevice device) {
+        if (VDBG) Log.d(TAG, "isConnected(" + device + ")");
+        if (mService != null) {
+            try {
+                return mService.isConnected(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+        return false;
+    }
+
+    /**
+     * Initiate connection. Initiation of outgoing connections is not
+     * supported for MAP server.
+     */
+    public boolean connect(BluetoothDevice device) {
+        if (DBG) Log.d(TAG, "connect(" + device + ")" + "for MAPS MCE");
+        if (mService != null) {
+            try {
+                return mService.connect(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
+            }
+        } else {
+            Log.w(TAG, "Proxy not attached to service");
+            if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+        }
+        return false;
+    }
+
+    /**
+     * Initiate disconnect.
+     *
+     * @param device Remote Bluetooth Device
+     * @return false on error, true otherwise
+     */
+    public boolean disconnect(BluetoothDevice device) {
+        if (DBG) Log.d(TAG, "disconnect(" + device + ")");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.disconnect(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Get the list of connected devices. Currently at most one.
+     *
+     * @return list of connected devices
+     */
+    @Override
+    public List<BluetoothDevice> getConnectedDevices() {
+        if (DBG) Log.d(TAG, "getConnectedDevices()");
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.getConnectedDevices();
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return new ArrayList<>();
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return new ArrayList<>();
+    }
+
+    /**
+     * Get the list of devices matching specified states. Currently at most one.
+     *
+     * @return list of matching devices
+     */
+    @Override
+    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+        if (DBG) Log.d(TAG, "getDevicesMatchingStates()");
+        if (mService != null && isEnabled()) {
+            try {
+                return mService.getDevicesMatchingConnectionStates(states);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return new ArrayList<>();
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return new ArrayList<>();
+    }
+
+    /**
+     * Get connection state of device
+     *
+     * @return device connection state
+     */
+    @Override
+    public int getConnectionState(BluetoothDevice device) {
+        if (DBG) Log.d(TAG, "getConnectionState(" + device + ")");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.getConnectionState(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return BluetoothProfile.STATE_DISCONNECTED;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return BluetoothProfile.STATE_DISCONNECTED;
+    }
+
+    /**
+     * Set priority of the profile
+     *
+     * <p> The device should already be paired.  Priority can be one of {@link #PRIORITY_ON} or
+     * {@link #PRIORITY_OFF},
+     *
+     * @param device Paired bluetooth device
+     * @return true if priority is set, false on error
+     */
+    public boolean setPriority(BluetoothDevice device, int priority) {
+        if (DBG) Log.d(TAG, "setPriority(" + device + ", " + priority + ")");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            if (priority != BluetoothProfile.PRIORITY_OFF &&
+                    priority != BluetoothProfile.PRIORITY_ON) {
+                return false;
+            }
+            try {
+                return mService.setPriority(device, priority);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return false;
+    }
+
+    /**
+     * Get the priority of the profile.
+     *
+     * <p> The priority can be any of:
+     * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
+     * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
+     *
+     * @param device Bluetooth device
+     * @return priority of the device
+     */
+    public int getPriority(BluetoothDevice device) {
+        if (VDBG) Log.d(TAG, "getPriority(" + device + ")");
+        if (mService != null && isEnabled() &&
+                isValidDevice(device)) {
+            try {
+                return mService.getPriority(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return PRIORITY_OFF;
+            }
+        }
+        if (mService == null) Log.w(TAG, "Proxy not attached to service");
+        return PRIORITY_OFF;
+    }
+
+    /**
+     * Send a message.
+     *
+     * Send an SMS message to either the contacts primary number or the telephone number specified.
+     *
+     * @param device          Bluetooth device
+     * @param contacts        Uri[] of the contacts
+     * @param message         Message to be sent
+     * @param sentIntent      intent issued when message is sent
+     * @param deliveredIntent intent issued when message is delivered
+     * @return true if the message is enqueued, false on error
+     */
+    public boolean sendMessage(BluetoothDevice device, Uri[] contacts, String message,
+            PendingIntent sentIntent, PendingIntent deliveredIntent) {
+        if (DBG) Log.d(TAG, "sendMessage(" + device + ", " + contacts + ", " + message);
+        if (mService != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return mService.sendMessage(device, contacts, message, sentIntent, deliveredIntent);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Get unread messages.  Unread messages will be published via {@link #ACTION_MESSAGE_RECEIVED}.
+     *
+     * @param device Bluetooth device
+     * @return true if the message is enqueued, false on error
+     */
+    public boolean getUnreadMessages(BluetoothDevice device) {
+        if (DBG) Log.d(TAG, "getUnreadMessages(" + device + ")");
+        if (mService != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return mService.getUnreadMessages(device);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        return false;
+    }
+
+    private final ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) Log.d(TAG, "Proxy object connected");
+            mService = IBluetoothMapClient.Stub.asInterface(service);
+            if (mServiceListener != null) {
+                mServiceListener.onServiceConnected(BluetoothProfile.MAP_CLIENT,
+                    BluetoothMapClient.this);
+            }
+        }
+
+        public void onServiceDisconnected(ComponentName className) {
+            if (DBG) Log.d(TAG, "Proxy object disconnected");
+            mService = null;
+            if (mServiceListener != null) {
+                mServiceListener.onServiceDisconnected(BluetoothProfile.MAP_CLIENT);
+            }
+        }
+    };
+
+    private boolean isEnabled() {
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        if (adapter != null && adapter.getState() == BluetoothAdapter.STATE_ON) return true;
+        if (DBG) Log.d(TAG, "Bluetooth is Not enabled");
+        return false;
+    }
+
+    private boolean isValidDevice(BluetoothDevice device) {
+        if (device == null) return false;
+
+        if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
+        return false;
+    }
+
+
+}
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index 20d95cc..f363607 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2014 The Android Open Source Project
+ * Copyright (C) 2010-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.
@@ -137,6 +137,12 @@
     public static final int PBAP_CLIENT = 17;
 
     /**
+     * MAP Messaging Client Equipment (MCE)
+     * @hide
+     */
+    public static final int MAP_CLIENT = 18;
+
+    /**
      * Max profile ID. This value should be updated whenever a new profile is added to match
      * the largest value assigned to a profile.
      * @hide
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/IBluetoothMapClient.aidl b/core/java/android/bluetooth/IBluetoothMapClient.aidl
new file mode 100644
index 0000000..df45af9
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothMapClient.aidl
@@ -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.
+ */
+
+package android.bluetooth;
+
+import android.app.PendingIntent;
+import android.bluetooth.BluetoothDevice;
+import android.net.Uri;
+
+/**
+ * System private API for Bluetooth MAP MCE service
+ *
+ * {@hide}
+ */
+interface IBluetoothMapClient {
+    boolean connect(in BluetoothDevice device);
+    boolean disconnect(in BluetoothDevice device);
+    boolean isConnected(in BluetoothDevice device);
+    List<BluetoothDevice> getConnectedDevices();
+    List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
+    int getConnectionState(in BluetoothDevice device);
+    boolean setPriority(in BluetoothDevice device,in int priority);
+    int getPriority(in BluetoothDevice device);
+    boolean sendMessage(in BluetoothDevice device, in Uri[] contacts, in  String message,
+        in PendingIntent sentIntent, in PendingIntent deliveryIntent);
+    boolean getUnreadMessages(in BluetoothDevice device);
+}
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/Context.java b/core/java/android/content/Context.java
index 2f2ffc9..322cc7b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2688,7 +2688,7 @@
             NETWORK_STATS_SERVICE,
             //@hide: NETWORK_POLICY_SERVICE,
             WIFI_SERVICE,
-            WIFI_NAN_SERVICE,
+            WIFI_AWARE_SERVICE,
             WIFI_P2P_SERVICE,
             WIFI_SCANNING_SERVICE,
             //@hide: WIFI_RTT_SERVICE,
@@ -3161,14 +3161,14 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a
-     * {@link android.net.wifi.nan.WifiNanManager} for handling management of
-     * Wi-Fi NAN.
+     * {@link android.net.wifi.aware.WifiAwareManager} for handling management of
+     * Wi-Fi Aware.
      *
      * @see #getSystemService
-     * @see android.net.wifi.nan.WifiNanManager
-     * @hide PROPOSED_NAN_API
+     * @see android.net.wifi.aware.WifiAwareManager
+     * @hide PROPOSED_AWARE_API
      */
-    public static final String WIFI_NAN_SERVICE = "wifinan";
+    public static final String WIFI_AWARE_SERVICE = "wifiaware";
 
     /**
      * Use with {@link #getSystemService} to retrieve a {@link
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index e031275..4eecd48 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3120,6 +3120,11 @@
      * URIs that can be opened with
      * {@link ContentResolver#openFileDescriptor(Uri, String)}.
      * <p>
+     * Callers can set a document URI through {@link #setData(Uri)} to indicate
+     * the initial location of documents navigator. System will do its best to
+     * launch the navigator in the specified document if it's a folder, or the
+     * folder that contains the specified document if not.
+     * <p>
      * Output: The URI of the item that was picked, returned in
      * {@link #getData()}. This must be a {@code content://} URI so that any
      * receiver can access it. If multiple documents were selected, they are
@@ -3156,6 +3161,11 @@
      * URIs that can be opened with
      * {@link ContentResolver#openFileDescriptor(Uri, String)}.
      * <p>
+     * Callers can set a document URI through {@link #setData(Uri)} to indicate
+     * the initial location of documents navigator. System will do its best to
+     * launch the navigator in the specified document if it's a folder, or the
+     * folder that contains the specified document if not.
+     * <p>
      * Output: The URI of the item that was created. This must be a
      * {@code content://} URI so that any receiver can access it.
      *
@@ -3178,6 +3188,11 @@
      * {@link DocumentsContract#buildChildDocumentsUriUsingTree(Uri, String)}
      * with the returned URI.
      * <p>
+     * Callers can set a document URI through {@link #setData(Uri)} to indicate
+     * the initial location of documents navigator. System will do its best to
+     * initiate the navigator in the specified document if it's a folder, or
+     * the folder that contains the specified document if not.
+     * <p>
      * Output: The URI representing the selected directory tree.
      *
      * @see DocumentsContract
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/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index ecfc00f..74ec8e4 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -489,14 +489,6 @@
     public static final int PRIVATE_FLAG_DIRECT_BOOT_AWARE = 1 << 6;
 
     /**
-     * Value for {@link #privateFlags}: set to {@code true} if the application
-     * is AutoPlay.
-     *
-     * {@hide}
-     */
-    public static final int PRIVATE_FLAG_AUTOPLAY = 1 << 7;
-
-    /**
      * When set, at least one component inside this application is direct boot
      * aware.
      *
@@ -1197,13 +1189,6 @@
     /**
      * @hide
      */
-    public boolean isAutoPlayApp() {
-        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_AUTOPLAY) != 0;
-    }
-
-    /**
-     * @hide
-     */
     public boolean isEphemeralApp() {
         return (privateFlags & ApplicationInfo.PRIVATE_FLAG_EPHEMERAL) != 0;
     }
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/core/java/android/content/pm/ConfigurationInfo.aidl
similarity index 74%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to core/java/android/content/pm/ConfigurationInfo.aidl
index 5f66d16..0fa1003 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/core/java/android/content/pm/ConfigurationInfo.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
+/**
+ * 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
+ *     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,
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.content.pm;
 
-parcelable PublishConfig;
+parcelable ConfigurationInfo;
\ No newline at end of file
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 26e0346..052fa61 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2040,12 +2040,12 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
-     * {@link #hasSystemFeature}: The device supports Wi-Fi NAN.
+     * {@link #hasSystemFeature}: The device supports Wi-Fi Aware.
      *
-     * @hide PROPOSED_NAN_API
+     * @hide PROPOSED_AWARE_API
      */
     @SdkConstant(SdkConstantType.FEATURE)
-    public static final String FEATURE_WIFI_NAN = "android.hardware.wifi.nan";
+    public static final String FEATURE_WIFI_AWARE = "android.hardware.wifi.aware";
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index da4eb2d..1f013ae 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -189,4 +189,17 @@
     public abstract void revokeRuntimePermission(String packageName, String name, int userId,
             boolean overridePolicy);
 
+    /**
+     * Retrieve the official name associated with a user id.  This name is
+     * guaranteed to never change, though it is possible for the underlying
+     * user id to be changed.  That is, if you are storing information about
+     * user ids in persistent storage, you should use the string returned
+     * by this function instead of the raw user-id.
+     *
+     * @param uid The user id for which you would like to retrieve a name.
+     * @return Returns a unique name for the given user id, or null if the
+     * user id is not currently assigned.
+     */
+    public abstract String getNameForUid(int uid);
+
 }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 12e8d48..bb9c18a 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -23,6 +23,7 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Intent;
@@ -98,6 +99,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
@@ -696,23 +698,23 @@
     public static PackageLite parsePackageLite(File packageFile, int flags)
             throws PackageParserException {
         if (packageFile.isDirectory()) {
-            return parseClusterPackageLite(packageFile, flags);
+            return parseClusterPackageLite(packageFile, flags, null);
         } else {
-            return parseMonolithicPackageLite(packageFile, flags);
+            return parseMonolithicPackageLite(packageFile, flags, null);
         }
     }
 
-    private static PackageLite parseMonolithicPackageLite(File packageFile, int flags)
-            throws PackageParserException {
+    private static PackageLite parseMonolithicPackageLite(File packageFile, int flags,
+            AssetManager cachedAssetManager) throws PackageParserException {
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parseApkLite");
-        final ApkLite baseApk = parseApkLite(packageFile, flags);
+        final ApkLite baseApk = parseApkLite(packageFile, flags, cachedAssetManager);
         final String packagePath = packageFile.getAbsolutePath();
         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         return new PackageLite(packagePath, baseApk, null, null, null);
     }
 
-    private static PackageLite parseClusterPackageLite(File packageDir, int flags)
-            throws PackageParserException {
+    private static PackageLite parseClusterPackageLite(File packageDir, int flags,
+            AssetManager cachedAssetManager) throws PackageParserException {
         final File[] files = packageDir.listFiles();
         if (ArrayUtils.isEmpty(files)) {
             throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK,
@@ -726,7 +728,7 @@
         final ArrayMap<String, ApkLite> apks = new ArrayMap<>();
         for (File file : files) {
             if (isApkFile(file)) {
-                final ApkLite lite = parseApkLite(file, flags);
+                final ApkLite lite = parseApkLite(file, flags, cachedAssetManager);
 
                 // Assert that all package names and version codes are
                 // consistent with the first one we encounter.
@@ -819,16 +821,16 @@
      * must be done separately in {@link #collectCertificates(Package, int)}.
      */
     private Package parseClusterPackage(File packageDir, int flags) throws PackageParserException {
-        final PackageLite lite = parseClusterPackageLite(packageDir, 0);
+        final AssetManager assets = newConfiguredAssetManager();
+        final PackageLite lite = parseClusterPackageLite(packageDir, 0, assets);
 
         if (mOnlyCoreApps && !lite.coreApp) {
             throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
                     "Not a coreApp: " + packageDir);
         }
 
-        final AssetManager assets = new AssetManager();
         try {
-            // Load the base and all splits into the AssetManager
+            // Load all splits into the AssetManager (base has already been loaded earlier)
             // so that resources can be overriden when parsing the manifests.
             loadApkIntoAssetManager(assets, lite.baseCodePath, flags);
 
@@ -878,7 +880,8 @@
      */
     @Deprecated
     public Package parseMonolithicPackage(File apkFile, int flags) throws PackageParserException {
-        final PackageLite lite = parseMonolithicPackageLite(apkFile, flags);
+        final AssetManager assets = newConfiguredAssetManager();
+        final PackageLite lite = parseMonolithicPackageLite(apkFile, flags, assets);
         if (mOnlyCoreApps) {
             if (!lite.coreApp) {
                 throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
@@ -886,7 +889,6 @@
             }
         }
 
-        final AssetManager assets = new AssetManager();
         try {
             final Package pkg = parseBaseApk(apkFile, assets, flags);
             pkg.setCodePath(apkFile.getAbsolutePath());
@@ -936,8 +938,6 @@
         XmlResourceParser parser = null;
         try {
             res = new Resources(assets, mMetrics, null);
-            assets.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    Build.VERSION.RESOURCES_SDK_INT);
             parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
 
             final String[] outError = new String[1];
@@ -1303,6 +1303,13 @@
         return res;
     }
 
+    private static AssetManager newConfiguredAssetManager() {
+        AssetManager assetManager = new AssetManager();
+        assetManager.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                Build.VERSION.RESOURCES_SDK_INT);
+        return assetManager;
+    }
+
     /**
      * Utility method that retrieves lightweight details about a single APK
      * file, including package name, split name, and install location.
@@ -1313,15 +1320,17 @@
      */
     public static ApkLite parseApkLite(File apkFile, int flags)
             throws PackageParserException {
+        return parseApkLite(apkFile, flags, null);
+    }
+
+    private static ApkLite parseApkLite(File apkFile, int flags,
+            @Nullable AssetManager cachedAssetManager) throws PackageParserException {
         final String apkPath = apkFile.getAbsolutePath();
 
         AssetManager assets = null;
         XmlResourceParser parser = null;
         try {
-            assets = new AssetManager();
-            assets.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    Build.VERSION.RESOURCES_SDK_INT);
-
+            assets = cachedAssetManager == null ? newConfiguredAssetManager() : cachedAssetManager;
             int cookie = assets.addAssetPath(apkPath);
             if (cookie == 0) {
                 throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK,
@@ -1360,7 +1369,9 @@
                     "Failed to parse " + apkPath, e);
         } finally {
             IoUtils.closeQuietly(parser);
-            IoUtils.closeQuietly(assets);
+            if (cachedAssetManager == null) {
+                IoUtils.closeQuietly(assets);
+            }
         }
     }
 
@@ -2599,9 +2610,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 +3584,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/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 2be3657..e796fa7 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -102,6 +102,11 @@
     public long creationTime;
     public long lastLoggedInTime;
     public String lastLoggedInFingerprint;
+    /**
+     * If this user is a parent user, it would be its own user id.
+     * If this user is a child user, it would be its parent user id.
+     * Otherwise, it would be {@link #NO_PROFILE_GROUP_ID}.
+     */
     public int profileGroupId;
     public int restrictedProfileParentId;
 
diff --git a/core/java/android/hardware/radio/RadioMetadata.java b/core/java/android/hardware/radio/RadioMetadata.java
index b7715da..d07b407 100644
--- a/core/java/android/hardware/radio/RadioMetadata.java
+++ b/core/java/android/hardware/radio/RadioMetadata.java
@@ -530,14 +530,13 @@
         Bitmap bmp = null;
         try {
             bmp = BitmapFactory.decodeByteArray(value, 0, value.length);
-        } catch (Exception e) {
-        } finally {
-            if (bmp == null) {
-                return -1;
+            if (bmp != null) {
+                mBundle.putParcelable(key, bmp);
+                return 0;
             }
-            mBundle.putParcelable(key, bmp);
-            return 0;
+        } catch (Exception e) {
         }
+        return -1;
     }
 
     int putClockFromNative(int nativeKey, long utcEpochSeconds, int timezoneOffsetInMinutes) {
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/IIpConnectivityMetrics.aidl b/core/java/android/net/IIpConnectivityMetrics.aidl
index d36b766..6f07b31 100644
--- a/core/java/android/net/IIpConnectivityMetrics.aidl
+++ b/core/java/android/net/IIpConnectivityMetrics.aidl
@@ -18,6 +18,7 @@
 
 import android.os.Parcelable;
 import android.net.ConnectivityMetricsEvent;
+import android.net.INetdEventCallback;
 
 /** {@hide} */
 interface IIpConnectivityMetrics {
@@ -27,4 +28,13 @@
      * or -1 if the event was dropped due to rate limiting.
      */
     int logEvent(in ConnectivityMetricsEvent event);
+
+    /**
+     * At most one callback can be registered (by DevicePolicyManager).
+     * @return status {@code true} if registering/unregistering of the callback was successful,
+     *         {@code false} otherwise (might happen if IIpConnectivityMetrics is not available,
+     *         if it happens make sure you call it when the service is up in the caller)
+     */
+    boolean registerNetdEventCallback(in INetdEventCallback callback);
+    boolean unregisterNetdEventCallback();
 }
diff --git a/core/java/android/net/INetdEventCallback.aidl b/core/java/android/net/INetdEventCallback.aidl
new file mode 100644
index 0000000..49436be
--- /dev/null
+++ b/core/java/android/net/INetdEventCallback.aidl
@@ -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.
+ */
+
+package android.net;
+
+/** {@hide} */
+oneway interface INetdEventCallback {
+
+    /**
+     * Reports a single DNS lookup function call.
+     * This method must not block or perform long-running operations.
+     *
+     * @param hostname the name that was looked up.
+     * @param ipAddresses (possibly a subset of) the IP addresses returned.
+     *        At most {@link #DNS_REPORTED_IP_ADDRESSES_LIMIT} addresses are logged.
+     * @param ipAddressesCount the number of IP addresses returned. May be different from the length
+     *        of ipAddresses if there were too many addresses to log.
+     * @param timestamp the timestamp at which the query was reported by netd.
+     * @param uid the UID of the application that performed the query.
+     */
+    void onDnsEvent(String hostname, in String[] ipAddresses, int ipAddressesCount, long timestamp,
+            int uid);
+
+    /**
+     * Reports a single connect library call.
+     * This method must not block or perform long-running operations.
+     *
+     * @param ipAddr destination IP address.
+     * @param port destination port number.
+     * @param timestamp the timestamp at which the call was reported by netd.
+     * @param uid the UID of the application that performed the connection.
+     */
+    void onConnectEvent(String ipAddr, int port, long timestamp, int uid);
+}
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 6196400..dacea55 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -419,14 +419,14 @@
     public static final int TRANSPORT_VPN = 4;
 
     /**
-     * Indicates this network uses a Wi-Fi NAN transport.
+     * Indicates this network uses a Wi-Fi Aware transport.
      *
-     * @hide PROPOSED_NAN_API
+     * @hide PROPOSED_AWARE_API
      */
-    public static final int TRANSPORT_WIFI_NAN = 5;
+    public static final int TRANSPORT_WIFI_AWARE = 5;
 
     private static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
-    private static final int MAX_TRANSPORT = TRANSPORT_WIFI_NAN;
+    private static final int MAX_TRANSPORT = TRANSPORT_WIFI_AWARE;
 
     /**
      * Adds the given transport type to this {@code NetworkCapability} instance.
@@ -896,7 +896,7 @@
                 case TRANSPORT_BLUETOOTH:   transports += "BLUETOOTH"; break;
                 case TRANSPORT_ETHERNET:    transports += "ETHERNET"; break;
                 case TRANSPORT_VPN:         transports += "VPN"; break;
-                case TRANSPORT_WIFI_NAN:    transports += "WIFI_NAN"; break;
+                case TRANSPORT_WIFI_AWARE:  transports += "WIFI_AWARE"; break;
             }
             if (++i < types.length) transports += "|";
         }
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index d570e66..c704ef0 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -171,7 +171,8 @@
         String subscriberId = null;
         String networkId = null;
         boolean roaming = false;
-        boolean metered = false;
+        boolean metered = !state.networkCapabilities.hasCapability(
+                NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
 
         if (isNetworkTypeMobile(type)) {
             if (state.subscriberId == null) {
@@ -185,9 +186,6 @@
             subscriberId = state.subscriberId;
             roaming = state.networkInfo.isRoaming();
 
-            metered = !state.networkCapabilities.hasCapability(
-                    NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
-
         } else if (type == TYPE_WIFI) {
             if (state.networkId != null) {
                 networkId = state.networkId;
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index f65a50f..77ce65b 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -68,11 +68,18 @@
     // TODO: Rename TAG_NONE to TAG_ALL.
     public static final int TAG_NONE = 0;
 
-    /** {@link #set} value for all roaming values. */
+    /** {@link #metered} value to account for all metered states. */
+    public static final int METERED_ALL = -1;
+    /** {@link #metered} value where native, unmetered data is accounted. */
+    public static final int METERED_NO = 0;
+    /** {@link #metered} value where metered data is accounted. */
+    public static final int METERED_YES = 1;
+
+    /** {@link #roaming} value to account for all roaming states. */
     public static final int ROAMING_ALL = -1;
-    /** {@link #set} value where native, non-roaming data is accounted. */
+    /** {@link #roaming} value where native, non-roaming data is accounted. */
     public static final int ROAMING_NO = 0;
-    /** {@link #set} value where roaming data is accounted. */
+    /** {@link #roaming} value where roaming data is accounted. */
     public static final int ROAMING_YES = 1;
 
     // TODO: move fields to "mVariable" notation
@@ -88,6 +95,7 @@
     private int[] uid;
     private int[] set;
     private int[] tag;
+    private int[] metered;
     private int[] roaming;
     private long[] rxBytes;
     private long[] rxPackets;
@@ -105,6 +113,12 @@
          * to disk. We merge in the correct value when reporting this value to clients of
          * getSummary().
          */
+        public int metered;
+        /**
+         * Note that this is only populated w/ the default value when read from /proc or written
+         * to disk. We merge in the correct value when reporting this value to clients of
+         * getSummary().
+         */
         public int roaming;
         public long rxBytes;
         public long rxPackets;
@@ -123,16 +137,17 @@
 
         public Entry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets,
                 long txBytes, long txPackets, long operations) {
-            this(iface, uid, set, tag, ROAMING_NO, rxBytes, rxPackets, txBytes, txPackets,
-                    operations);
+            this(iface, uid, set, tag, METERED_NO, ROAMING_NO, rxBytes, rxPackets, txBytes,
+                    txPackets, operations);
         }
 
-        public Entry(String iface, int uid, int set, int tag, int roaming, long rxBytes,
-                long rxPackets, long txBytes, long txPackets, long operations) {
+        public Entry(String iface, int uid, int set, int tag, int metered, int roaming,
+                 long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
             this.iface = iface;
             this.uid = uid;
             this.set = set;
             this.tag = tag;
+            this.metered = metered;
             this.roaming = roaming;
             this.rxBytes = rxBytes;
             this.rxPackets = rxPackets;
@@ -165,6 +180,7 @@
             builder.append(" uid=").append(uid);
             builder.append(" set=").append(setToString(set));
             builder.append(" tag=").append(tagToString(tag));
+            builder.append(" metered=").append(meteredToString(metered));
             builder.append(" roaming=").append(roamingToString(roaming));
             builder.append(" rxBytes=").append(rxBytes);
             builder.append(" rxPackets=").append(rxPackets);
@@ -178,13 +194,18 @@
         public boolean equals(Object o) {
             if (o instanceof Entry) {
                 final Entry e = (Entry) o;
-                return uid == e.uid && set == e.set && tag == e.tag && roaming == e.roaming
-                        && rxBytes == e.rxBytes && rxPackets == e.rxPackets && txBytes == e.txBytes
-                        && txPackets == e.txPackets && operations == e.operations
-                        && iface.equals(e.iface);
+                return uid == e.uid && set == e.set && tag == e.tag && metered == e.metered
+                        && roaming == e.roaming && rxBytes == e.rxBytes && rxPackets == e.rxPackets
+                        && txBytes == e.txBytes && txPackets == e.txPackets
+                        && operations == e.operations && iface.equals(e.iface);
             }
             return false;
         }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(uid, set, tag, metered, roaming, iface);
+        }
     }
 
     public NetworkStats(long elapsedRealtime, int initialSize) {
@@ -196,6 +217,7 @@
             this.uid = new int[initialSize];
             this.set = new int[initialSize];
             this.tag = new int[initialSize];
+            this.metered = new int[initialSize];
             this.roaming = new int[initialSize];
             this.rxBytes = new long[initialSize];
             this.rxPackets = new long[initialSize];
@@ -209,6 +231,7 @@
             this.uid = EmptyArray.INT;
             this.set = EmptyArray.INT;
             this.tag = EmptyArray.INT;
+            this.metered = EmptyArray.INT;
             this.roaming = EmptyArray.INT;
             this.rxBytes = EmptyArray.LONG;
             this.rxPackets = EmptyArray.LONG;
@@ -226,6 +249,7 @@
         uid = parcel.createIntArray();
         set = parcel.createIntArray();
         tag = parcel.createIntArray();
+        metered = parcel.createIntArray();
         roaming = parcel.createIntArray();
         rxBytes = parcel.createLongArray();
         rxPackets = parcel.createLongArray();
@@ -243,6 +267,7 @@
         dest.writeIntArray(uid);
         dest.writeIntArray(set);
         dest.writeIntArray(tag);
+        dest.writeIntArray(metered);
         dest.writeIntArray(roaming);
         dest.writeLongArray(rxBytes);
         dest.writeLongArray(rxPackets);
@@ -277,10 +302,11 @@
     }
 
     @VisibleForTesting
-    public NetworkStats addValues(String iface, int uid, int set, int tag, int roaming,
+    public NetworkStats addValues(String iface, int uid, int set, int tag, int metered, int roaming,
             long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
         return addValues(new Entry(
-                iface, uid, set, tag, roaming, rxBytes, rxPackets, txBytes, txPackets, operations));
+                iface, uid, set, tag, metered, roaming, rxBytes, rxPackets, txBytes, txPackets,
+                operations));
     }
 
     /**
@@ -294,6 +320,7 @@
             uid = Arrays.copyOf(uid, newLength);
             set = Arrays.copyOf(set, newLength);
             tag = Arrays.copyOf(tag, newLength);
+            metered = Arrays.copyOf(metered, newLength);
             roaming = Arrays.copyOf(roaming, newLength);
             rxBytes = Arrays.copyOf(rxBytes, newLength);
             rxPackets = Arrays.copyOf(rxPackets, newLength);
@@ -307,6 +334,7 @@
         uid[size] = entry.uid;
         set[size] = entry.set;
         tag[size] = entry.tag;
+        metered[size] = entry.metered;
         roaming[size] = entry.roaming;
         rxBytes[size] = entry.rxBytes;
         rxPackets[size] = entry.rxPackets;
@@ -327,6 +355,7 @@
         entry.uid = uid[i];
         entry.set = set[i];
         entry.tag = tag[i];
+        entry.metered = metered[i];
         entry.roaming = roaming[i];
         entry.rxBytes = rxBytes[i];
         entry.rxPackets = rxPackets[i];
@@ -381,7 +410,8 @@
      * also be used to subtract values from existing rows.
      */
     public NetworkStats combineValues(Entry entry) {
-        final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag, entry.roaming);
+        final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag, entry.metered,
+                entry.roaming);
         if (i == -1) {
             // only create new entry when positive contribution
             addValues(entry);
@@ -409,10 +439,11 @@
     /**
      * Find first stats index that matches the requested parameters.
      */
-    public int findIndex(String iface, int uid, int set, int tag, int roaming) {
+    public int findIndex(String iface, int uid, int set, int tag, int metered, int roaming) {
         for (int i = 0; i < size; i++) {
             if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i]
-                    && roaming == this.roaming[i] && Objects.equals(iface, this.iface[i])) {
+                    && metered == this.metered[i] && roaming == this.roaming[i]
+                    && Objects.equals(iface, this.iface[i])) {
                 return i;
             }
         }
@@ -424,7 +455,7 @@
      * search around the hinted index as an optimization.
      */
     @VisibleForTesting
-    public int findIndexHinted(String iface, int uid, int set, int tag, int roaming,
+    public int findIndexHinted(String iface, int uid, int set, int tag, int metered, int roaming,
             int hintIndex) {
         for (int offset = 0; offset < size; offset++) {
             final int halfOffset = offset / 2;
@@ -438,7 +469,8 @@
             }
 
             if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i]
-                    && roaming == this.roaming[i] && Objects.equals(iface, this.iface[i])) {
+                    && metered == this.metered[i] && roaming == this.roaming[i]
+                    && Objects.equals(iface, this.iface[i])) {
                 return i;
             }
         }
@@ -452,7 +484,7 @@
      */
     public void spliceOperationsFrom(NetworkStats stats) {
         for (int i = 0; i < size; i++) {
-            final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i], roaming[i]);
+            final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i], metered[i], roaming[i]);
             if (j == -1) {
                 operations[i] = 0;
             } else {
@@ -542,6 +574,7 @@
         entry.uid = limitUid;
         entry.set = SET_ALL;
         entry.tag = TAG_NONE;
+        entry.metered = METERED_ALL;
         entry.roaming = ROAMING_ALL;
         entry.rxBytes = 0;
         entry.rxPackets = 0;
@@ -637,11 +670,12 @@
             entry.uid = left.uid[i];
             entry.set = left.set[i];
             entry.tag = left.tag[i];
+            entry.metered = left.metered[i];
             entry.roaming = left.roaming[i];
 
             // find remote row that matches, and subtract
             final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag,
-                    entry.roaming, i);
+                    entry.metered, entry.roaming, i);
             if (j == -1) {
                 // newly appearing row, return entire value
                 entry.rxBytes = left.rxBytes[i];
@@ -687,6 +721,7 @@
         entry.uid = UID_ALL;
         entry.set = SET_ALL;
         entry.tag = TAG_NONE;
+        entry.metered = METERED_ALL;
         entry.roaming = ROAMING_ALL;
         entry.operations = 0L;
 
@@ -716,6 +751,7 @@
         entry.iface = IFACE_ALL;
         entry.set = SET_ALL;
         entry.tag = TAG_NONE;
+        entry.metered = METERED_ALL;
         entry.roaming = ROAMING_ALL;
 
         for (int i = 0; i < size; i++) {
@@ -762,6 +798,7 @@
             pw.print(" uid="); pw.print(uid[i]);
             pw.print(" set="); pw.print(setToString(set[i]));
             pw.print(" tag="); pw.print(tagToString(tag[i]));
+            pw.print(" metered="); pw.print(meteredToString(metered[i]));
             pw.print(" roaming="); pw.print(roamingToString(roaming[i]));
             pw.print(" rxBytes="); pw.print(rxBytes[i]);
             pw.print(" rxPackets="); pw.print(rxPackets[i]);
@@ -830,6 +867,22 @@
     }
 
     /**
+     * Return text description of {@link #metered} value.
+     */
+    public static String meteredToString(int metered) {
+        switch (metered) {
+            case METERED_ALL:
+                return "ALL";
+            case METERED_NO:
+                return "NO";
+            case METERED_YES:
+                return "YES";
+            default:
+                return "UNKNOWN";
+        }
+    }
+
+    /**
      * Return text description of {@link #roaming} value.
      */
     public static String roamingToString(int roaming) {
@@ -998,6 +1051,7 @@
                 tmpEntry.uid = uid[i];
                 tmpEntry.tag = tag[i];
                 tmpEntry.set = set[i];
+                tmpEntry.metered = metered[i];
                 tmpEntry.roaming = roaming[i];
                 combineValues(tmpEntry);
                 if (tag[i] == TAG_NONE) {
@@ -1017,24 +1071,25 @@
         moved.set = SET_DBG_VPN_OUT;
         moved.tag = TAG_NONE;
         moved.iface = underlyingIface;
+        moved.metered = METERED_ALL;
         moved.roaming = ROAMING_ALL;
         combineValues(moved);
 
         // Caveat: if the vpn software uses tag, the total tagged traffic may be greater than
         // the TAG_NONE traffic.
         //
-        // Relies on the fact that the underlying traffic only has state ROAMING_NO, which
-        // should be the case as it comes directly from the /proc file. We only blend in the
+        // Relies on the fact that the underlying traffic only has state ROAMING_NO and METERED_NO,
+        // which should be the case as it comes directly from the /proc file. We only blend in the
         // roaming data after applying these adjustments, by checking the NetworkIdentity of the
         // underlying iface.
         int idxVpnBackground = findIndex(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE,
-                ROAMING_NO);
+                METERED_NO, ROAMING_NO);
         if (idxVpnBackground != -1) {
             tunSubtract(idxVpnBackground, this, moved);
         }
 
         int idxVpnForeground = findIndex(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE,
-                ROAMING_NO);
+                METERED_NO, ROAMING_NO);
         if (idxVpnForeground != -1) {
             tunSubtract(idxVpnForeground, this, moved);
         }
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index cf77567..7b7533b 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -563,7 +563,11 @@
         boolean res;
         // Log any exceptions as warnings, don't silently suppress them.
         // If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
+        final boolean tracingEnabled = Binder.isTracingEnabled();
         try {
+            if (tracingEnabled) {
+                Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + ":" + code);
+            }
             res = onTransact(code, data, reply, flags);
         } catch (RemoteException|RuntimeException e) {
             if (LOG_RUNTIME_EXCEPTION) {
@@ -587,6 +591,10 @@
             reply.setDataPosition(0);
             reply.writeException(re);
             res = true;
+        } finally {
+            if (tracingEnabled) {
+                Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
+            }
         }
         checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
         reply.recycle();
@@ -613,8 +621,21 @@
 
     public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
         Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
-        if (Binder.isTracingEnabled()) { Binder.getTransactionTracker().addTrace(); }
-        return transactNative(code, data, reply, flags);
+        final boolean tracingEnabled = Binder.isTracingEnabled();
+        if (tracingEnabled) {
+            final Throwable tr = new Throwable();
+            Binder.getTransactionTracker().addTrace(tr);
+            StackTraceElement stackTraceElement = tr.getStackTrace()[1];
+            Trace.traceBegin(Trace.TRACE_TAG_ALWAYS,
+                    stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName());
+        }
+        try {
+            return transactNative(code, data, reply, flags);
+        } finally {
+            if (tracingEnabled) {
+                Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
+            }
+        }
     }
 
     public native String getInterfaceDescriptor() throws RemoteException;
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 312a098..e5832c8 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -755,6 +755,11 @@
          * N MR1: Nougat++.
          */
         public static final int N_MR1 = 25;
+
+        /**
+         * O.
+         */
+        public static final int O = CUR_DEVELOPMENT; // STOPSHIP Replace with the real version.
     }
 
     /** The type of build, like "user" or "eng". */
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/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/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/core/java/android/os/StrictMode.aidl
similarity index 73%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to core/java/android/os/StrictMode.aidl
index 5f66d16..d045db4 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/core/java/android/os/StrictMode.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
+/**
+ * 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
+ *     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,
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.os;
 
-parcelable PublishConfig;
+/** @hide */
+parcelable StrictMode.ViolationInfo;
\ No newline at end of file
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index ff69cf6..e9a3936 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -16,6 +16,7 @@
 package android.os;
 
 import android.animation.ValueAnimator;
+import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.ActivityThread;
 import android.app.ApplicationErrorReport;
@@ -1554,7 +1555,7 @@
                     // We restore the current policy below, in the finally block.
                     setThreadPolicyMask(0);
 
-                    ActivityManagerNative.getDefault().handleApplicationStrictModeViolation(
+                    ActivityManager.getService().handleApplicationStrictModeViolation(
                         RuntimeInit.getApplicationObject(),
                         violationMaskSubset,
                         info);
@@ -2373,7 +2374,7 @@
      *
      * @hide
      */
-    public static class ViolationInfo {
+    public static class ViolationInfo implements Parcelable {
         public String message;
 
         /**
@@ -2528,6 +2529,7 @@
         /**
          * Save a ViolationInfo instance to a parcel.
          */
+        @Override
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeString(message);
             crashInfo.writeToParcel(dest, flags);
@@ -2584,6 +2586,23 @@
             }
         }
 
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        public static final Parcelable.Creator<ViolationInfo> CREATOR =
+                new Parcelable.Creator<ViolationInfo>() {
+                    @Override
+                    public ViolationInfo createFromParcel(Parcel in) {
+                        return new ViolationInfo(in);
+                    }
+
+                    @Override
+                    public ViolationInfo[] newArray(int size) {
+                        return new ViolationInfo[size];
+                    }
+                };
     }
 
     // Dummy throwable, for now, since we don't know when or where the
diff --git a/core/java/android/os/TransactionTracker.java b/core/java/android/os/TransactionTracker.java
index 77f3e02..ebb4699 100644
--- a/core/java/android/os/TransactionTracker.java
+++ b/core/java/android/os/TransactionTracker.java
@@ -43,8 +43,8 @@
         resetTraces();
     }
 
-    public void addTrace() {
-        String trace = Log.getStackTraceString(new Throwable());
+    public void addTrace(Throwable tr) {
+        String trace = Log.getStackTraceString(tr);
         synchronized (this) {
             if (mTraces.containsKey(trace)) {
                 mTraces.put(trace, mTraces.get(trace) + 1);
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/storage/IMountService.aidl b/core/java/android/os/storage/IMountService.aidl
new file mode 100644
index 0000000..390df99
--- /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) = 0;
+    /**
+     * Unregisters an IMountServiceListener
+     */
+    void unregisterListener(IMountServiceListener listener) = 1;
+    /**
+     * Returns true if a USB mass storage host is connected
+     */
+    boolean isUsbMassStorageConnected() = 2;
+    /**
+     * Enables / disables USB mass storage. The caller should check actual
+     * status of enabling/disabling USB mass storage via StorageEventListener.
+     */
+    void setUsbMassStorageEnabled(boolean enable) = 3;
+    /**
+     * Returns true if a USB mass storage host is enabled (media is shared)
+     */
+    boolean isUsbMassStorageEnabled() = 4;
+    /**
+     * Mount external storage at given mount point. Returns an int consistent
+     * with MountServiceResultCode
+     */
+    int mountVolume(in String mountPoint) = 5;
+    /**
+     * 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) = 6;
+    /**
+     * Format external storage given a mount point. Returns an int consistent
+     * with MountServiceResultCode
+     */
+    int formatVolume(in String mountPoint) = 7;
+    /**
+     * Returns an array of pids with open files on the specified path.
+     */
+    int[] getStorageUsers(in String path) = 8;
+    /**
+     * Gets the state of a volume via its mountpoint.
+     */
+    String getVolumeState(in String mountPoint) = 9;
+    /*
+     * 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) = 10;
+    /*
+     * 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) = 11;
+    /*
+     * 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) = 12;
+    /*
+     * 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) = 13;
+    /*
+     * Unount a secure container. Returns an int consistent with
+     * MountServiceResultCode
+     */
+    int unmountSecureContainer(in String id, boolean force) = 14;
+    /*
+     * Returns true if the specified container is mounted
+     */
+    boolean isSecureContainerMounted(in String id) = 15;
+    /*
+     * Rename an unmounted secure container. Returns an int consistent with
+     * MountServiceResultCode
+     */
+    int renameSecureContainer(in String oldId, in String newId) = 16;
+    /*
+     * Returns the filesystem path of a mounted secure container.
+     */
+    String getSecureContainerPath(in String id) = 17;
+    /**
+     * Gets an Array of currently known secure container IDs
+     */
+    String[] getSecureContainerList() = 18;
+    /**
+     * Shuts down the MountService and gracefully unmounts all external media.
+     * Invokes call back once the shutdown is complete.
+     */
+    void shutdown(IMountShutdownObserver observer) = 19;
+    /**
+     * Call into MountService by PackageManager to notify that its done
+     * processing the media status update request.
+     */
+    void finishMediaUpdate() = 20;
+    /**
+     * 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) = 21;
+    /**
+     * 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) = 22;
+    /**
+     * Checks whether the specified Opaque Binary Blob (OBB) is mounted
+     * somewhere.
+     */
+    boolean isObbMounted(in String rawPath) = 23;
+    /**
+     * Gets the path to the mounted Opaque Binary Blob (OBB).
+     */
+    String getMountedObbPath(in String rawPath) = 24;
+    /**
+     * Returns whether or not the external storage is emulated.
+     */
+    boolean isExternalStorageEmulated() = 25;
+    /**
+     * Decrypts any encrypted volumes.
+     */
+    int decryptStorage(in String password) = 26;
+    /**
+     * Encrypts storage.
+     */
+    int encryptStorage(int type, in String password) = 27;
+    /**
+     * Changes the encryption password.
+     */
+    int changeEncryptionPassword(int type, in String password) = 28;
+    /**
+     * Returns list of all mountable volumes.
+     */
+    StorageVolume[] getVolumeList(int uid, in String packageName, int flags) = 29;
+    /**
+     * 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) = 30;
+    /**
+     * 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() = 31;
+    /**
+     * Verify the encryption password against the stored volume.  This method
+     * may only be called by the system process.
+     */
+    int verifyEncryptionPassword(in String password) = 32;
+    /*
+     * 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) = 33;
+    /**
+     * 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) = 34;
+    /**
+     * Determines the type of the encryption password
+     * @return PasswordType
+     */
+    int getPasswordType() = 35;
+    /**
+     * Get password from vold
+     * @return password or empty string
+     */
+    String getPassword() = 36;
+    /**
+     * Securely clear password from vold
+     */
+    oneway void clearPassword() = 37;
+    /**
+     * 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) = 38;
+    /**
+     * Gets a field from the crypto header.
+     * @param field field to get
+     * @return contents of field
+     */
+    String getField(in String field) = 39;
+    int resizeSecureContainer(in String id, int sizeMb, in String key) = 40;
+    /**
+     * 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() = 41;
+    /**
+     * Kick off an immediate maintenance operation
+     * @throws RemoteException
+     */
+    void runMaintenance() = 42;
+    void waitForAsecScan() = 43;
+    DiskInfo[] getDisks() = 44;
+    VolumeInfo[] getVolumes(int flags) = 45;
+    VolumeRecord[] getVolumeRecords(int flags) = 46;
+    void mount(in String volId) = 47;
+    void unmount(in String volId) = 48;
+    void format(in String volId) = 49;
+    void partitionPublic(in String diskId) = 50;
+    void partitionPrivate(in String diskId) = 51;
+    void partitionMixed(in String diskId, int ratio) = 52;
+    void setVolumeNickname(in String fsUuid, in String nickname) = 53;
+    void setVolumeUserFlags(in String fsUuid, int flags, int mask) = 54;
+    void forgetVolume(in String fsUuid) = 55;
+    void forgetAllVolumes() = 56;
+    String getPrimaryStorageUuid() = 57;
+    void setPrimaryStorageUuid(in String volumeUuid, IPackageMoveObserver callback) = 58;
+    long benchmark(in String volId) = 59;
+    void setDebugFlags(int flags, int mask) = 60;
+    void createUserKey(int userId, int serialNumber, boolean ephemeral) = 61;
+    void destroyUserKey(int userId) = 62;
+    void unlockUserKey(int userId, int serialNumber, in byte[] token, in byte[] secret) = 63;
+    void lockUserKey(int userId) = 64;
+    boolean isUserKeyUnlocked(int userId) = 65;
+    void prepareUserStorage(in String volumeUuid, int userId, int serialNumber, int flags) = 66;
+    void destroyUserStorage(in String volumeUuid, int userId, int flags) = 67;
+    boolean isConvertibleToFBE() = 68;
+    ParcelFileDescriptor mountAppFuse(in String name) = 69;
+    void addUserKeyAuth(int userId, int serialNumber, in byte[] token, in byte[] secret) = 70;
+    void fixateNewestUserKeyAuth(int userId) = 71;
+}
\ 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..0e20cd3
--- /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) = 0;
+
+    /**
+     * 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) = 1;
+
+    void onVolumeStateChanged(in VolumeInfo vol, int oldState, int newState) = 2;
+
+    void onVolumeRecordChanged(in VolumeRecord rec) = 3;
+
+    void onVolumeForgotten(in String fsUuid) = 4;
+
+    void onDiskScanned(in DiskInfo disk, int volumeCount) = 5;
+
+    void onDiskDestroyed(in DiskInfo disk) = 6;
+
+    /**
+     * 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..f3e1654
--- /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) = 0;
+
+    /**
+     * 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..61ba4d5
--- /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) = 0;
+
+    /**
+     * 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/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/core/java/android/os/storage/VolumeRecord.aidl
similarity index 74%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to core/java/android/os/storage/VolumeRecord.aidl
index 5f66d16..27c4010 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/core/java/android/os/storage/VolumeRecord.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
+/**
+ * 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
+ *     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,
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.os.storage;
 
-parcelable PublishConfig;
+/** @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..2dcf220 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
@@ -652,7 +636,7 @@
     /** {@hide} */
     public static final String METHOD_EJECT_ROOT = "android:ejectRoot";
     /** {@hide} */
-    public static final String METHOD_FIND_PATH = "android:findPath";
+    public static final String METHOD_FIND_DOCUMENT_PATH = "android:findDocumentPath";
 
     /** {@hide} */
     public static final String EXTRA_PARENT_URI = "parentUri";
@@ -1320,22 +1304,20 @@
      * from the top of the tree or the root document to the requested document,
      * both inclusive.
      *
-     * Document id should be unique across roots.
+     * Document ID should be unique across roots.
      *
      * @param treeUri treeUri of the document which path is requested.
      * @return a list of documents ID starting from the top of the tree to the
      *      requested document, or {@code null} if failed.
-     * @see DocumentsProvider#findPath(String, String)
-     *
-     * {@hide}
+     * @see DocumentsProvider#findDocumentPath(String, String)
      */
-    public static List<String> findPath(ContentResolver resolver, Uri treeUri) {
+    public static List<String> findDocumentPath(ContentResolver resolver, Uri treeUri) {
         checkArgument(isTreeUri(treeUri), treeUri + " is not a tree uri.");
 
         final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
                 treeUri.getAuthority());
         try {
-            return findPath(client, treeUri).getPath();
+            return findDocumentPath(client, treeUri).getPath();
         } catch (Exception e) {
             Log.w(TAG, "Failed to find path", e);
             return null;
@@ -1355,15 +1337,17 @@
      * @param uri uri of the document which path is requested. It can be either a
      *          plain document uri or a tree uri.
      * @return the path of the document.
-     * @see DocumentsProvider#findPath(String, String)
+     * @see DocumentsProvider#findDocumentPath(String, String)
      *
      * {@hide}
      */
-    public static Path findPath(ContentProviderClient client, Uri uri) throws RemoteException {
+    public static Path findDocumentPath(ContentProviderClient client, Uri uri)
+            throws RemoteException {
+
         final Bundle in = new Bundle();
         in.putParcelable(DocumentsContract.EXTRA_URI, uri);
 
-        final Bundle out = client.call(METHOD_FIND_PATH, null, in);
+        final Bundle out = client.call(METHOD_FIND_DOCUMENT_PATH, null, in);
 
         return out.getParcelable(DocumentsContract.EXTRA_RESULT);
     }
@@ -1409,9 +1393,8 @@
     }
 
     /**
-     * Holds a path from a root to a particular document under it.
-     *
-     * @hide
+     * Holds a path from a document to a particular document under it. It
+     * may also contains the root ID where the path resides.
      */
     public static final class Path implements Parcelable {
 
@@ -1422,10 +1405,10 @@
          * Creates a Path.
          *
          * @param rootId the ID of the root. May be null.
-         * @param path the list of document ids from the parent document at
+         * @param path the list of document ID 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..96c2556 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -20,7 +20,7 @@
 import static android.provider.DocumentsContract.METHOD_CREATE_DOCUMENT;
 import static android.provider.DocumentsContract.METHOD_DELETE_DOCUMENT;
 import static android.provider.DocumentsContract.METHOD_EJECT_ROOT;
-import static android.provider.DocumentsContract.METHOD_FIND_PATH;
+import static android.provider.DocumentsContract.METHOD_FIND_DOCUMENT_PATH;
 import static android.provider.DocumentsContract.METHOD_IS_CHILD_DOCUMENT;
 import static android.provider.DocumentsContract.METHOD_MOVE_DOCUMENT;
 import static android.provider.DocumentsContract.METHOD_REMOVE_DOCUMENT;
@@ -350,17 +350,15 @@
      * document.
      *
      * @param childDocumentId the document which path is requested.
-     * @param parentDocumentId the document with which path starts if not null, or
-     *     null to indicate path to root is requested.
+     * @param parentDocumentId the document from which the path starts if not null,
+     *     or null to indicate a path from the root is requested.
      * @return the path of the requested document. If parentDocumentId is null
      *     returned root ID must not be null. If parentDocumentId is not null
      *     returned root ID must be null.
-     *
-     * @hide
      */
-    public Path findPath(String childDocumentId, @Nullable String parentDocumentId)
+    public Path findDocumentPath(String childDocumentId, @Nullable String parentDocumentId)
             throws FileNotFoundException {
-        throw new UnsupportedOperationException("findPath not supported.");
+        throw new UnsupportedOperationException("findDocumentPath not supported.");
     }
 
     /**
@@ -468,9 +466,6 @@
      * least {@link Document#COLUMN_DISPLAY_NAME} be matched in a
      * case-insensitive fashion.
      * <p>
-     * Only documents may be returned; directories are not supported in search
-     * results.
-     * <p>
      * If your provider is cloud-based, and you have some data cached or pinned
      * locally, you may return the local data immediately, setting
      * {@link DocumentsContract#EXTRA_LOADING} on the Cursor to indicate that
@@ -914,7 +909,7 @@
 
             // It's responsibility of the provider to revoke any grants, as the document may be
             // still attached to another parents.
-        } else if (METHOD_FIND_PATH.equals(method)) {
+        } else if (METHOD_FIND_DOCUMENT_PATH.equals(method)) {
             final boolean isTreeUri = isTreeUri(documentUri);
 
             if (isTreeUri) {
@@ -927,14 +922,20 @@
                     ? DocumentsContract.getTreeDocumentId(documentUri)
                     : null;
 
-            final Path path = findPath(documentId, parentDocumentId);
+            Path path = findDocumentPath(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 d3a978c..1b905a0 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5161,18 +5161,10 @@
                 "accessibility_display_magnification_scale";
 
         /**
-         * Setting that specifies whether the display magnification should be
-         * automatically updated. If this fearture is enabled the system will
-         * exit magnification mode or pan the viewport when a context change
-         * occurs. For example, on staring a new activity or rotating the screen,
-         * the system may zoom out so the user can see the new context he is in.
-         * Another example is on showing a window that is not visible in the
-         * magnified viewport the system may pan the viewport to make the window
-         * the has popped up so the user knows that the context has changed.
-         * Whether a screen magnification is performed is controlled by
-         * {@link #ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED}
+         * Unused mangnification setting
          *
          * @hide
+         * @deprecated
          */
         public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE =
                 "accessibility_display_magnification_auto_update";
@@ -6001,6 +5993,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
          */
@@ -6485,7 +6483,6 @@
             ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
             ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
             ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
-            ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE,
             ACCESSIBILITY_SCRIPT_INJECTION,
             ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
             ENABLED_ACCESSIBILITY_SERVICES,
@@ -8283,10 +8280,16 @@
                 BLUETOOTH_MAP_PRIORITY_PREFIX = "bluetooth_map_priority_";
         /** {@hide} */
         public static final String
+                BLUETOOTH_MAP_CLIENT_PRIORITY_PREFIX = "bluetooth_map_client_priority_";
+        /** {@hide} */
+        public static final String
                 BLUETOOTH_PBAP_CLIENT_PRIORITY_PREFIX = "bluetooth_pbap_client_priority_";
         /** {@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.
@@ -8464,6 +8467,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
          */
@@ -8472,6 +8483,14 @@
         }
 
         /**
+         * Get the key that retrieves a bluetooth map client priority.
+         * @hide
+         */
+        public static final String getBluetoothMapClientPriorityKey(String address) {
+            return BLUETOOTH_MAP_CLIENT_PRIORITY_PREFIX + address.toUpperCase(Locale.ROOT);
+        }
+
+        /**
          * Get the key that retrieves a bluetooth pbap client priority.
          * @hide
          */
@@ -8480,7 +8499,7 @@
         }
 
         /**
-         * Get the key that retrieves a bluetooth map priority.
+         * Get the key that retrieves a bluetooth sap priority.
          * @hide
          */
         public static final String getBluetoothSapPriorityKey(String address) {
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index e6f58f5..e606ebf 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -1037,60 +1037,6 @@
          * @hide */
         public static final int VISIBILITY_NO_OVERRIDE = NotificationManager.VISIBILITY_NO_OVERRIDE;
 
-        /**
-         * Value signifying that the user has not expressed an importance.
-         *
-         * This value is for persisting preferences, and should never be associated with
-         * an actual notification.
-         *
-         * @hide
-         */
-        public static final int IMPORTANCE_UNSPECIFIED = NotificationManager.IMPORTANCE_UNSPECIFIED;
-
-        /**
-         * A notification with no importance: shows nowhere, is blocked.
-         *
-         * @hide
-         */
-        public static final int IMPORTANCE_NONE = NotificationManager.IMPORTANCE_NONE;
-
-        /**
-         * Min notification importance: only shows in the shade, below the fold.
-         *
-         * @hide
-         */
-        public static final int IMPORTANCE_MIN = NotificationManager.IMPORTANCE_MIN;
-
-        /**
-         * Low notification importance: shows everywhere, but is not intrusive.
-         *
-         * @hide
-         */
-        public static final int IMPORTANCE_LOW = NotificationManager.IMPORTANCE_LOW;
-
-        /**
-         * Default notification importance: shows everywhere, allowed to makes noise,
-         * but does not visually intrude.
-         *
-         * @hide
-         */
-        public static final int IMPORTANCE_DEFAULT = NotificationManager.IMPORTANCE_DEFAULT;
-
-        /**
-         * Higher notification importance: shows everywhere, allowed to makes noise and peek.
-         *
-         * @hide
-         */
-        public static final int IMPORTANCE_HIGH = NotificationManager.IMPORTANCE_HIGH;
-
-        /**
-         * Highest notification importance: shows everywhere, allowed to makes noise, peek, and
-         * use full screen intents.
-         *
-         * @hide
-         */
-        public static final int IMPORTANCE_MAX = NotificationManager.IMPORTANCE_MAX;
-
         private String mKey;
         private int mRank = -1;
         private boolean mIsAmbient;
@@ -1192,7 +1138,7 @@
                 CharSequence explanation, String overrideGroupKey) {
             mKey = key;
             mRank = rank;
-            mIsAmbient = importance < IMPORTANCE_LOW;
+            mIsAmbient = importance < NotificationManager.IMPORTANCE_LOW;
             mMatchesInterruptionFilter = matchesInterruptionFilter;
             mVisibilityOverride = visibilityOverride;
             mSuppressedVisualEffects = suppressedVisualEffects;
@@ -1206,20 +1152,19 @@
          */
         public static String importanceToString(int importance) {
             switch (importance) {
-                case IMPORTANCE_UNSPECIFIED:
+                case NotificationManager.IMPORTANCE_UNSPECIFIED:
                     return "UNSPECIFIED";
-                case IMPORTANCE_NONE:
+                case NotificationManager.IMPORTANCE_NONE:
                     return "NONE";
-                case IMPORTANCE_MIN:
+                case NotificationManager.IMPORTANCE_MIN:
                     return "MIN";
-                case IMPORTANCE_LOW:
+                case NotificationManager.IMPORTANCE_LOW:
                     return "LOW";
-                case IMPORTANCE_DEFAULT:
+                case NotificationManager.IMPORTANCE_DEFAULT:
                     return "DEFAULT";
-                case IMPORTANCE_HIGH:
+                case NotificationManager.IMPORTANCE_HIGH:
+                case NotificationManager.IMPORTANCE_MAX:
                     return "HIGH";
-                case IMPORTANCE_MAX:
-                    return "MAX";
                 default:
                     return "UNKNOWN(" + String.valueOf(importance) + ")";
             }
@@ -1326,7 +1271,7 @@
             }
             Integer importance = mImportance.get(key);
             if (importance == null) {
-                return Ranking.IMPORTANCE_DEFAULT;
+                return NotificationManager.IMPORTANCE_DEFAULT;
             }
             return importance.intValue();
         }
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..a81eef8
--- /dev/null
+++ b/core/java/android/view/IPinnedStackController.aidl
@@ -0,0 +1,38 @@
+/**
+ * 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);
+
+    /**
+     * Notifies the controller that the desired snap mode is to the closest edge.
+     */
+    oneway void setSnapToEdge(boolean snapToEdge);
+}
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..bccb822 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;
@@ -84,8 +85,8 @@
     void pauseKeyDispatching(IBinder token);
     void resumeKeyDispatching(IBinder token);
     void setEventDispatching(boolean enabled);
-    void addWindowToken(IBinder token, int type);
-    void removeWindowToken(IBinder token);
+    void addWindowToken(IBinder token, int type, int displayId);
+    void removeWindowToken(IBinder token, int displayId);
     /**
      * Adds an application token to the specified task Id.
      * @param addPos The position to add the token to in the task.
@@ -182,7 +183,7 @@
     void notifyAppStopped(IBinder token);
     void startAppFreezingScreen(IBinder token, int configChanges);
     void stopAppFreezingScreen(IBinder token, boolean force);
-    void removeAppToken(IBinder token);
+    void removeAppToken(IBinder token, int displayId);
 
     /** Used by system ui to report that recents has shown itself. */
     void endProlongedAnimations();
@@ -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);
@@ -212,16 +213,6 @@
     void dismissKeyguard();
     void keyguardGoingAway(int flags);
 
-    /**
-     * Called to tell WindowManager whether the keyguard is animating in. While this property
-     * is true, WindowManager won't assume that the keyguard is opaque (eg. WindowAnimator won't
-     * force-hide windows just because keyguard is visible and WallpaperController won't occlude
-     * app windows with the system wallpaper.
-     *
-     * <p>Requires CONTROL_KEYGUARD permission</p>
-     */
-    void setKeyguardAnimatingIn(boolean animating);
-
     // Requires INTERACT_ACROSS_USERS_FULL permission
     void setSwitchingUser(boolean switching);
 
@@ -426,6 +417,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 +450,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/RenderNode.java b/core/java/android/view/RenderNode.java
index 51d818b..7a3c95e 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -26,8 +26,6 @@
 
 import dalvik.annotation.optimization.FastNative;
 
-import libcore.util.NativeAllocationRegistry;
-
 /**
  * <p>A display list records a series of graphics related operations and can replay
  * them later. Display lists are usually built by recording operations on a
@@ -132,36 +130,46 @@
  */
 public class RenderNode {
 
- // Use a Holder to allow static initialization in the boot image.
-    private static class NoImagePreloadHolder {
-        public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
-            RenderNode.class.getClassLoader(), nGetNativeFinalizer(), 1024);
-    }
-
     private boolean mValid;
     // Do not access directly unless you are ThreadedRenderer
-    final long mNativeRenderNode;
+    long mNativeRenderNode;
     private final View mOwningView;
 
     private RenderNode(String name, View owningView) {
         mNativeRenderNode = nCreate(name);
-        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
         mOwningView = owningView;
-        if (mOwningView instanceof SurfaceView) {
-            nRequestPositionUpdates(mNativeRenderNode, (SurfaceView) mOwningView);
-        }
     }
 
     /**
      * @see RenderNode#adopt(long)
      */
     private RenderNode(long nativePtr) {
-        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, nativePtr);
         mNativeRenderNode = nativePtr;
         mOwningView = null;
     }
 
     /**
+     * Immediately destroys the RenderNode
+     * Only suitable for testing/benchmarking where waiting for the GC/finalizer
+     * is not feasible.
+     */
+    public void destroy() {
+        if (mNativeRenderNode != 0) {
+            nFinalize(mNativeRenderNode);
+            mNativeRenderNode = 0;
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            destroy();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
      * Creates a new RenderNode that can be used to record batches of
      * drawing operations, and store / apply render properties when drawn.
      *
@@ -183,6 +191,13 @@
         return new RenderNode(nativePtr);
     }
 
+    /**
+     * Enable callbacks for position changes.
+     */
+    public void requestPositionUpdates(SurfaceView view) {
+        nRequestPositionUpdates(mNativeRenderNode, view);
+    }
+
 
     /**
      * Starts recording a display list for the render node. All
@@ -784,9 +799,6 @@
      */
     void onRenderNodeDetached() {
         discardDisplayList();
-        if (mOwningView != null) {
-            mOwningView.onRenderNodeDetached(this);
-        }
     }
 
     ///////////////////////////////////////////////////////////////////////////
@@ -823,6 +835,7 @@
 
     // Intentionally not static because it acquires a reference to 'this'
     private native long nCreate(String name);
+    private native void nFinalize(long renderNode);
 
     private static native long nGetNativeFinalizer();
     private static native void nSetDisplayList(long renderNode, long newData);
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..d46910c 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -207,6 +207,7 @@
 
     public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+        mRenderNode.requestPositionUpdates(this);
 
         setWillNotDraw(true);
     }
@@ -957,7 +958,7 @@
          */
         @Override
         public Canvas lockCanvas() {
-            return internalLockCanvas(null);
+            return internalLockCanvas(null, false);
         }
 
         /**
@@ -977,10 +978,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 +995,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/View.java b/core/java/android/view/View.java
index 20876a9..441f330 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7194,7 +7194,6 @@
 
     /**
      * Gets the unique identifier of this view on the screen for accessibility purposes.
-     * If this {@link View} is not attached to any window, {@value #NO_ID} is returned.
      *
      * @return The view accessibility id.
      *
@@ -16186,13 +16185,6 @@
     }
 
     /**
-     * Called when the passed RenderNode is removed from the draw tree
-     * @hide
-     */
-    public void onRenderNodeDetached(RenderNode renderNode) {
-    }
-
-    /**
      * <p>Calling this method is equivalent to calling <code>getDrawingCache(false)</code>.</p>
      *
      * @return A non-scaled bitmap representing this view or null if cache is disabled.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 87b330d..5a6cf7d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -19,7 +19,6 @@
 import static android.view.WindowCallbacks.RESIZE_MODE_DOCKED_DIVIDER;
 import static android.view.WindowCallbacks.RESIZE_MODE_FREEFORM;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
@@ -3542,20 +3541,7 @@
                     mWinFrame.bottom = t + h;
 
                     mPendingBackDropFrame.set(mWinFrame);
-
-                    // Suppress layouts during resizing - a correct layout will happen when resizing
-                    // is done, and this just increases system load.
-                    boolean isDockedDivider = mWindowAttributes.type == TYPE_DOCK_DIVIDER;
-                    boolean suppress = (mDragResizing && mResizeMode == RESIZE_MODE_DOCKED_DIVIDER)
-                            || isDockedDivider;
-                    if (!suppress) {
-                        if (mView != null) {
-                            forceLayout(mView);
-                        }
-                        requestLayout();
-                    } else {
-                        maybeHandleWindowMove(mWinFrame);
-                    }
+                    maybeHandleWindowMove(mWinFrame);
                 }
                 break;
             case MSG_WINDOW_FOCUS_CHANGED: {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index f14acaa..2971280 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -249,48 +249,92 @@
          * @see #TYPE_INPUT_METHOD_DIALOG
          */
         @ViewDebug.ExportedProperty(mapping = {
-            @ViewDebug.IntToString(from = TYPE_BASE_APPLICATION, to = "TYPE_BASE_APPLICATION"),
-            @ViewDebug.IntToString(from = TYPE_APPLICATION, to = "TYPE_APPLICATION"),
-            @ViewDebug.IntToString(from = TYPE_APPLICATION_STARTING, to = "TYPE_APPLICATION_STARTING"),
-            @ViewDebug.IntToString(from = TYPE_DRAWN_APPLICATION, to = "TYPE_DRAWN_APPLICATION"),
-            @ViewDebug.IntToString(from = TYPE_APPLICATION_PANEL, to = "TYPE_APPLICATION_PANEL"),
-            @ViewDebug.IntToString(from = TYPE_APPLICATION_MEDIA, to = "TYPE_APPLICATION_MEDIA"),
-            @ViewDebug.IntToString(from = TYPE_APPLICATION_SUB_PANEL, to = "TYPE_APPLICATION_SUB_PANEL"),
-            @ViewDebug.IntToString(from = TYPE_APPLICATION_ABOVE_SUB_PANEL, to = "TYPE_APPLICATION_ABOVE_SUB_PANEL"),
-            @ViewDebug.IntToString(from = TYPE_APPLICATION_ATTACHED_DIALOG, to = "TYPE_APPLICATION_ATTACHED_DIALOG"),
-            @ViewDebug.IntToString(from = TYPE_APPLICATION_MEDIA_OVERLAY, to = "TYPE_APPLICATION_MEDIA_OVERLAY"),
-            @ViewDebug.IntToString(from = TYPE_STATUS_BAR, to = "TYPE_STATUS_BAR"),
-            @ViewDebug.IntToString(from = TYPE_SEARCH_BAR, to = "TYPE_SEARCH_BAR"),
-            @ViewDebug.IntToString(from = TYPE_PHONE, to = "TYPE_PHONE"),
-            @ViewDebug.IntToString(from = TYPE_SYSTEM_ALERT, to = "TYPE_SYSTEM_ALERT"),
-            @ViewDebug.IntToString(from = TYPE_TOAST, to = "TYPE_TOAST"),
-            @ViewDebug.IntToString(from = TYPE_SYSTEM_OVERLAY, to = "TYPE_SYSTEM_OVERLAY"),
-            @ViewDebug.IntToString(from = TYPE_PRIORITY_PHONE, to = "TYPE_PRIORITY_PHONE"),
-            @ViewDebug.IntToString(from = TYPE_SYSTEM_DIALOG, to = "TYPE_SYSTEM_DIALOG"),
-            @ViewDebug.IntToString(from = TYPE_KEYGUARD_DIALOG, to = "TYPE_KEYGUARD_DIALOG"),
-            @ViewDebug.IntToString(from = TYPE_SYSTEM_ERROR, to = "TYPE_SYSTEM_ERROR"),
-            @ViewDebug.IntToString(from = TYPE_INPUT_METHOD, to = "TYPE_INPUT_METHOD"),
-            @ViewDebug.IntToString(from = TYPE_INPUT_METHOD_DIALOG, to = "TYPE_INPUT_METHOD_DIALOG"),
-            @ViewDebug.IntToString(from = TYPE_WALLPAPER, to = "TYPE_WALLPAPER"),
-            @ViewDebug.IntToString(from = TYPE_STATUS_BAR_PANEL, to = "TYPE_STATUS_BAR_PANEL"),
-            @ViewDebug.IntToString(from = TYPE_SECURE_SYSTEM_OVERLAY, to = "TYPE_SECURE_SYSTEM_OVERLAY"),
-            @ViewDebug.IntToString(from = TYPE_DRAG, to = "TYPE_DRAG"),
-            @ViewDebug.IntToString(from = TYPE_STATUS_BAR_SUB_PANEL, to = "TYPE_STATUS_BAR_SUB_PANEL"),
-            @ViewDebug.IntToString(from = TYPE_POINTER, to = "TYPE_POINTER"),
-            @ViewDebug.IntToString(from = TYPE_NAVIGATION_BAR, to = "TYPE_NAVIGATION_BAR"),
-            @ViewDebug.IntToString(from = TYPE_VOLUME_OVERLAY, to = "TYPE_VOLUME_OVERLAY"),
-            @ViewDebug.IntToString(from = TYPE_BOOT_PROGRESS, to = "TYPE_BOOT_PROGRESS"),
-            @ViewDebug.IntToString(from = TYPE_INPUT_CONSUMER, to = "TYPE_INPUT_CONSUMER"),
-            @ViewDebug.IntToString(from = TYPE_DREAM, to = "TYPE_DREAM"),
-            @ViewDebug.IntToString(from = TYPE_NAVIGATION_BAR_PANEL, to = "TYPE_NAVIGATION_BAR_PANEL"),
-            @ViewDebug.IntToString(from = TYPE_DISPLAY_OVERLAY, to = "TYPE_DISPLAY_OVERLAY"),
-            @ViewDebug.IntToString(from = TYPE_MAGNIFICATION_OVERLAY, to = "TYPE_MAGNIFICATION_OVERLAY"),
-            @ViewDebug.IntToString(from = TYPE_PRIVATE_PRESENTATION, to = "TYPE_PRIVATE_PRESENTATION"),
-            @ViewDebug.IntToString(from = TYPE_VOICE_INTERACTION, to = "TYPE_VOICE_INTERACTION"),
-            @ViewDebug.IntToString(from = TYPE_VOICE_INTERACTION_STARTING, to = "TYPE_VOICE_INTERACTION_STARTING"),
-            @ViewDebug.IntToString(from = TYPE_DOCK_DIVIDER, to = "TYPE_DOCK_DIVIDER"),
-            @ViewDebug.IntToString(from = TYPE_QS_DIALOG, to = "TYPE_QS_DIALOG"),
-            @ViewDebug.IntToString(from = TYPE_SCREENSHOT, to = "TYPE_SCREENSHOT")
+                @ViewDebug.IntToString(from = TYPE_BASE_APPLICATION,
+                        to = "TYPE_BASE_APPLICATION"),
+                @ViewDebug.IntToString(from = TYPE_APPLICATION,
+                        to = "TYPE_APPLICATION"),
+                @ViewDebug.IntToString(from = TYPE_APPLICATION_STARTING,
+                        to = "TYPE_APPLICATION_STARTING"),
+                @ViewDebug.IntToString(from = TYPE_DRAWN_APPLICATION,
+                        to = "TYPE_DRAWN_APPLICATION"),
+                @ViewDebug.IntToString(from = TYPE_APPLICATION_PANEL,
+                        to = "TYPE_APPLICATION_PANEL"),
+                @ViewDebug.IntToString(from = TYPE_APPLICATION_MEDIA,
+                        to = "TYPE_APPLICATION_MEDIA"),
+                @ViewDebug.IntToString(from = TYPE_APPLICATION_SUB_PANEL,
+                        to = "TYPE_APPLICATION_SUB_PANEL"),
+                @ViewDebug.IntToString(from = TYPE_APPLICATION_ABOVE_SUB_PANEL,
+                        to = "TYPE_APPLICATION_ABOVE_SUB_PANEL"),
+                @ViewDebug.IntToString(from = TYPE_APPLICATION_ATTACHED_DIALOG,
+                        to = "TYPE_APPLICATION_ATTACHED_DIALOG"),
+                @ViewDebug.IntToString(from = TYPE_APPLICATION_MEDIA_OVERLAY,
+                        to = "TYPE_APPLICATION_MEDIA_OVERLAY"),
+                @ViewDebug.IntToString(from = TYPE_STATUS_BAR,
+                        to = "TYPE_STATUS_BAR"),
+                @ViewDebug.IntToString(from = TYPE_SEARCH_BAR,
+                        to = "TYPE_SEARCH_BAR"),
+                @ViewDebug.IntToString(from = TYPE_PHONE,
+                        to = "TYPE_PHONE"),
+                @ViewDebug.IntToString(from = TYPE_SYSTEM_ALERT,
+                        to = "TYPE_SYSTEM_ALERT"),
+                @ViewDebug.IntToString(from = TYPE_TOAST,
+                        to = "TYPE_TOAST"),
+                @ViewDebug.IntToString(from = TYPE_SYSTEM_OVERLAY,
+                        to = "TYPE_SYSTEM_OVERLAY"),
+                @ViewDebug.IntToString(from = TYPE_PRIORITY_PHONE,
+                        to = "TYPE_PRIORITY_PHONE"),
+                @ViewDebug.IntToString(from = TYPE_SYSTEM_DIALOG,
+                        to = "TYPE_SYSTEM_DIALOG"),
+                @ViewDebug.IntToString(from = TYPE_KEYGUARD_DIALOG,
+                        to = "TYPE_KEYGUARD_DIALOG"),
+                @ViewDebug.IntToString(from = TYPE_SYSTEM_ERROR,
+                        to = "TYPE_SYSTEM_ERROR"),
+                @ViewDebug.IntToString(from = TYPE_INPUT_METHOD,
+                        to = "TYPE_INPUT_METHOD"),
+                @ViewDebug.IntToString(from = TYPE_INPUT_METHOD_DIALOG,
+                        to = "TYPE_INPUT_METHOD_DIALOG"),
+                @ViewDebug.IntToString(from = TYPE_WALLPAPER,
+                        to = "TYPE_WALLPAPER"),
+                @ViewDebug.IntToString(from = TYPE_STATUS_BAR_PANEL,
+                        to = "TYPE_STATUS_BAR_PANEL"),
+                @ViewDebug.IntToString(from = TYPE_SECURE_SYSTEM_OVERLAY,
+                        to = "TYPE_SECURE_SYSTEM_OVERLAY"),
+                @ViewDebug.IntToString(from = TYPE_DRAG,
+                        to = "TYPE_DRAG"),
+                @ViewDebug.IntToString(from = TYPE_STATUS_BAR_SUB_PANEL,
+                        to = "TYPE_STATUS_BAR_SUB_PANEL"),
+                @ViewDebug.IntToString(from = TYPE_POINTER,
+                        to = "TYPE_POINTER"),
+                @ViewDebug.IntToString(from = TYPE_NAVIGATION_BAR,
+                        to = "TYPE_NAVIGATION_BAR"),
+                @ViewDebug.IntToString(from = TYPE_VOLUME_OVERLAY,
+                        to = "TYPE_VOLUME_OVERLAY"),
+                @ViewDebug.IntToString(from = TYPE_BOOT_PROGRESS,
+                        to = "TYPE_BOOT_PROGRESS"),
+                @ViewDebug.IntToString(from = TYPE_INPUT_CONSUMER,
+                        to = "TYPE_INPUT_CONSUMER"),
+                @ViewDebug.IntToString(from = TYPE_DREAM,
+                        to = "TYPE_DREAM"),
+                @ViewDebug.IntToString(from = TYPE_NAVIGATION_BAR_PANEL,
+                        to = "TYPE_NAVIGATION_BAR_PANEL"),
+                @ViewDebug.IntToString(from = TYPE_DISPLAY_OVERLAY,
+                        to = "TYPE_DISPLAY_OVERLAY"),
+                @ViewDebug.IntToString(from = TYPE_MAGNIFICATION_OVERLAY,
+                        to = "TYPE_MAGNIFICATION_OVERLAY"),
+                @ViewDebug.IntToString(from = TYPE_PRESENTATION,
+                        to = "TYPE_PRESENTATION"),
+                @ViewDebug.IntToString(from = TYPE_PRIVATE_PRESENTATION,
+                        to = "TYPE_PRIVATE_PRESENTATION"),
+                @ViewDebug.IntToString(from = TYPE_VOICE_INTERACTION,
+                        to = "TYPE_VOICE_INTERACTION"),
+                @ViewDebug.IntToString(from = TYPE_VOICE_INTERACTION_STARTING,
+                        to = "TYPE_VOICE_INTERACTION_STARTING"),
+                @ViewDebug.IntToString(from = TYPE_DOCK_DIVIDER,
+                        to = "TYPE_DOCK_DIVIDER"),
+                @ViewDebug.IntToString(from = TYPE_QS_DIALOG,
+                        to = "TYPE_QS_DIALOG"),
+                @ViewDebug.IntToString(from = TYPE_SCREENSHOT,
+                        to = "TYPE_SCREENSHOT")
         })
         public int type;
 
@@ -599,13 +643,6 @@
         public static final int TYPE_MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW+27;
 
         /**
-         * Window type: keyguard scrim window. Shows if keyguard needs to be restarted.
-         * In multiuser systems shows on all users' windows.
-         * @hide
-         */
-        public static final int TYPE_KEYGUARD_SCRIM           = FIRST_SYSTEM_WINDOW+29;
-
-        /**
          * Window type: Window for Presentation on top of private
          * virtual display.
          */
@@ -658,6 +695,13 @@
         public static final int TYPE_SCREENSHOT = FIRST_SYSTEM_WINDOW + 36;
 
         /**
+         * Window type: Window for Presentation on an external display.
+         * @see android.app.Presentation
+         * @hide
+         */
+        public static final int TYPE_PRESENTATION = FIRST_SYSTEM_WINDOW + 37;
+
+        /**
          * End of types of system windows.
          */
         public static final int LAST_SYSTEM_WINDOW      = 2999;
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index 653e583..6e2a92c 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -99,19 +99,30 @@
 
         /**
          * Called when a pending app transition gets cancelled.
+         *
+         * @param transit transition type indicating what kind of transition got cancelled
          */
-        public void onAppTransitionCancelledLocked() {}
+        public void onAppTransitionCancelledLocked(int transit) {}
 
         /**
          * Called when an app transition gets started
          *
+         * @param transit transition type indicating what kind of transition gets run, must be one
+         *                of AppTransition.TRANSIT_* values
          * @param openToken the token for the opening app
          * @param closeToken the token for the closing app
          * @param openAnimation the animation for the opening app
          * @param closeAnimation the animation for the closing app
+         *
+         * @return Return any bit set of {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_LAYOUT},
+         * {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_CONFIG},
+         * {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_WALLPAPER},
+         * or {@link WindowManagerPolicy#FINISH_LAYOUT_REDO_ANIM}.
          */
-        public void onAppTransitionStartingLocked(IBinder openToken, IBinder closeToken,
-                Animation openAnimation, Animation closeAnimation) {}
+        public int onAppTransitionStartingLocked(int transit, IBinder openToken, IBinder closeToken,
+                Animation openAnimation, Animation closeAnimation) {
+            return 0;
+        }
 
         /**
          * Called when an app transition is finished running.
@@ -230,16 +241,19 @@
      *
      * @param token The token to add.
      * @param type The window type.
+     * @param displayId The display to add the token to.
      */
-    public abstract void addWindowToken(android.os.IBinder token, int type);
+    public abstract void addWindowToken(android.os.IBinder token, int type, int displayId);
 
     /**
      * Removes a window token.
      *
      * @param token The toke to remove.
      * @param removeWindows Whether to also remove the windows associated with the token.
+     * @param displayId The display to remove the token from.
      */
-    public abstract void removeWindowToken(android.os.IBinder token, boolean removeWindows);
+    public abstract void removeWindowToken(android.os.IBinder token, boolean removeWindows,
+            int displayId);
 
     /**
      * Registers a listener to be notified about app transition events.
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index a6be493..8a9bb33 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -136,10 +136,10 @@
             throws RemoteException;
 
     /**
-     * @return true if windows with FLAG_DISMISS_KEYGUARD should be allowed to show even if
-     *         the keyguard is locked.
+     * Called when the Keyguard occluded state changed.
+     * @param occluded Whether Keyguard is currently occluded or not.
      */
-    boolean canShowDismissingWindowWhileLockedLw();
+    void onKeyguardOccludedChangedLw(boolean occluded);
 
     /**
      * Interface to the Window Manager state associated with a particular
@@ -339,13 +339,6 @@
         boolean isVisibleLw();
 
         /**
-         * Like {@link #isVisibleLw}, but also counts a window that is currently
-         * "hidden" behind the keyguard as visible.  This allows us to apply
-         * things like window flags that impact the keyguard.
-         */
-        boolean isVisibleOrBehindKeyguardLw();
-
-        /**
          * Is this window currently visible to the user on-screen?  It is
          * displayed either if it is visible or it is currently running an
          * animation before no longer being visible.  Must be called with the
@@ -424,6 +417,10 @@
         public boolean isInMultiWindowMode();
 
         public int getRotationAnimationHint();
+
+        public boolean isInputMethodWindow();
+
+        public int getDisplayId();
     }
 
     /**
@@ -509,9 +506,9 @@
         void getStackBounds(int stackId, Rect outBounds);
 
         /**
-         * Overrides all currently playing app animations with {@param a}.
+         * Notifies window manager that {@link #isShowingDreamLw} has changed.
          */
-        void overridePlayingAppAnimationsLw(Animation a);
+        void notifyShowingDreamChanged();
     }
 
     public interface PointerEventListener {
@@ -699,31 +696,15 @@
             int uiMode);
 
     /**
-     * Return whether the given window is forcibly hiding all windows except windows with
-     * FLAG_SHOW_WHEN_LOCKED set.  Typically returns true for the keyguard.
-     */
-    public boolean isForceHiding(WindowManager.LayoutParams attrs);
-
-
-    /**
-     * Return whether the given window can become one that passes isForceHiding() test.
-     * Typically returns true for the StatusBar.
+     * Return whether the given window can become the Keyguard window. Typically returns true for
+     * the StatusBar.
      */
     public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs);
 
     /**
-     * Determine if a window that is behind one that is force hiding
-     * (as determined by {@link #isForceHiding}) should actually be hidden.
-     * For example, typically returns false for the status bar.  Be careful
-     * to return false for any window that you may hide yourself, since this
-     * will conflict with what you set.
+     * @return whether {@param win} can be hidden by Keyguard
      */
-    public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs);
-
-    /**
-     * Return the window that is hiding the keyguard, if such a thing exists.
-     */
-    public WindowState getWinShowWhenLockedLw();
+    public boolean canBeHiddenByKeyguardLw(WindowState win);
 
     /**
      * Called when the system would like to show a UI to indicate that an
@@ -834,16 +815,16 @@
             boolean forceDefault);
 
     /**
-     * Create and return an animation to re-display a force hidden window.
+     * Create and return an animation to re-display a window that was force hidden by Keyguard.
      */
-    public Animation createForceHideEnterAnimation(boolean onWallpaper,
+    public Animation createHiddenByKeyguardExit(boolean onWallpaper,
             boolean goingToNotificationShade);
 
     /**
-     * Create and return an animation to let the wallpaper disappear after being shown on a force
-     * hiding window.
+     * Create and return an animation to let the wallpaper disappear after being shown behind
+     * Keyguard.
      */
-    public Animation createForceHideWallpaperExitAnimation(boolean goingToNotificationShade);
+    public Animation createKeyguardWallpaperExit(boolean goingToNotificationShade);
 
     /**
      * Called from the input reader thread before a key is enqueued.
@@ -1000,7 +981,7 @@
      * @param attached For sub-windows, the window it is attached to. Otherwise null.
      */
     public void applyPostLayoutPolicyLw(WindowState win,
-            WindowManager.LayoutParams attrs, WindowState attached);
+            WindowManager.LayoutParams attrs, WindowState attached, WindowState imeTarget);
 
     /**
      * Called following layout of all windows and after policy has been applied
@@ -1147,11 +1128,11 @@
     public boolean isKeyguardSecure(int userId);
 
     /**
-     * Return whether the keyguard is on.
+     * Return whether the keyguard is currently occluded.
      *
-     * @return true if in keyguard is on.
+     * @return true if in keyguard is occluded, false otherwise
      */
-    public boolean isKeyguardShowingOrOccluded();
+    public boolean isKeyguardOccluded();
 
     /**
      * @return true if in keyguard is on and not occluded.
@@ -1159,6 +1140,11 @@
     public boolean isKeyguardShowingAndNotOccluded();
 
     /**
+     * @return whether Keyguard is in trusted state and can be dismissed without credentials
+     */
+    public boolean isKeyguardTrustedLw();
+
+    /**
      * inKeyguardRestrictedKeyInputMode
      *
      * if keyguard screen is showing or in restricted key input mode (i.e. in
@@ -1175,11 +1161,6 @@
     public void dismissKeyguardLw();
 
     /**
-     * Notifies the keyguard that the activity has drawn it was waiting for.
-     */
-    public void notifyActivityDrawnForKeyguardLw();
-
-    /**
      * Ask the policy whether the Keyguard has drawn. If the Keyguard is disabled, this method
      * returns true as soon as we know that Keyguard is disabled.
      *
@@ -1187,6 +1168,8 @@
      */
     public boolean isKeyguardDrawnLw();
 
+    public boolean isShowingDreamLw();
+
     /**
      * Given an orientation constant, returns the appropriate surface rotation,
      * taking into account sensors, docking mode, rotation lock, and other factors.
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index 71e77c4..2829744 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -35,16 +35,16 @@
  */
 interface IAccessibilityManager {
 
-    int addClient(IAccessibilityManagerClient client, int userId);
+    oneway void interrupt(int userId);
 
-    void sendAccessibilityEvent(in AccessibilityEvent uiEvent, int userId);
+    oneway void sendAccessibilityEvent(in AccessibilityEvent uiEvent, int userId);
+
+    int addClient(IAccessibilityManagerClient client, int userId);
 
     List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(int userId);
 
     List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType, int userId);
 
-    void interrupt(int userId);
-
     int addAccessibilityInteractionConnection(IWindow windowToken,
         in IAccessibilityInteractionConnection connection, int userId);
 
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/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/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..b2a77d0 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -320,6 +320,18 @@
             return this;
         }
 
+        public boolean prefersAsyncApply() {
+            return false;
+        }
+
+        /**
+         * Overridden by subclasses which have (or inherit) an ApplicationInfo instance
+         * as member variable
+         */
+        public boolean hasSameAppInfo(ApplicationInfo parentInfo) {
+            return true;
+        }
+
         int viewId;
     }
 
@@ -715,20 +727,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 +1482,11 @@
             // unique from the standpoint of merging.
             return "ReflectionAction" + this.methodName + this.type;
         }
+
+        @Override
+        public boolean prefersAsyncApply() {
+            return this.type == URI || this.type == ICON;
+        }
     }
 
     /**
@@ -1503,11 +1529,11 @@
             }
         }
 
-        public ViewGroupAction(Parcel parcel, BitmapCache bitmapCache) {
+        ViewGroupAction(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info) {
             viewId = parcel.readInt();
             boolean nestedViewsNull = parcel.readInt() == 0;
             if (!nestedViewsNull) {
-                nestedViews = new RemoteViews(parcel, bitmapCache);
+                nestedViews = new RemoteViews(parcel, bitmapCache, info);
             } else {
                 nestedViews = null;
             }
@@ -1526,6 +1552,13 @@
         }
 
         @Override
+        public boolean hasSameAppInfo(ApplicationInfo parentInfo) {
+            return nestedViews != null
+                    && nestedViews.mApplication.packageName.equals(parentInfo.packageName)
+                    && nestedViews.mApplication.uid == parentInfo.uid;
+        }
+
+        @Override
         public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
             final Context context = root.getContext();
             final ViewGroup target = (ViewGroup) root.findViewById(viewId);
@@ -1598,6 +1631,11 @@
             return MERGE_APPEND;
         }
 
+        @Override
+        public boolean prefersAsyncApply() {
+            return nestedViews != null && nestedViews.prefersAsyncApply();
+        }
+
         RemoteViews nestedViews;
 
         public final static int TAG = 4;
@@ -1749,6 +1787,11 @@
             return copy;
         }
 
+        @Override
+        public boolean prefersAsyncApply() {
+            return useIcons;
+        }
+
         public String getActionName() {
             return "TextViewDrawableAction";
         }
@@ -2167,10 +2210,10 @@
      * @param parcel
      */
     public RemoteViews(Parcel parcel) {
-        this(parcel, null);
+        this(parcel, null, null);
     }
 
-    private RemoteViews(Parcel parcel, BitmapCache bitmapCache) {
+    private RemoteViews(Parcel parcel, BitmapCache bitmapCache, ApplicationInfo info) {
         int mode = parcel.readInt();
 
         // We only store a bitmap cache in the root of the RemoteViews.
@@ -2182,7 +2225,8 @@
         }
 
         if (mode == MODE_NORMAL) {
-            mApplication = parcel.readParcelable(null);
+            mApplication = parcel.readInt() == 0 ? info :
+                    ApplicationInfo.CREATOR.createFromParcel(parcel);
             mLayoutId = parcel.readInt();
             mIsWidgetCollectionChild = parcel.readInt() == 1;
 
@@ -2202,7 +2246,7 @@
                             mActions.add(new ReflectionAction(parcel));
                             break;
                         case ViewGroupAction.TAG:
-                            mActions.add(new ViewGroupAction(parcel, mBitmapCache));
+                            mActions.add(new ViewGroupAction(parcel, mBitmapCache, mApplication));
                             break;
                         case ReflectionActionWithoutParams.TAG:
                             mActions.add(new ReflectionActionWithoutParams(parcel));
@@ -2250,8 +2294,8 @@
             }
         } else {
             // MODE_HAS_LANDSCAPE_AND_PORTRAIT
-            mLandscape = new RemoteViews(parcel, mBitmapCache);
-            mPortrait = new RemoteViews(parcel, mBitmapCache);
+            mLandscape = new RemoteViews(parcel, mBitmapCache, info);
+            mPortrait = new RemoteViews(parcel, mBitmapCache, mLandscape.mApplication);
             mApplication = mPortrait.mApplication;
             mLayoutId = mPortrait.getLayoutId();
         }
@@ -2271,11 +2315,11 @@
         // Do not parcel the Bitmap cache - doing so creates an expensive copy of all bitmaps.
         // Instead pretend we're not owning the cache while parceling.
         mIsRoot = false;
-        writeToParcel(p, 0);
+        writeToParcel(p, PARCELABLE_ELIDE_DUPLICATES);
         p.setDataPosition(0);
         mIsRoot = true;
 
-        RemoteViews rv = new RemoteViews(p, mBitmapCache.clone());
+        RemoteViews rv = new RemoteViews(p, mBitmapCache.clone(), mApplication);
         rv.mIsRoot = true;
 
         p.recycle();
@@ -3443,6 +3487,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)
@@ -3490,7 +3552,12 @@
             if (mIsRoot) {
                 mBitmapCache.writeBitmapsToParcel(dest, flags);
             }
-            dest.writeParcelable(mApplication, flags);
+            if (!mIsRoot && (flags & PARCELABLE_ELIDE_DUPLICATES) != 0) {
+                dest.writeInt(0);
+            } else {
+                dest.writeInt(1);
+                mApplication.writeToParcel(dest, flags);
+            }
             dest.writeInt(mLayoutId);
             dest.writeInt(mIsWidgetCollectionChild ? 1 : 0);
             int count;
@@ -3502,7 +3569,8 @@
             dest.writeInt(count);
             for (int i=0; i<count; i++) {
                 Action a = mActions.get(i);
-                a.writeToParcel(dest, 0);
+                a.writeToParcel(dest, a.hasSameAppInfo(mApplication)
+                        ? PARCELABLE_ELIDE_DUPLICATES : 0);
             }
         } else {
             dest.writeInt(MODE_HAS_LANDSCAPE_AND_PORTRAIT);
@@ -3512,7 +3580,8 @@
                 mBitmapCache.writeBitmapsToParcel(dest, flags);
             }
             mLandscape.writeToParcel(dest, flags);
-            mPortrait.writeToParcel(dest, flags);
+            // Both RemoteViews already share the same package and user
+            mPortrait.writeToParcel(dest, flags | PARCELABLE_ELIDE_DUPLICATES);
         }
     }
 
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 2f9c97b..9c48cf8 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -672,6 +672,11 @@
     public static void preloadFontCache() {
         Paint p = new Paint();
         p.setAntiAlias(true);
+        // Ensure that the Typeface is loaded here.
+        // Typically, Typeface is preloaded by zygote but not on all devices, e.g. Android Auto.
+        // So, sets Typeface.DEFAULT explicitly here for ensuring that the Typeface is loaded here
+        // since Paint.measureText can not be called without Typeface static initializer.
+        p.setTypeface(Typeface.DEFAULT);
         // We don't care about the result, just the side-effect of measuring.
         p.measureText("H");
     }
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index c851e4e..e57a224 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -114,7 +114,7 @@
 
                 // Bring up crash dialog, wait for it to be dismissed
                 ActivityManagerNative.getDefault().handleApplicationCrash(
-                        mApplicationObject, new ApplicationErrorReport.CrashInfo(e));
+                        mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e));
             } catch (Throwable t2) {
                 if (t2 instanceof DeadObjectException) {
                     // System process is dead; ignore
@@ -380,7 +380,8 @@
     public static void wtf(String tag, Throwable t, boolean system) {
         try {
             if (ActivityManagerNative.getDefault().handleApplicationWtf(
-                    mApplicationObject, tag, system, new ApplicationErrorReport.CrashInfo(t))) {
+                    mApplicationObject, tag, system,
+                    new ApplicationErrorReport.ParcelableCrashInfo(t))) {
                 // The Activity Manager has already written us off -- now exit.
                 Process.killProcess(Process.myPid());
                 System.exit(10);
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 12d4be3..e1118d8 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -258,7 +258,7 @@
                     continue;
                 }
 
-                Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClass " + line);
+                Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
                 try {
                     if (false) {
                         Log.v(TAG, "Preloading " + line + "...");
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index 50dd33a..788103d 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -34,7 +34,6 @@
 
     void addStateMonitorCallback(IKeyguardStateCallback callback);
     void verifyUnlock(IKeyguardExitCallback callback);
-    void keyguardDone(boolean authenticated, boolean wakeup);
     void dismiss(boolean allowWhileOccluded);
     void onDreamingStarted();
     void onDreamingStopped();
@@ -93,10 +92,4 @@
      * @param fadeoutDuration the duration of the exit animation, in milliseconds
      */
     void startKeyguardExitAnimation(long startTime, long fadeoutDuration);
-
-    /**
-     * Notifies the Keyguard that the activity that was starting has now been drawn and it's safe
-     * to start the keyguard dismiss sequence.
-     */
-    void onActivityDrawn();
 }
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..cbacf26
--- /dev/null
+++ b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
@@ -0,0 +1,256 @@
+/*
+ * 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 mDefaultSnapMode = SNAP_MODE_CORNERS_ONLY;
+    private int mSnapMode = mDefaultSnapMode;
+
+    private Scroller mScroller;
+    private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
+
+    public PipSnapAlgorithm(Context context) {
+        mContext = context;
+        onConfigurationChanged();
+    }
+
+    /**
+     * Updates the snap algorithm when the configuration changes.
+     */
+    public void onConfigurationChanged() {
+        mOrientation = mContext.getResources().getConfiguration().orientation;
+        calculateSnapTargets();
+    }
+
+    /**
+     * Enables snapping to the closest edge.
+     */
+    public void setSnapToEdge(boolean snapToEdge) {
+        mSnapMode = snapToEdge ? SNAP_MODE_EDGE : mDefaultSnapMode;
+    }
+
+    /**
+     * @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
+            snapRectToClosestEdge(stackBounds, movementBounds, newBounds);
+        } 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 returns a fraction that describes where along the {@param movementBounds} the
+     *         {@param stackBounds} are. If the {@param stackBounds} are not currently on the
+     *         {@param movementBounds} exactly, then they will be snapped to the movement bounds.
+     *
+     *         The fraction is defined in a clockwise fashion against the {@param movementBounds}:
+     *
+     *            0   1
+     *          4 +---+ 1
+     *            |   |
+     *          3 +---+ 2
+     *            3   2
+     */
+    public float getSnapFraction(Rect stackBounds, Rect movementBounds) {
+        final Rect tmpBounds = new Rect();
+        snapRectToClosestEdge(stackBounds, movementBounds, tmpBounds);
+        final float widthFraction = (float) (tmpBounds.left - movementBounds.left) /
+                movementBounds.width();
+        final float heightFraction = (float) (tmpBounds.top - movementBounds.top) /
+                movementBounds.height();
+        if (tmpBounds.top == movementBounds.top) {
+            return widthFraction;
+        } else if (tmpBounds.left == movementBounds.right) {
+            return 1f + heightFraction;
+        } else if (tmpBounds.top == movementBounds.bottom) {
+            return 2f + (1f - widthFraction);
+        } else {
+            return 3f + (1f - heightFraction);
+        }
+    }
+
+    /**
+     * Moves the {@param stackBounds} along the {@param movementBounds} to the given snap fraction.
+     * See {@link #getSnapFraction(Rect, Rect)}.
+     *
+     * The fraction is define in a clockwise fashion against the {@param movementBounds}:
+     *
+     *    0   1
+     *  4 +---+ 1
+     *    |   |
+     *  3 +---+ 2
+     *    3   2
+     */
+    public void applySnapFraction(Rect stackBounds, Rect movementBounds, float snapFraction) {
+        if (snapFraction < 1f) {
+            int offset = movementBounds.left + (int) (snapFraction * movementBounds.width());
+            stackBounds.offsetTo(offset, movementBounds.top);
+        } else if (snapFraction < 2f) {
+            snapFraction -= 1f;
+            int offset = movementBounds.top + (int) (snapFraction * movementBounds.height());
+            stackBounds.offsetTo(movementBounds.right, offset);
+        } else if (snapFraction < 3f) {
+            snapFraction -= 2f;
+            int offset = movementBounds.left + (int) ((1f - snapFraction) * movementBounds.width());
+            stackBounds.offsetTo(offset, movementBounds.bottom);
+        } else {
+            snapFraction -= 3f;
+            int offset = movementBounds.top + (int) ((1f - snapFraction) * movementBounds.height());
+            stackBounds.offsetTo(movementBounds.left, offset);
+        }
+    }
+
+    /**
+     * @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;
+    }
+
+    /**
+     * Snaps the {@param stackBounds} to the closest edge of the {@param movementBounds} and writes
+     * the new bounds out to {@param boundsOut}.
+     */
+    private void snapRectToClosestEdge(Rect stackBounds, Rect movementBounds, Rect boundsOut) {
+        final int fromLeft = Math.abs(stackBounds.left - movementBounds.left);
+        final int fromTop = Math.abs(stackBounds.top - movementBounds.top);
+        final int fromRight = Math.abs(movementBounds.right - stackBounds.left);
+        final int fromBottom = Math.abs(movementBounds.bottom - stackBounds.top);
+        boundsOut.set(stackBounds);
+        if (fromLeft <= fromTop && fromLeft <= fromRight && fromLeft <= fromBottom) {
+            boundsOut.offsetTo(movementBounds.left, stackBounds.top);
+        } else if (fromTop <= fromLeft && fromTop <= fromRight && fromTop <= fromBottom) {
+            boundsOut.offsetTo(stackBounds.left, movementBounds.top);
+        } else if (fromRight < fromLeft && fromRight < fromTop && fromRight < fromBottom) {
+            boundsOut.offsetTo(movementBounds.right, stackBounds.top);
+        } else {
+            boundsOut.offsetTo(stackBounds.left, movementBounds.bottom);
+        }
+    }
+
+    /**
+     * @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/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java
index 83d5ce3..3d8c85e 100644
--- a/core/java/com/android/internal/util/XmlUtils.java
+++ b/core/java/com/android/internal/util/XmlUtils.java
@@ -1594,6 +1594,9 @@
 
     public static int readIntAttribute(XmlPullParser in, String name, int defaultValue) {
         final String value = in.getAttributeValue(null, name);
+        if (TextUtils.isEmpty(value)) {
+            return defaultValue;
+        }
         try {
             return Integer.parseInt(value);
         } catch (NumberFormatException e) {
@@ -1617,6 +1620,9 @@
 
     public static long readLongAttribute(XmlPullParser in, String name, long defaultValue) {
         final String value = in.getAttributeValue(null, name);
+        if (TextUtils.isEmpty(value)) {
+            return defaultValue;
+        }
         try {
             return Long.parseLong(value);
         } catch (NumberFormatException e) {
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/jni/Android.mk b/core/jni/Android.mk
index 7950685..91e8310 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 \
@@ -252,6 +259,7 @@
     libicuuc \
     libicui18n \
     libmedia \
+    libaudioclient \
     libjpeg \
     libusbhost \
     libharfbuzz_ng \
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 467ec37..d9aa8f1 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -655,7 +655,7 @@
         alphaType = requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType;
     }
     bitmap->bitmap().reconfigure(SkImageInfo::Make(width, height, colorType, alphaType,
-            sk_sp<SkColorSpace>(bitmap->info().colorSpace())));
+            sk_ref_sp(bitmap->info().colorSpace())));
 }
 
 // These must match the int values in Bitmap.java
@@ -806,7 +806,7 @@
     std::unique_ptr<SkBitmap> bitmap(new SkBitmap);
 
     if (!bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType,
-            isSRGB ? SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named) : nullptr), rowBytes)) {
+            isSRGB ? SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named) : nullptr), rowBytes)) {
         return NULL;
     }
 
@@ -921,7 +921,7 @@
     auto bitmapWrapper = reinterpret_cast<BitmapWrapper*>(bitmapHandle);
     bitmapWrapper->getSkBitmap(&bitmap);
 
-    sk_sp<SkColorSpace> sRGB = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
+    sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
     bool isSRGB = bitmap.colorSpace() == sRGB.get();
 
     p->writeInt32(isMutable);
@@ -1195,13 +1195,6 @@
     return JNI_TRUE;
 }
 
-static jlong Bitmap_refPixelRef(JNIEnv* env, jobject, jlong bitmapHandle) {
-    LocalScopedBitmap bitmap(bitmapHandle);
-    SkPixelRef& pixelRef = bitmap->bitmap();
-    pixelRef.ref();
-    return reinterpret_cast<jlong>(&pixelRef);
-}
-
 static void Bitmap_prepareToDraw(JNIEnv* env, jobject, jlong bitmapPtr) {
     LocalScopedBitmap bitmapHandle(bitmapPtr);
     if (!bitmapHandle.valid()) return;
@@ -1269,7 +1262,6 @@
     {   "nativeCopyPixelsFromBuffer", "(JLjava/nio/Buffer;)V",
                                             (void*)Bitmap_copyPixelsFromBuffer },
     {   "nativeSameAs",             "(JJ)Z", (void*)Bitmap_sameAs },
-    {   "nativeRefPixelRef",        "(J)J", (void*)Bitmap_refPixelRef },
     {   "nativePrepareToDraw",      "(J)V", (void*)Bitmap_prepareToDraw },
     {   "nativeGetAllocationByteCount", "(J)I", (void*)Bitmap_getAllocationByteCount },
 };
@@ -1283,4 +1275,4 @@
     gBitmap_getAllocationByteCountMethodID = env->GetMethodID(gBitmap_class, "getAllocationByteCount", "()I");
     return android::RegisterMethodsOrDie(env, "android/graphics/Bitmap", gBitmapMethods,
                                          NELEM(gBitmapMethods));
-}
\ No newline at end of file
+}
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index bc2da91..1ded2c5 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -365,7 +365,7 @@
     SkColorType decodeColorType = codec->computeOutputColorType(prefColorType);
 
     // Construct a color table for the decode if necessary
-    SkAutoTUnref<SkColorTable> colorTable(nullptr);
+    sk_sp<SkColorTable> colorTable(nullptr);
     SkPMColor* colorPtr = nullptr;
     int* colorCount = nullptr;
     int maxColors = 256;
@@ -399,7 +399,7 @@
     }
     SkBitmap decodingBitmap;
     if (!decodingBitmap.setInfo(bitmapInfo) ||
-            !decodingBitmap.tryAllocPixels(decodeAllocator, colorTable)) {
+            !decodingBitmap.tryAllocPixels(decodeAllocator, colorTable.get())) {
         // SkAndroidCodec should recommend a valid SkImageInfo, so setInfo()
         // should only only fail if the calculated value for rowBytes is too
         // large.
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index 45bf702..115ee72 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -39,18 +39,20 @@
 #include <jni.h>
 #include <sys/stat.h>
 
+#include <memory>
+
 using namespace android;
 
 static jobject createBitmapRegionDecoder(JNIEnv* env, std::unique_ptr<SkStreamRewindable> stream) {
-    SkAutoTDelete<SkBitmapRegionDecoder> brd(
+  std::unique_ptr<SkBitmapRegionDecoder> brd(
             SkBitmapRegionDecoder::Create(stream.release(),
                                           SkBitmapRegionDecoder::kAndroidCodec_Strategy));
-    if (NULL == brd) {
+    if (!brd) {
         doThrowIOE(env, "Image format not supported");
         return nullObjectReturn("CreateBitmapRegionDecoder returned null");
     }
 
-    return GraphicsJNI::createBitmapRegionDecoder(env, brd.detach());
+    return GraphicsJNI::createBitmapRegionDecoder(env, brd.release());
 }
 
 static jobject nativeNewInstanceFromByteArray(JNIEnv* env, jobject, jbyteArray byteArray,
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index 2088421..15e7165 100644
--- a/core/jni/android/graphics/FontFamily.cpp
+++ b/core/jni/android/graphics/FontFamily.cpp
@@ -106,7 +106,7 @@
     SkFontMgr::FontParameters params;
     params.setCollectionIndex(ttcIndex);
 
-    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+    sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
     sk_sp<SkTypeface> face(fm->createFromStream(fontData.release(), params));
     if (face == NULL) {
         ALOGE("addFont failed to create font");
@@ -172,7 +172,7 @@
     params.setCollectionIndex(ttcIndex);
     params.setAxes(skiaAxes.get(), skiaAxesLength);
 
-    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+    sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
     sk_sp<SkTypeface> face(fm->createFromStream(fontData.release(), params));
     if (face == NULL) {
         ALOGE("addFont failed to create font, invalid request");
@@ -216,7 +216,7 @@
     sk_sp<SkData> data(SkData::MakeWithProc(buf, asset->getLength(), releaseAsset, asset));
     std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(std::move(data)));
 
-    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+    sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
     sk_sp<SkTypeface> face(fm->createFromStream(fontData.release(), SkFontMgr::FontParameters()));
     if (face == NULL) {
         ALOGE("addFontFromAsset failed to create font %s", str.c_str());
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/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index dffb63c..322eed5 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -437,7 +437,7 @@
 
 sk_sp<SkColorSpace> GraphicsJNI::defaultColorSpace() {
 #ifdef ANDROID_ENABLE_LINEAR_BLENDING
-    return SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
+    return SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
 #else
     return nullptr;
 #endif
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/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 38452bb..e10fdbd 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -32,7 +32,7 @@
 #include "SkPathEffect.h"
 #include "SkRasterizer.h"
 #include "SkShader.h"
-#include "SkXfermode.h"
+#include "SkBlendMode.h"
 #include "unicode/uloc.h"
 #include "unicode/ushape.h"
 #include "utils/Blur.h"
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/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index a2416df..657b1ef 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -2,7 +2,7 @@
 #include "SkGradientShader.h"
 #include "SkImagePriv.h"
 #include "SkShader.h"
-#include "SkXfermode.h"
+#include "SkBlendMode.h"
 #include "core_jni_helpers.h"
 
 #include <Caches.h>
@@ -59,7 +59,7 @@
     // The current shader will no longer need a direct reference owned by Shader.java
     // as all the data needed is contained within the newly created LocalMatrixShader.
     SkASSERT(shaderHandle);
-    SkAutoTUnref<SkShader> currentShader(reinterpret_cast<SkShader*>(shaderHandle));
+    sk_sp<SkShader> currentShader(reinterpret_cast<SkShader*>(shaderHandle));
 
     // Attempt to peel off an existing proxy shader and get the proxy's matrix. If
     // the proxy existed and it's matrix equals the desired matrix then just return
@@ -74,10 +74,10 @@
     //          API enforces that all local matrices are set using this call and
     //          not passed to the constructor of the Shader.
     SkMatrix proxyMatrix;
-    SkAutoTUnref<SkShader> baseShader(currentShader->refAsALocalMatrixShader(&proxyMatrix));
+    sk_sp<SkShader> baseShader = currentShader->makeAsALocalMatrixShader(&proxyMatrix);
     if (baseShader.get()) {
         if (proxyMatrix == *matrix) {
-            return reinterpret_cast<jlong>(currentShader.detach());
+            return reinterpret_cast<jlong>(currentShader.release());
         }
         return reinterpret_cast<jlong>(baseShader->makeWithLocalMatrix(*matrix).release());
     }
@@ -237,7 +237,7 @@
     SkBlendMode mode = static_cast<SkBlendMode>(xfermodeHandle);
     SkShader* shader = SkShader::MakeComposeShader(sk_ref_sp(shaderA),
                                                    sk_ref_sp(shaderB),
-                                                   (SkXfermode::Mode)mode).release();
+                                                   mode).release();
     return reinterpret_cast<jlong>(shader);
 }
 
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_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_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp
index 13e3f0d..1a33d91 100644
--- a/core/jni/android_os_HwBinder.cpp
+++ b/core/jni/android_os_HwBinder.cpp
@@ -24,8 +24,9 @@
 #include "android_os_HwRemoteBinder.h"
 
 #include <JNIHelp.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
 #include <android_runtime/AndroidRuntime.h>
-#include <hidl/IServiceManager.h>
+#include <hidl/ServiceManagement.h>
 #include <hidl/Status.h>
 #include <hwbinder/ProcessState.h>
 #include <nativehelper/ScopedLocalRef.h>
@@ -196,54 +197,88 @@
 }
 
 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);
+    using android::hidl::manager::V1_0::IServiceManager;
+
+    const IServiceManager::Version kVersion {
+        .major = static_cast<uint16_t>(versionMajor),
+        .minor = static_cast<uint16_t>(versionMinor),
+    };
 
     sp<hardware::IBinder> binder = JHwBinder::GetNativeContext(env, thiz);
 
-    status_t err = hardware::defaultServiceManager()->addService(
-                String16(
-                    reinterpret_cast<const char16_t *>(serviceName),
-                    env->GetStringLength(serviceNameObj)),
+    bool ok = hardware::defaultServiceManager()->add(
+                String8(String16(
+                          reinterpret_cast<const char16_t *>(serviceName),
+                          env->GetStringLength(serviceNameObj))).string(),
                 binder,
                 kVersion);
 
     env->ReleaseStringCritical(serviceNameObj, serviceName);
     serviceName = NULL;
 
-    if (err == OK) {
+    if (ok) {
         LOG(INFO) << "Starting thread pool.";
         ::android::hardware::ProcessState::self()->startThreadPool();
     }
 
-    signalExceptionForError(env, err);
+    signalExceptionForError(env, (ok ? OK : UNKNOWN_ERROR));
 }
 
 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);
+    using android::hidl::manager::V1_0::IServiceManager;
+
+    const IServiceManager::Version kVersion {
+        .major = static_cast<uint16_t>(versionMajor),
+        .minor = static_cast<uint16_t>(versionMinor),
+    };
 
     LOG(INFO) << "looking for service '"
               << String8(String16(
@@ -251,12 +286,15 @@
                           env->GetStringLength(serviceNameObj))).string()
               << "'";
 
-    sp<hardware::IBinder> service =
-        hardware::defaultServiceManager()->getService(
-                String16(
-                    reinterpret_cast<const char16_t *>(serviceName),
-                    env->GetStringLength(serviceNameObj)),
-                kVersion);
+    sp<hardware::IBinder> service;
+    hardware::defaultServiceManager()->get(
+            String8(String16(
+                      reinterpret_cast<const char16_t *>(serviceName),
+                      env->GetStringLength(serviceNameObj))).string(),
+            kVersion,
+            [&service](sp<hardware::IBinder> out) {
+                service = out;
+            });
 
     env->ReleaseStringCritical(serviceNameObj, serviceName);
     serviceName = NULL;
@@ -280,10 +318,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_os_HwRemoteBinder.cpp b/core/jni/android_os_HwRemoteBinder.cpp
index 3023ba8..1d5d6d5 100644
--- a/core/jni/android_os_HwRemoteBinder.cpp
+++ b/core/jni/android_os_HwRemoteBinder.cpp
@@ -24,7 +24,6 @@
 
 #include <JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
-#include <hidl/IServiceManager.h>
 #include <hidl/Status.h>
 #include <nativehelper/ScopedLocalRef.h>
 
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/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_HardwareLayer.cpp
index 4e0b924..65c1590 100644
--- a/core/jni/android_view_HardwareLayer.cpp
+++ b/core/jni/android_view_HardwareLayer.cpp
@@ -29,7 +29,7 @@
 #include <SkBitmap.h>
 #include <SkCanvas.h>
 #include <SkMatrix.h>
-#include <SkXfermode.h>
+#include <SkBlendMode.h>
 
 #include <DeferredLayerUpdater.h>
 #include <SkiaShader.h>
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index dd2a7a9..f88de51 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -124,6 +124,10 @@
     renderNode->decStrong(0);
 }
 
+static void android_view_RenderNode_finalize(JNIEnv* env, jobject clazz, jlong renderNodePtr) {
+    releaseRenderNode(reinterpret_cast<RenderNode*>(renderNodePtr));
+}
+
 static jlong android_view_RenderNode_getNativeFinalizer(JNIEnv* env,
         jobject clazz) {
     return static_cast<jlong>(reinterpret_cast<uintptr_t>(&releaseRenderNode));
@@ -650,6 +654,7 @@
 // Regular JNI
 // ----------------------------------------------------------------------------
     { "nCreate",               "(Ljava/lang/String;)J", (void*) android_view_RenderNode_create },
+    { "nFinalize",             "(J)V",   (void*) android_view_RenderNode_finalize },
     { "nGetNativeFinalizer",   "()J",    (void*) android_view_RenderNode_getNativeFinalizer },
     { "nSetDisplayList",       "(JJ)V",   (void*) android_view_RenderNode_setDisplayList },
     { "nOutput",               "(J)V",    (void*) android_view_RenderNode_output },
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
index 9fa90ac..4a2b881 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -43,6 +43,7 @@
     jfieldID uid;
     jfieldID set;
     jfieldID tag;
+    jfieldID metered;
     jfieldID roaming;
     jfieldID rxBytes;
     jfieldID rxPackets;
@@ -239,6 +240,9 @@
     ScopedIntArrayRW tag(env, get_int_array(env, stats,
             gNetworkStatsClassInfo.tag, size, grow));
     if (tag.get() == NULL) return -1;
+    ScopedIntArrayRW metered(env, get_int_array(env, stats,
+            gNetworkStatsClassInfo.metered, size, grow));
+    if (metered.get() == NULL) return -1;
     ScopedIntArrayRW roaming(env, get_int_array(env, stats,
             gNetworkStatsClassInfo.roaming, size, grow));
     if (roaming.get() == NULL) return -1;
@@ -265,7 +269,7 @@
         uid[i] = lines[i].uid;
         set[i] = lines[i].set;
         tag[i] = lines[i].tag;
-        // Roaming is populated in Java-land by inspecting the iface properties.
+        // Metered and Roaming are populated in Java-land by inspecting the iface properties.
         rxBytes[i] = lines[i].rxBytes;
         rxPackets[i] = lines[i].rxPackets;
         txBytes[i] = lines[i].txBytes;
@@ -279,6 +283,7 @@
         env->SetObjectField(stats, gNetworkStatsClassInfo.uid, uid.getJavaArray());
         env->SetObjectField(stats, gNetworkStatsClassInfo.set, set.getJavaArray());
         env->SetObjectField(stats, gNetworkStatsClassInfo.tag, tag.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.metered, metered.getJavaArray());
         env->SetObjectField(stats, gNetworkStatsClassInfo.roaming, roaming.getJavaArray());
         env->SetObjectField(stats, gNetworkStatsClassInfo.rxBytes, rxBytes.getJavaArray());
         env->SetObjectField(stats, gNetworkStatsClassInfo.rxPackets, rxPackets.getJavaArray());
@@ -311,6 +316,7 @@
     gNetworkStatsClassInfo.uid = GetFieldIDOrDie(env, clazz, "uid", "[I");
     gNetworkStatsClassInfo.set = GetFieldIDOrDie(env, clazz, "set", "[I");
     gNetworkStatsClassInfo.tag = GetFieldIDOrDie(env, clazz, "tag", "[I");
+    gNetworkStatsClassInfo.metered = GetFieldIDOrDie(env, clazz, "metered", "[I");
     gNetworkStatsClassInfo.roaming = GetFieldIDOrDie(env, clazz, "roaming", "[I");
     gNetworkStatsClassInfo.rxBytes = GetFieldIDOrDie(env, clazz, "rxBytes", "[J");
     gNetworkStatsClassInfo.rxPackets = GetFieldIDOrDie(env, clazz, "rxPackets", "[J");
diff --git a/core/jni/fd_utils-inl.h b/core/jni/fd_utils-inl.h
index af27069..b78b8ff 100644
--- a/core/jni/fd_utils-inl.h
+++ b/core/jni/fd_utils-inl.h
@@ -51,6 +51,7 @@
   "/dev/null",
   "/dev/socket/zygote",
   "/dev/socket/zygote_secondary",
+  "/dev/socket/webview_zygote",
   "/sys/kernel/debug/tracing/trace_marker",
   "/system/framework/framework-res.apk",
   "/dev/urandom",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c346849..4eebea6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -292,7 +292,7 @@
     <protected-broadcast android:name="android.net.wifi.WIFI_AP_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.WIFI_CREDENTIAL_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.WIFI_SCAN_AVAILABLE" />
-    <protected-broadcast android:name="android.net.wifi.nan.action.WIFI_NAN_STATE_CHANGED" />
+    <protected-broadcast android:name="android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.SCAN_RESULTS" />
     <protected-broadcast android:name="android.net.wifi.RSSI_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.STATE_CHANGE" />
@@ -300,7 +300,6 @@
     <protected-broadcast android:name="android.net.wifi.CONFIGURED_NETWORKS_CHANGE" />
     <protected-broadcast android:name="android.net.wifi.supplicant.CONNECTION_CHANGE" />
     <protected-broadcast android:name="android.net.wifi.supplicant.STATE_CHANGE" />
-    <protected-broadcast android:name="android.net.wifi.nan.STATE_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.p2p.STATE_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.p2p.DISCOVERY_STATE_CHANGE" />
     <protected-broadcast android:name="android.net.wifi.p2p.THIS_DEVICE_CHANGED" />
@@ -454,6 +453,7 @@
     <protected-broadcast android:name="com.android.server.Wifi.action.TOGGLE_PNO" />
     <protected-broadcast android:name="intent.action.ACTION_RF_BAND_INFO" />
     <protected-broadcast android:name="android.intent.action.MEDIA_RESOURCE_GRANTED" />
+    <protected-broadcast android:name="android.app.action.NETWORK_LOGS_AVAILABLE" />
     <protected-broadcast android:name="android.app.action.SECURITY_LOGS_AVAILABLE" />
 
     <protected-broadcast android:name="android.app.action.INTERRUPTION_FILTER_CHANGED" />
@@ -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"
@@ -1779,12 +1774,12 @@
         android:protectionLevel="signature|privileged" />
 
     <!-- Allows applications to set the system time zone.
-         <p>Protection level: normal
+         <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.SET_TIME_ZONE"
         android:label="@string/permlab_setTimeZone"
         android:description="@string/permdesc_setTimeZone"
-        android:protectionLevel="normal" />
+        android:protectionLevel="signature|privileged" />
 
     <!-- ==================================================== -->
     <!-- Permissions related to changing status bar   -->
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-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-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-ca/strings.xml b/core/res/res/values-ca/strings.xml
index d1fbebb..07f6aa8 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -67,8 +67,8 @@
     </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
-    <string name="ClipMmi" msgid="6952821216480289285">"ID de l\'emissor (trucada entrant)"</string>
-    <string name="ClirMmi" msgid="7784673673446833091">"ID de l\'emissor (trucada de sortida)"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"Identificador de trucada (trucada entrant)"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"Identificador de trucada (trucada de sortida)"</string>
     <string name="ColpMmi" msgid="3065121483740183974">"Identificador de la línia connectada"</string>
     <string name="ColrMmi" msgid="4996540314421889589">"Restricció de l\'identificador de la línia connectada"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Desviació de trucades"</string>
@@ -82,12 +82,12 @@
     <string name="RuacMmi" msgid="7827887459138308886">"Rebuig de trucades molestes no desitjades"</string>
     <string name="CndMmi" msgid="3116446237081575808">"Lliurament de número que truca"</string>
     <string name="DndMmi" msgid="1265478932418334331">"No molesteu"</string>
-    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"El valor predeterminat de l\'identificador de l\'emissor és restringit. Següent trucada: restringit"</string>
-    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"El valor predeterminat de l\'identificador de l\'emissor és restringit. Següent trucada: no restringit"</string>
-    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"El valor predeterminat de l\'identificador de l\'emissor és no restringit. Següent trucada: restringit"</string>
-    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"El valor predeterminat de l\'identificador de l\'emissor és no restringit. Següent trucada: no restringit"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"El valor predeterminat de l\'identificador de trucada és restringit. Trucada següent: restringit"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"El valor predeterminat de l\'identificador de trucada és restringit. Trucada següent: no restringit"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"El valor predeterminat de l\'identificador de trucada és no restringit. Trucada següent: restringit"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"El valor predeterminat de l\'identificador de trucada és no restringit. Trucada següent: no restringit"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"No s\'ha proveït el servei."</string>
-    <string name="CLIRPermanent" msgid="3377371145926835671">"No pots canviar la configuració de l\'identificador de l\'emissor."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"No pots canviar la configuració de l\'identificador de trucada."</string>
     <string name="RestrictedOnData" msgid="8653794784690065540">"El servei de dades està bloquejat."</string>
     <string name="RestrictedOnEmergency" msgid="6581163779072833665">"El servei d\'emergència està bloquejat."</string>
     <string name="RestrictedOnNormal" msgid="4953867011389750673">"El servei de veu està bloquejat."</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 5a1ad70..af7aaaf 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -1137,7 +1137,7 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Սահմանել ժամը"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Սահմանել ամսաթիվը"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Սահմանել"</string>
-    <string name="date_time_done" msgid="2507683751759308828">"Կատարված է"</string>
+    <string name="date_time_done" msgid="2507683751759308828">"Պատրաստ է"</string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"Նոր` "</font></string>
     <string name="perms_description_app" msgid="5139836143293299417">"Տրամադրված է <xliff:g id="APP_NAME">%1$s</xliff:g>-ի կողմից:"</string>
     <string name="no_permissions" msgid="7283357728219338112">"Թույլտվություններ չեն պահանջվում"</string>
@@ -1214,7 +1214,7 @@
     <string name="ime_action_search" msgid="658110271822807811">"Որոնել"</string>
     <string name="ime_action_send" msgid="2316166556349314424">"Ուղարկել"</string>
     <string name="ime_action_next" msgid="3138843904009813834">"Հաջորդը"</string>
-    <string name="ime_action_done" msgid="8971516117910934605">"Կատարված է"</string>
+    <string name="ime_action_done" msgid="8971516117910934605">"Պատրաստ է"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Նախորդ"</string>
     <string name="ime_action_default" msgid="2840921885558045721">"Կատարել"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"Հավաքել հեռախոսահամարը`\nօգտագործելով <xliff:g id="NUMBER">%s</xliff:g>-ը"</string>
@@ -1263,7 +1263,7 @@
       <item quantity="one"><xliff:g id="INDEX">%d</xliff:g>՝ <xliff:g id="TOTAL">%d</xliff:g>-ից</item>
       <item quantity="other"><xliff:g id="INDEX">%d</xliff:g>՝ <xliff:g id="TOTAL">%d</xliff:g>-ից</item>
     </plurals>
-    <string name="action_mode_done" msgid="7217581640461922289">"Կատարված է"</string>
+    <string name="action_mode_done" msgid="7217581640461922289">"Պատրաստ է"</string>
     <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Ջնջում է USB կրիչը..."</string>
     <string name="progress_erasing" product="default" msgid="6596988875507043042">"Ջնջում է SD քարտը..."</string>
     <string name="share" msgid="1778686618230011964">"Կիսվել"</string>
@@ -1305,7 +1305,7 @@
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</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_done" msgid="1992571118466679775">"Պատրաստ է"</string>
     <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Ռեժիմի փոփոխում"</string>
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Մուտք"</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-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..340010f 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -667,11 +667,11 @@
     <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>
-    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Tryck på Menu om du vill låsa upp eller ringa nödsamtal."</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Tryck på Menu för att låsa upp eller ringa nödsamtal."</string>
     <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Tryck på Menu för att låsa upp."</string>
     <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Rita grafiskt lösenord för att låsa upp"</string>
     <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Nödsamtal"</string>
diff --git a/core/res/res/values-watch/config.xml b/core/res/res/values-watch/config.xml
index 7c05b7a..d13d154 100644
--- a/core/res/res/values-watch/config.xml
+++ b/core/res/res/values-watch/config.xml
@@ -62,4 +62,7 @@
          ListView/GridView are notably absent since this is their default anyway.
          Set to true for watch devices. -->
     <bool name="config_focusScrollContainersInTouchMode">true</bool>
+
+    <!-- The small screens of watch devices makes multi-window support undesireable. -->
+    <bool name="config_supportsMultiWindow">false</bool>
 </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/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 1d7153b..ff1d383 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1374,6 +1374,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>
 
@@ -2178,9 +2181,9 @@
     -->
     <string-array translatable="false" name="config_telephonyHardware">
         <!-- modem -->
-        <item>"0,modem,0,0,0,1,1,1"</item>
+        <item>0,modem,0,0,0,1,1,1</item>
         <!-- sim -->
-        <item>"1,sim,0,modem"</item>
+        <item>1,sim,0,modem</item>
     </string-array>
 
     <!-- This string array can be overriden to add an additional DRM support for WebView EME. -->
@@ -2638,4 +2641,11 @@
 
     <!-- An array of packages for which notifications cannot be blocked. -->
     <string-array translatable="false" name="config_nonBlockableNotificationPackages" />
+
+    <!-- The default value for transition animation scale found in developer settings.
+         1.0 corresponds to 1x animator scale, 0 means that there will be no transition
+         animations. Note that this is only a default and will be overridden by a
+         user-set value if toggled by settings so the "Transition animation scale" setting
+         should also be hidden if intended to be permanent. -->
+    <item name="config_appTransitionAnimationDurationScaleDefault" format="float" type="dimen">1.0</item>
 </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 98ccdb9..92fff65 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -368,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" />
@@ -2731,4 +2732,6 @@
   <!-- Screen-size-dependent modes for picker dialogs. -->
   <java-symbol type="integer" name="time_picker_mode" />
   <java-symbol type="integer" name="date_picker_mode" />
+
+  <java-symbol type="dimen" name="config_appTransitionAnimationDurationScaleDefault" />
 </resources>
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/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java
index d48a67a..eb85eb4 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsTest.java
@@ -16,6 +16,9 @@
 
 package android.net;
 
+import static android.net.NetworkStats.METERED_ALL;
+import static android.net.NetworkStats.METERED_NO;
+import static android.net.NetworkStats.METERED_YES;
 import static android.net.NetworkStats.ROAMING_ALL;
 import static android.net.NetworkStats.ROAMING_NO;
 import static android.net.NetworkStats.ROAMING_YES;
@@ -45,103 +48,124 @@
     private static final long TEST_START = 1194220800000L;
 
     public void testFindIndex() throws Exception {
-        final NetworkStats stats = new NetworkStats(TEST_START, 4)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L, 0L,
-                        0L, 10)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 1024L,
-                        8L, 11)
-                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
-                        1024L, 8L, 12)
-                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_YES, 1024L, 8L,
-                        1024L, 8L, 12);
+        final NetworkStats stats = new NetworkStats(TEST_START, 5)
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
+                        8L, 0L, 0L, 10)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L, 0L,
+                        1024L, 8L, 11)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 0L, 0L,
+                        1024L, 8L, 11)
+                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
+                        8L, 1024L, 8L, 12)
+                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, 1024L,
+                        8L, 1024L, 8L, 12);
 
-        assertEquals(3, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_YES));
-        assertEquals(2, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO));
-        assertEquals(1, stats.findIndex(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO));
-        assertEquals(0, stats.findIndex(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO));
-        assertEquals(-1, stats.findIndex(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE, ROAMING_NO));
+        assertEquals(4, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES,
+                ROAMING_YES));
+        assertEquals(3, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO,
+                ROAMING_NO));
+        assertEquals(2, stats.findIndex(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES,
+                ROAMING_NO));
+        assertEquals(1, stats.findIndex(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO,
+                ROAMING_NO));
+        assertEquals(0, stats.findIndex(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO,
+                ROAMING_NO));
+        assertEquals(-1, stats.findIndex(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE, METERED_NO,
+                ROAMING_NO));
     }
 
     public void testFindIndexHinted() {
         final NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L, 0L,
-                        0L, 10)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 1024L,
-                        8L, 11)
-                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
-                        1024L, 8L, 12)
-                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 1024L, 8L,
-                        0L, 0L, 10)
-                .addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 0L, 0L, 1024L,
-                        8L, 11)
-                .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
-                        1024L, 8L, 12)
-                .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, ROAMING_YES, 1024L, 8L,
-                        1024L, 8L, 12);
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
+                        8L, 0L, 0L, 10)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L, 0L,
+                        1024L, 8L, 11)
+                .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
+                        8L, 1024L, 8L, 12)
+                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                        1024L, 8L, 0L, 0L, 10)
+                .addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 0L, 0L,
+                        1024L, 8L, 11)
+                .addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, 0L, 0L,
+                        1024L, 8L, 11)
+                .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
+                        8L, 1024L, 8L, 12)
+                .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, 1024L,
+                        8L, 1024L, 8L, 12);
 
         // verify that we correctly find across regardless of hinting
         for (int hint = 0; hint < stats.size(); hint++) {
             assertEquals(0, stats.findIndexHinted(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE,
-                    ROAMING_NO, hint));
+                    METERED_NO, ROAMING_NO, hint));
             assertEquals(1, stats.findIndexHinted(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE,
-                    ROAMING_NO, hint));
+                    METERED_NO, ROAMING_NO, hint));
             assertEquals(2, stats.findIndexHinted(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE,
-                    ROAMING_NO, hint));
+                    METERED_NO, ROAMING_NO, hint));
             assertEquals(3, stats.findIndexHinted(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE,
-                    ROAMING_NO, hint));
+                    METERED_NO, ROAMING_NO, hint));
             assertEquals(4, stats.findIndexHinted(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D,
-                    ROAMING_NO, hint));
-            assertEquals(5, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE,
-                    ROAMING_NO, hint));
+                    METERED_NO, ROAMING_NO, hint));
+            assertEquals(5, stats.findIndexHinted(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D,
+                    METERED_YES, ROAMING_NO, hint));
             assertEquals(6, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE,
-                    ROAMING_YES, hint));
+                    METERED_NO, ROAMING_NO, hint));
+            assertEquals(7, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE,
+                    METERED_YES, ROAMING_YES, hint));
             assertEquals(-1, stats.findIndexHinted(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE,
-                    ROAMING_NO, hint));
+                    METERED_NO, ROAMING_NO, hint));
         }
     }
 
     public void testAddEntryGrow() throws Exception {
-        final NetworkStats stats = new NetworkStats(TEST_START, 3);
+        final NetworkStats stats = new NetworkStats(TEST_START, 4);
 
         assertEquals(0, stats.size());
-        assertEquals(3, stats.internalSize());
+        assertEquals(4, stats.internalSize());
 
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L, 1L, 2L,
-                2L, 3);
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 2L, 2L, 2L,
-                2L, 4);
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 3L, 3L, 2L,
-                2L, 5);
-
-        assertEquals(3, stats.size());
-        assertEquals(3, stats.internalSize());
-
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 4L, 40L, 4L,
-                40L, 7);
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 5L, 50L, 4L,
-                40L, 8);
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 6L, 60L, 5L,
-                50L, 10);
-        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 7L, 70L, 5L,
-                50L, 11);
-
-        assertEquals(7, stats.size());
-        assertTrue(stats.internalSize() >= 7);
-
-        assertValues(stats, 0, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L, 1L,
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1L, 1L,
                 2L, 2L, 3);
-        assertValues(stats, 1, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 2L, 2L,
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 2L, 2L,
                 2L, 2L, 4);
-        assertValues(stats, 2, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 3L, 3L,
-                2L, 2L, 5);
-        assertValues(stats, 3, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 4L,
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 3L,
+                3L, 2L, 2L, 5);
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, 3L,
+                3L, 2L, 2L, 5);
+
+        assertEquals(4, stats.size());
+        assertEquals(4, stats.internalSize());
+
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 4L,
                 40L, 4L, 40L, 7);
-        assertValues(stats, 4, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 5L,
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 5L,
                 50L, 4L, 40L, 8);
-        assertValues(stats, 5, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 6L,
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 6L,
                 60L, 5L, 50L, 10);
-        assertValues(stats, 6, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 7L,
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 7L,
                 70L, 5L, 50L, 11);
+        stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, 7L,
+                70L, 5L, 50L, 11);
+
+        assertEquals(9, stats.size());
+        assertTrue(stats.internalSize() >= 9);
+
+        assertValues(stats, 0, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                1L, 1L, 2L, 2L, 3);
+        assertValues(stats, 1, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                2L, 2L, 2L, 2L, 4);
+        assertValues(stats, 2, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+                3L, 3L, 2L, 2L, 5);
+        assertValues(stats, 3, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES,
+                ROAMING_YES, 3L, 3L, 2L, 2L, 5);
+        assertValues(stats, 4, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                4L, 40L, 4L, 40L, 7);
+        assertValues(stats, 5, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                5L, 50L, 4L, 40L, 8);
+        assertValues(stats, 6, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                6L, 60L, 5L, 50L, 10);
+        assertValues(stats, 7, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
+                7L, 70L, 5L, 50L, 11);
+        assertValues(stats, 8, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES,
+                ROAMING_YES, 7L, 70L, 5L, 50L, 11);
     }
 
     public void testCombineExisting() throws Exception {
@@ -152,20 +176,18 @@
         stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L,
                 -128L, -1L, -1);
 
-        assertValues(stats, 0, TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, ROAMING_NO, 384L, 3L,
-                128L, 1L, 9);
-        assertValues(stats, 1, TEST_IFACE, 1001, SET_DEFAULT, 0xff, ROAMING_NO, 128L, 1L, 128L,
-                1L, 2);
+        assertValues(stats, 0, TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                384L, 3L, 128L, 1L, 9);
+        assertValues(stats, 1, TEST_IFACE, 1001, SET_DEFAULT, 0xff, METERED_NO, ROAMING_NO, 128L,
+                1L, 128L, 1L, 2);
 
         // now try combining that should create row
-        stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L,
-                128L, 1L, 3);
-        assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 1L,
-                128L, 1L, 3);
-        stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L,
-                128L, 1L, 3);
-        assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, ROAMING_NO, 256L, 2L,
-                256L, 2L, 6);
+        stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3);
+        assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                128L, 1L, 128L, 1L, 3);
+        stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3);
+        assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                256L, 2L, 256L, 2L, 6);
     }
 
     public void testSubtractIdenticalData() throws Exception {
@@ -180,10 +202,10 @@
         final NetworkStats result = after.subtract(before);
 
         // identical data should result in zero delta
-        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L,
-                0L, 0);
-        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L,
-                0L, 0);
+        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
+                0L, 0L, 0L, 0);
+        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
+                0L, 0L, 0L, 0);
     }
 
     public void testSubtractIdenticalRows() throws Exception {
@@ -198,10 +220,10 @@
         final NetworkStats result = after.subtract(before);
 
         // expect delta between measurements
-        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L, 1L, 2L,
-                1L, 4);
-        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 3L, 1L, 4L,
-                1L, 8);
+        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1L,
+                1L, 2L, 1L, 4);
+        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 3L,
+                1L, 4L, 1L, 8);
     }
 
     public void testSubtractNewRows() throws Exception {
@@ -217,12 +239,12 @@
         final NetworkStats result = after.subtract(before);
 
         // its okay to have new rows
-        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L,
-                0L, 0);
-        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L,
-                0L, 0);
-        assertValues(result, 2, TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
-                1024L, 8L, 20);
+        assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
+                0L, 0L, 0L, 0);
+        assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
+                0L, 0L, 0L, 0);
+        assertValues(result, 2, TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                1024L, 8L, 1024L, 8L, 20);
     }
 
     public void testSubtractMissingRows() throws Exception {
@@ -237,8 +259,8 @@
 
         // should silently drop omitted rows
         assertEquals(1, result.size());
-        assertValues(result, 0, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L,
-                2L, 3L, 4L, 0);
+        assertValues(result, 0, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO,
+                ROAMING_NO, 1L, 2L, 3L, 4L, 0);
         assertEquals(4L, result.getTotalBytes());
     }
 
@@ -263,13 +285,22 @@
                 .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L);
         assertEquals(64L, uidTag.getTotalBytes());
 
+        final NetworkStats uidMetered = new NetworkStats(TEST_START, 3)
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 32L, 0L,
+                        0L, 0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
+                        0L, 0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
+                        0L, 0L, 0L);
+        assertEquals(96L, uidMetered.getTotalBytes());
+
         final NetworkStats uidRoaming = new NetworkStats(TEST_START, 3)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L,
-                        0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L,
-                        0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_YES, 32L, 0L, 0L, 0L,
-                        0L);
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 32L, 0L,
+                        0L, 0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
+                        0L, 0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 32L, 0L,
+                        0L, 0L, 0L);
         assertEquals(96L, uidRoaming.getTotalBytes());
     }
 
@@ -283,95 +314,95 @@
 
     public void testGroupedByIfaceAll() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
-                .addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, ROAMING_NO, 128L, 8L, 0L, 2L,
-                        20L)
-                .addValues(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
+                .addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L, 0L,
                         2L, 20L)
-                .addValues(IFACE_ALL, 101, SET_ALL, TAG_NONE, ROAMING_YES, 128L, 8L, 0L, 2L,
-                        20L);
+                .addValues(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO, 128L,
+                        8L, 0L, 2L, 20L)
+                .addValues(IFACE_ALL, 101, SET_ALL, TAG_NONE, METERED_NO, ROAMING_YES, 128L, 8L, 0L,
+                        2L, 20L);
         final NetworkStats grouped = uidStats.groupedByIface();
 
         assertEquals(3, uidStats.size());
         assertEquals(1, grouped.size());
 
-        assertValues(grouped, 0, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, ROAMING_ALL, 384L, 24L, 0L,
-                6L, 0L);
+        assertValues(grouped, 0, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+                384L, 24L, 0L, 6L, 0L);
     }
 
     public void testGroupedByIface() throws Exception {
         final NetworkStats uidStats = new NetworkStats(TEST_START, 7)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
-                        2L, 20L)
-                .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 512L, 32L, 0L,
-                        0L, 0L)
-                .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 4L, 0L, 0L,
-                        0L)
-                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 512L, 32L,
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L,
+                        0L, 2L, 20L)
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 512L,
+                        32L, 0L, 0L, 0L)
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 64L, 4L,
                         0L, 0L, 0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
-                        0L, 0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 128L, 8L, 0L, 0L,
-                        0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_YES, 128L, 8L, 0L,
-                        0L, 0L);
+                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 512L,
+                        32L, 0L, 0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L,
+                        0L, 0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, 128L, 8L,
+                        0L, 0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 128L,
+                        8L, 0L, 0L, 0L);
 
         final NetworkStats grouped = uidStats.groupedByIface();
 
         assertEquals(7, uidStats.size());
 
         assertEquals(2, grouped.size());
-        assertValues(grouped, 0, TEST_IFACE, UID_ALL, SET_ALL, TAG_NONE, ROAMING_ALL, 384L, 24L, 0L,
-                2L, 0L);
-        assertValues(grouped, 1, TEST_IFACE2, UID_ALL, SET_ALL, TAG_NONE, ROAMING_ALL, 1024L, 64L,
-                0L, 0L, 0L);
+        assertValues(grouped, 0, TEST_IFACE, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+                384L, 24L, 0L, 2L, 0L);
+        assertValues(grouped, 1, TEST_IFACE2, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+                1024L, 64L, 0L, 0L, 0L);
     }
 
     public void testAddAllValues() {
         final NetworkStats first = new NetworkStats(TEST_START, 5)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L,
-                        0L)
-                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 32L, 0L, 0L,
-                        0L, 0L)
-                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_YES, 32L, 0L, 0L,
-                        0L, 0L);
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
+                        0L, 0L, 0L)
+                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 32L,
+                        0L, 0L, 0L, 0L)
+                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, 32L,
+                        0L, 0L, 0L, 0L);
 
         final NetworkStats second = new NetworkStats(TEST_START, 2)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L,
-                        0L)
-                .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L,
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
                         0L, 0L, 0L)
-                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_YES, 32L, 0L, 0L,
-                        0L, 0L);
+                .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 32L,
+                        0L, 0L, 0L, 0L)
+                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, 32L,
+                        0L, 0L, 0L, 0L);
 
         first.combineAllValues(second);
 
         assertEquals(4, first.size());
-        assertValues(first, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 64L, 0L, 0L,
-                0L, 0L);
-        assertValues(first, 1, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 32L, 0L,
-                0L, 0L, 0L);
-        assertValues(first, 2, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_YES, 64L, 0L,
-                0L, 0L, 0L);
-        assertValues(first, 3, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L,
+        assertValues(first, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 64L,
                 0L, 0L, 0L, 0L);
+        assertValues(first, 1, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                32L, 0L, 0L, 0L, 0L);
+        assertValues(first, 2, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
+                64L, 0L, 0L, 0L, 0L);
+        assertValues(first, 3, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                32L, 0L, 0L, 0L, 0L);
     }
 
     public void testGetTotal() {
         final NetworkStats stats = new NetworkStats(TEST_START, 7)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
-                        2L, 20L)
-                .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 512L, 32L, 0L,
-                        0L, 0L)
-                .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 4L, 0L, 0L,
-                        0L)
-                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 512L, 32L,
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L,
+                        0L, 2L, 20L)
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 512L,
+                        32L, 0L, 0L, 0L)
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 64L, 4L,
                         0L, 0L, 0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
-                        0L, 0L)
-                .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 128L, 8L, 0L, 0L,
-                        0L)
-                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_YES, 128L, 8L, 0L,
-                        0L, 0L);
+                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 512L,
+                        32L, 0L, 0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 128L,
+                        8L, 0L, 0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 128L, 8L,
+                        0L, 0L, 0L)
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 128L,
+                        8L, 0L, 0L, 0L);
 
         assertValues(stats.getTotal(null), 1408L, 88L, 0L, 2L, 20L);
         assertValues(stats.getTotal(null, 100), 1280L, 80L, 0L, 2L, 20L);
@@ -396,10 +427,10 @@
         final NetworkStats after = before.withoutUids(new int[] { 100 });
         assertEquals(6, before.size());
         assertEquals(2, after.size());
-        assertValues(after, 0, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L,
-                0L, 0L, 0L);
-        assertValues(after, 1, TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 128L, 8L, 0L,
-                0L, 0L);
+        assertValues(after, 0, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                128L, 8L, 0L, 0L, 0L);
+        assertValues(after, 1, TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 128L,
+                8L, 0L, 0L, 0L);
     }
 
     public void testClone() throws Exception {
@@ -434,77 +465,90 @@
         final String underlyingIface = "wlan0";
         final int testTag1 = 8888;
         NetworkStats delta = new NetworkStats(TEST_START, 17)
-            .addValues(tunIface, 10100, SET_DEFAULT, TAG_NONE, 39605L, 46L, 12259L, 55L, 0L)
-            .addValues(tunIface, 10100, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L)
-            .addValues(tunIface, 10120, SET_DEFAULT, TAG_NONE, 72667L, 197L, 43909L, 241L, 0L)
-            .addValues(tunIface, 10120, SET_FOREGROUND, TAG_NONE, 9297L, 17L, 4128L, 21L, 0L)
+            .addValues(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 39605L, 46L,
+                    12259L, 55L, 0L)
+            .addValues(tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 0L, 0L,
+                    0L, 0L, 0L)
+            .addValues(tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 72667L, 197L,
+                    43909L, 241L, 0L)
+            .addValues(tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 9297L,
+                    17L, 4128L, 21L, 0L)
             // VPN package also uses some traffic through unprotected network.
-            .addValues(tunIface, tunUid, SET_DEFAULT, TAG_NONE, 4983L, 10L, 1801L, 12L, 0L)
-            .addValues(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L)
+            .addValues(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 4983L, 10L,
+                    1801L, 12L, 0L)
+            .addValues(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 0L, 0L,
+                    0L, 0L, 0L)
             // Tag entries
-            .addValues(tunIface, 10120, SET_DEFAULT, testTag1, 21691L, 41L, 13820L, 51L, 0L)
-            .addValues(tunIface, 10120, SET_FOREGROUND, testTag1, 1281L, 2L, 665L, 2L, 0L)
+            .addValues(tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO, 21691L, 41L,
+                    13820L, 51L, 0L)
+            .addValues(tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO, 1281L, 2L,
+                    665L, 2L, 0L)
             // Irrelevant entries
-            .addValues(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, 1685L, 5L, 2070L, 6L, 0L)
+            .addValues(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1685L, 5L,
+                    2070L, 6L, 0L)
             // Underlying Iface entries
-            .addValues(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, 5178L, 8L, 2139L, 11L, 0L)
-            .addValues(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L)
-            .addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, 149873L, 287L,
-                    59217L /* smaller than sum(tun0) */, 299L /* smaller than sum(tun0) */, 0L)
-            .addValues(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
+            .addValues(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 5178L,
+                    8L, 2139L, 11L, 0L)
+            .addValues(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
+                    0L, 0L, 0L, 0L)
+            .addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                    149873L, 287L, 59217L /* smaller than sum(tun0) */,
+                    299L /* smaller than sum(tun0) */, 0L)
+            .addValues(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                    0L, 0L, 0L, 0L, 0L);
 
         assertTrue(delta.migrateTun(tunUid, tunIface, underlyingIface));
         assertEquals(20, delta.size());
 
         // tunIface and TEST_IFACE entries are not changed.
-        assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO,
+        assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 39605L, 46L, 12259L, 55L, 0L);
-        assertValues(delta, 1, tunIface, 10100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 0L, 0L,
-                0L, 0L, 0L);
-        assertValues(delta, 2, tunIface, 10120, SET_DEFAULT, TAG_NONE, ROAMING_NO,
+        assertValues(delta, 1, tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                0L, 0L, 0L, 0L, 0L);
+        assertValues(delta, 2, tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 72667L, 197L, 43909L, 241L, 0L);
-        assertValues(delta, 3, tunIface, 10120, SET_FOREGROUND, TAG_NONE, ROAMING_NO,
+        assertValues(delta, 3, tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
                 9297L, 17L, 4128L, 21L, 0L);
-        assertValues(delta, 4, tunIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_NO,
+        assertValues(delta, 4, tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 4983L, 10L, 1801L, 12L, 0L);
-        assertValues(delta, 5, tunIface, tunUid, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 0L, 0L,
-                0L, 0L, 0L);
-        assertValues(delta, 6, tunIface, 10120, SET_DEFAULT, testTag1, ROAMING_NO,
+        assertValues(delta, 5, tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                0L, 0L, 0L, 0L, 0L);
+        assertValues(delta, 6, tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO,
                 21691L, 41L, 13820L, 51L, 0L);
-        assertValues(delta, 7, tunIface, 10120, SET_FOREGROUND, testTag1, ROAMING_NO, 1281L,
-                2L, 665L, 2L, 0L);
-        assertValues(delta, 8, TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1685L, 5L,
-                2070L, 6L, 0L);
+        assertValues(delta, 7, tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO,
+                1281L, 2L, 665L, 2L, 0L);
+        assertValues(delta, 8, TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                1685L, 5L, 2070L, 6L, 0L);
 
         // Existing underlying Iface entries are updated
-        assertValues(delta, 9, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO,
-                44783L, 54L, 14178L, 62L, 0L);
-        assertValues(delta, 10, underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, ROAMING_NO,
-                0L, 0L, 0L, 0L, 0L);
+        assertValues(delta, 9, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO,
+                ROAMING_NO, 44783L, 54L, 14178L, 62L, 0L);
+        assertValues(delta, 10, underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO,
+                ROAMING_NO, 0L, 0L, 0L, 0L, 0L);
 
         // VPN underlying Iface entries are updated
-        assertValues(delta, 11, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_NO,
-                28304L, 27L, 1L, 2L, 0L);
-        assertValues(delta, 12, underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, ROAMING_NO,
-                0L, 0L, 0L, 0L, 0L);
+        assertValues(delta, 11, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO,
+                ROAMING_NO, 28304L, 27L, 1L, 2L, 0L);
+        assertValues(delta, 12, underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO,
+                ROAMING_NO, 0L, 0L, 0L, 0L, 0L);
 
         // New entries are added for new application's underlying Iface traffic
-        assertContains(delta, underlyingIface, 10120, SET_DEFAULT, TAG_NONE, ROAMING_NO,
-                72667L, 197L, 43123L, 227L, 0L);
-        assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, TAG_NONE, ROAMING_NO,
-                9297L, 17L, 4054, 19L, 0L);
-        assertContains(delta, underlyingIface, 10120, SET_DEFAULT, testTag1, ROAMING_NO,
-                21691L, 41L, 13572L, 48L, 0L);
-        assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, testTag1, ROAMING_NO,
-                1281L, 2L, 653L, 1L, 0L);
+        assertContains(delta, underlyingIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO,
+                ROAMING_NO, 72667L, 197L, 43123L, 227L, 0L);
+        assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO,
+                ROAMING_NO, 9297L, 17L, 4054, 19L, 0L);
+        assertContains(delta, underlyingIface, 10120, SET_DEFAULT, testTag1, METERED_NO,
+                ROAMING_NO, 21691L, 41L, 13572L, 48L, 0L);
+        assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, testTag1, METERED_NO,
+                ROAMING_NO, 1281L, 2L, 653L, 1L, 0L);
 
         // New entries are added for debug purpose
-        assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, ROAMING_NO,
-                39605L, 46L, 12039, 51, 0);
-        assertContains(delta, underlyingIface, 10120, SET_DBG_VPN_IN, TAG_NONE, ROAMING_NO,
-                81964, 214, 47177, 246, 0);
-        assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, ROAMING_ALL,
-                121569, 260, 59216, 297, 0);
+        assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, METERED_NO,
+                ROAMING_NO, 39605L, 46L, 12039, 51, 0);
+        assertContains(delta, underlyingIface, 10120, SET_DBG_VPN_IN, TAG_NONE, METERED_NO,
+                ROAMING_NO, 81964, 214, 47177, 246, 0);
+        assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, METERED_ALL,
+                ROAMING_ALL, 121569, 260, 59216, 297, 0);
 
     }
 
@@ -518,72 +562,78 @@
         final String underlyingIface = "wlan0";
         NetworkStats delta = new NetworkStats(TEST_START, 9)
             // 2 different apps sent/receive data via tun0.
-            .addValues(tunIface, 10100, SET_DEFAULT, TAG_NONE, 50000L, 25L, 100000L, 50L, 0L)
-            .addValues(tunIface, 20100, SET_DEFAULT, TAG_NONE, 500L, 2L, 200L, 5L, 0L)
+            .addValues(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 50000L, 25L,
+                    100000L, 50L, 0L)
+            .addValues(tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 500L, 2L,
+                    200L, 5L, 0L)
             // VPN package resends data through the tunnel (with exaggerated overhead)
-            .addValues(tunIface, tunUid, SET_DEFAULT, TAG_NONE, 240000, 100L, 120000L, 60L, 0L)
+            .addValues(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 240000,
+                    100L, 120000L, 60L, 0L)
             // 1 app already has some traffic on the underlying interface, the other doesn't yet
-            .addValues(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, 1000L, 10L, 2000L, 20L, 0L)
+            .addValues(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1000L,
+                    10L, 2000L, 20L, 0L)
             // Traffic through the underlying interface via the vpn app.
             // This test should redistribute this data correctly.
-            .addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE,
+            .addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                     75500L, 37L, 130000L, 70L, 0L);
 
         assertTrue(delta.migrateTun(tunUid, tunIface, underlyingIface));
         assertEquals(9, delta.size());
 
         // tunIface entries should not be changed.
-        assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO,
+        assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 50000L, 25L, 100000L, 50L, 0L);
-        assertValues(delta, 1, tunIface, 20100, SET_DEFAULT, TAG_NONE, ROAMING_NO,
+        assertValues(delta, 1, tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 500L, 2L, 200L, 5L, 0L);
-        assertValues(delta, 2, tunIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_NO,
+        assertValues(delta, 2, tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                 240000L, 100L, 120000L, 60L, 0L);
 
         // Existing underlying Iface entries are updated
-        assertValues(delta, 3, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO,
-                51000L, 35L, 102000L, 70L, 0L);
+        assertValues(delta, 3, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO,
+                ROAMING_NO, 51000L, 35L, 102000L, 70L, 0L);
 
         // VPN underlying Iface entries are updated
-        assertValues(delta, 4, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_NO,
-                25000L, 10L, 29800L, 15L, 0L);
+        assertValues(delta, 4, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO,
+                ROAMING_NO, 25000L, 10L, 29800L, 15L, 0L);
 
         // New entries are added for new application's underlying Iface traffic
-        assertContains(delta, underlyingIface, 20100, SET_DEFAULT, TAG_NONE, ROAMING_NO,
-                500L, 2L, 200L, 5L, 0L);
+        assertContains(delta, underlyingIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO,
+                ROAMING_NO, 500L, 2L, 200L, 5L, 0L);
 
         // New entries are added for debug purpose
-        assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, ROAMING_NO,
-                50000L, 25L, 100000L, 50L, 0L);
-        assertContains(delta, underlyingIface, 20100, SET_DBG_VPN_IN, TAG_NONE, ROAMING_NO,
-                500, 2L, 200L, 5L, 0L);
-        assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, ROAMING_ALL,
-                50500L, 27L, 100200L, 55, 0);
+        assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, METERED_NO,
+                ROAMING_NO, 50000L, 25L, 100000L, 50L, 0L);
+        assertContains(delta, underlyingIface, 20100, SET_DBG_VPN_IN, TAG_NONE, METERED_NO,
+                ROAMING_NO, 500, 2L, 200L, 5L, 0L);
+        assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, METERED_ALL,
+                ROAMING_ALL, 50500L, 27L, 100200L, 55, 0);
     }
 
     private static void assertContains(NetworkStats stats,  String iface, int uid, int set,
-            int tag, int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets,
-            long operations) {
-        int index = stats.findIndex(iface, uid, set, tag, roaming);
+            int tag, int metered, int roaming, long rxBytes, long rxPackets, long txBytes,
+            long txPackets, long operations) {
+        int index = stats.findIndex(iface, uid, set, tag, metered, roaming);
         assertTrue(index != -1);
-        assertValues(stats, index, iface, uid, set, tag, roaming,
+        assertValues(stats, index, iface, uid, set, tag, metered, roaming,
                 rxBytes, rxPackets, txBytes, txPackets, operations);
     }
 
     private static void assertValues(NetworkStats stats, int index, String iface, int uid, int set,
-            int tag, int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets,
-            long operations) {
+            int tag, int metered, int roaming, long rxBytes, long rxPackets, long txBytes,
+            long txPackets, long operations) {
         final NetworkStats.Entry entry = stats.getValues(index, null);
-        assertValues(entry, iface, uid, set, tag, roaming);
+        assertValues(entry, iface, uid, set, tag, metered, roaming);
         assertValues(entry, rxBytes, rxPackets, txBytes, txPackets, operations);
     }
 
     private static void assertValues(
-            NetworkStats.Entry entry, String iface, int uid, int set, int tag, int roaming) {
+            NetworkStats.Entry entry, String iface, int uid, int set, int tag, int metered,
+            int roaming) {
         assertEquals(iface, entry.iface);
         assertEquals(uid, entry.uid);
         assertEquals(set, entry.set);
         assertEquals(tag, entry.tag);
+        assertEquals(metered, entry.metered);
         assertEquals(roaming, entry.roaming);
     }
 
diff --git a/core/tests/coretests/src/android/provider/DocumentsProviderTest.java b/core/tests/coretests/src/android/provider/DocumentsProviderTest.java
index 0b4675c..d1c68a9 100644
--- a/core/tests/coretests/src/android/provider/DocumentsProviderTest.java
+++ b/core/tests/coretests/src/android/provider/DocumentsProviderTest.java
@@ -60,7 +60,7 @@
                 DocumentsContract.buildDocumentUri(TestDocumentsProvider.AUTHORITY, DOCUMENT_ID);
         try (ContentProviderClient client =
                      mResolver.acquireUnstableContentProviderClient(docUri)) {
-            final Path actual = DocumentsContract.findPath(client, docUri);
+            final Path actual = DocumentsContract.findDocumentPath(client, docUri);
             assertEquals(expected, actual);
         }
     }
@@ -73,7 +73,7 @@
 
         final Uri docUri = buildTreeDocumentUri(
                 TestDocumentsProvider.AUTHORITY, PARENT_DOCUMENT_ID, DOCUMENT_ID);
-        final List<String> actual = DocumentsContract.findPath(mResolver, docUri);
+        final List<String> actual = DocumentsContract.findDocumentPath(mResolver, docUri);
 
         assertEquals(expected.getPath(), actual);
     }
@@ -83,28 +83,21 @@
 
         final Uri docUri = buildTreeDocumentUri(
                 TestDocumentsProvider.AUTHORITY, PARENT_DOCUMENT_ID, DOCUMENT_ID);
-        assertNull(DocumentsContract.findPath(mResolver, docUri));
+        assertNull(DocumentsContract.findDocumentPath(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.findDocumentPath(client, docUri);
+            assertNull(path.getRootId());
+        }
     }
 
     private static Uri buildTreeDocumentUri(String authority, String parentDocId, String docId) {
diff --git a/core/tests/coretests/src/android/provider/TestDocumentsProvider.java b/core/tests/coretests/src/android/provider/TestDocumentsProvider.java
index 8dcf566..d61049d 100644
--- a/core/tests/coretests/src/android/provider/TestDocumentsProvider.java
+++ b/core/tests/coretests/src/android/provider/TestDocumentsProvider.java
@@ -85,7 +85,7 @@
     }
 
     @Override
-    public Path findPath(String documentId, @Nullable String parentDocumentId) {
+    public Path findDocumentPath(String documentId, @Nullable String parentDocumentId) {
         lastDocumentId = documentId;
         lastParentDocumentId = parentDocumentId;
 
diff --git a/core/tests/coretests/src/android/widget/RemoteViewsTest.java b/core/tests/coretests/src/android/widget/RemoteViewsTest.java
index 4e3bf46..7ba46be 100644
--- a/core/tests/coretests/src/android/widget/RemoteViewsTest.java
+++ b/core/tests/coretests/src/android/widget/RemoteViewsTest.java
@@ -20,6 +20,7 @@
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.os.Parcel;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -35,6 +36,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Tests for RemoteViews.
@@ -43,6 +45,9 @@
 @SmallTest
 public class RemoteViewsTest {
 
+    // This can point to any other package which exists on the device.
+    private static final String OTHER_PACKAGE = "com.android.systemui";
+
     @Rule
     public final ExpectedException exception = ExpectedException.none();
 
@@ -121,4 +126,44 @@
         clone.apply(mContext, mContainer);
     }
 
+    @Test
+    public void parcelSize_nestedViews() {
+        RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test);
+        // We don't care about the actual layout id.
+        RemoteViews child = new RemoteViews(mPackage, 33);
+        int expectedSize = getParcelSize(original) + getParcelSize(child);
+        original.addView(R.id.layout, child);
+
+        // The application info will get written only once.
+        assertTrue(getParcelSize(original) < expectedSize);
+        assertEquals(getParcelSize(original), getParcelSize(original.clone()));
+
+        original = new RemoteViews(mPackage, R.layout.remote_views_test);
+        child = new RemoteViews(OTHER_PACKAGE, 33);
+        expectedSize = getParcelSize(original) + getParcelSize(child);
+        original.addView(R.id.layout, child);
+
+        // Both the views will get written completely along with an additional view operation
+        assertTrue(getParcelSize(original) > expectedSize);
+        assertEquals(getParcelSize(original), getParcelSize(original.clone()));
+    }
+
+    @Test
+    public void parcelSize_differentOrientation() {
+        RemoteViews landscape = new RemoteViews(mPackage, R.layout.remote_views_test);
+        RemoteViews portrait = new RemoteViews(mPackage, 33);
+
+        // The application info will get written only once.
+        RemoteViews views = new RemoteViews(landscape, portrait);
+        assertTrue(getParcelSize(views) < (getParcelSize(landscape) + getParcelSize(portrait)));
+        assertEquals(getParcelSize(views), getParcelSize(views.clone()));
+    }
+
+    private int getParcelSize(RemoteViews view) {
+        Parcel parcel = Parcel.obtain();
+        view.writeToParcel(parcel, 0);
+        int size = parcel.dataSize();
+        parcel.recycle();
+        return size;
+    }
 }
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index d0802a0..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,6 @@
         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());
@@ -184,7 +177,6 @@
         onView(withId(R.id.textview)).check(hasSelection("\uD83D\uDE01"));
     }
 
-    @SmallTest
     public void testDragAndDrop() throws Exception {
         final String text = "abc def ghi.";
         onView(withId(R.id.textview)).perform(click());
@@ -206,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());
@@ -217,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());
@@ -228,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());
@@ -238,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());
@@ -249,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());
@@ -266,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
@@ -294,7 +280,6 @@
         assertFloatingToolbarIsDisplayed();
     }
 
-    @SmallTest
     public void testToolbarAndInsertionHandle() throws Exception {
         final String text = "text";
         onView(withId(R.id.textview)).perform(click());
@@ -314,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());
@@ -350,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());
@@ -370,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());
@@ -390,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());
@@ -415,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());
@@ -460,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());
@@ -485,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"
@@ -518,7 +496,6 @@
     }
 
 
-    @SmallTest
     public void testSelectionHandles_doesNotPassAnotherHandle() throws Exception {
         final String text = "abcd efg hijk lmn";
         onView(withId(R.id.textview)).perform(click());
@@ -536,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());
@@ -554,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());
@@ -607,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());
@@ -643,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());
@@ -707,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/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
index 327f3fd..7f13abc 100644
--- a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
+++ b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.net;
 
+import static android.net.NetworkStats.METERED_NO;
 import static android.net.NetworkStats.ROAMING_NO;
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.SET_DEFAULT;
@@ -101,12 +102,14 @@
 
         final NetworkStats stats = mFactory.readNetworkStatsDetail();
         assertEquals(70, stats.size());
-        assertStatsEntry(stats, "rmnet1", 10021, SET_DEFAULT, 0x30100000, 219110L, 578L, 227423L, 676L);
+        assertStatsEntry(stats, "rmnet1", 10021, SET_DEFAULT, 0x30100000, 219110L, 578L, 227423L,
+                676L);
         assertStatsEntry(stats, "rmnet1", 10021, SET_FOREGROUND, 0x30100000, 742L, 3L, 1265L, 3L);
     }
 
     public void testNetworkStatsSingle() throws Exception {
-        stageFile(R.raw.xt_qtaguid_iface_typical, new File(mTestProc, "net/xt_qtaguid/iface_stat_all"));
+        stageFile(R.raw.xt_qtaguid_iface_typical,
+                new File(mTestProc, "net/xt_qtaguid/iface_stat_all"));
 
         final NetworkStats stats = mFactory.readNetworkStatsSummaryDev();
         assertEquals(6, stats.size());
@@ -122,7 +125,8 @@
         final NetworkStats stats = mFactory.readNetworkStatsSummaryXt();
         assertEquals(3, stats.size());
         assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 6824L, 16L, 5692L, 10L);
-        assertStatsEntry(stats, "rmnet1", UID_ALL, SET_ALL, TAG_NONE, 11153922L, 8051L, 190226L, 2468L);
+        assertStatsEntry(stats, "rmnet1", UID_ALL, SET_ALL, TAG_NONE, 11153922L, 8051L, 190226L,
+                2468L);
         assertStatsEntry(stats, "rmnet2", UID_ALL, SET_ALL, TAG_NONE, 4968L, 35L, 3081L, 39L);
     }
 
@@ -157,7 +161,7 @@
 
     private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
             int tag, long rxBytes, long txBytes) {
-        final int i = stats.findIndex(iface, uid, set, tag, ROAMING_NO);
+        final int i = stats.findIndex(iface, uid, set, tag, METERED_NO, ROAMING_NO);
         final NetworkStats.Entry entry = stats.getValues(i, null);
         assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
         assertEquals("unexpected txBytes", txBytes, entry.txBytes);
@@ -165,7 +169,7 @@
 
     private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
             int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) {
-        final int i = stats.findIndex(iface, uid, set, tag, ROAMING_NO);
+        final int i = stats.findIndex(iface, uid, set, tag, METERED_NO, ROAMING_NO);
         final NetworkStats.Entry entry = stats.getValues(i, null);
         assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
         assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
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/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index fd2f705..79c63ee 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1655,16 +1655,6 @@
         nativePrepareToDraw(mNativePtr);
     }
 
-    /**
-     * Refs the underlying SkPixelRef and returns a pointer to it.
-     *
-     * @hide
-     * */
-    public final long refSkPixelRef() {
-        checkRecycled("Can't refSkPixelRef on a recycled bitmap!");
-        return nativeRefPixelRef(mNativePtr);
-    }
-
     //////////// native methods
 
     private static native Bitmap nativeCreate(int[] colors, int offset,
@@ -1721,7 +1711,6 @@
     private static native boolean nativeHasMipMap(long nativeBitmap);
     private static native void nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap);
     private static native boolean nativeSameAs(long nativeBitmap0, long nativeBitmap1);
-    private static native long nativeRefPixelRef(long nativeBitmap);
     private static native void nativePrepareToDraw(long nativeBitmap);
     private static native int nativeGetAllocationByteCount(long nativeBitmap);
 }
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
index 7d7d42c7..ad1ead8 100644
--- a/libs/androidfw/Android.mk
+++ b/libs/androidfw/Android.mk
@@ -50,6 +50,8 @@
 LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
 LOCAL_SRC_FILES:= $(hostSources)
 LOCAL_C_INCLUDES := external/zlib
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 
 include $(BUILD_HOST_STATIC_LIBRARY)
 
@@ -72,6 +74,8 @@
     libutils \
     libz
 
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
 LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 46fc9d4..ae789d6 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -684,6 +684,7 @@
             sharedRes->add(oass, oidmap, offset + 1, false);
             const_cast<AssetManager*>(this)->mAssetPaths.add(oap);
             const_cast<AssetManager*>(this)->mZipSet.addOverlay(targetPackagePath, oap);
+            delete oidmap;
         }
     }
 
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index b16279c..7d1e328 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -3577,7 +3577,7 @@
             }
             if (pi != NULL) {
                 if (kDebugTableTheme) {
-                    ALOGI("Desired type index is %zd in avail %zu", t, Res_MAXTYPE + 1);
+                    ALOGI("Desired type index is %u in avail %zu", t, Res_MAXTYPE + 1);
                 }
                 if (t <= Res_MAXTYPE) {
                     const type_info& ti = pi->types[t];
diff --git a/include/androidfw/Asset.h b/libs/androidfw/include/androidfw/Asset.h
similarity index 98%
rename from include/androidfw/Asset.h
rename to libs/androidfw/include/androidfw/Asset.h
index 52c8637..461e773 100644
--- a/include/androidfw/Asset.h
+++ b/libs/androidfw/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.
  *
@@ -48,7 +49,7 @@
 
     static int32_t getGlobalCount();
     static String8 getAssetAllocations();
-    
+
     /* used when opening an asset */
     typedef enum AccessMode {
         ACCESS_UNKNOWN = 0,
@@ -210,7 +211,7 @@
 
     AccessMode  mAccessMode;        // how the asset was opened
     String8    mAssetSource;       // debug string
-    
+
     Asset*		mNext;				// linked list.
     Asset*		mPrev;
 };
@@ -273,7 +274,7 @@
 
     FileMap*    mMap;           // for memory map
     unsigned char* mBuf;        // for read
-    
+
     const void* ensureAlignment(FileMap* map);
 };
 
@@ -310,7 +311,7 @@
     virtual const void* getBuffer(bool wordAligned);
     virtual off64_t getLength(void) const { return mUncompressedLen; }
     virtual off64_t getRemainingLength(void) const { return mUncompressedLen-mOffset; }
-    virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const { return -1; }
+    virtual int openFileDescriptor(off64_t* /* outStart */, off64_t* /* outLength */) const { return -1; }
     virtual bool isAllocated(void) const { return mBuf != NULL; }
 
 private:
diff --git a/include/androidfw/AssetDir.h b/libs/androidfw/include/androidfw/AssetDir.h
similarity index 100%
rename from include/androidfw/AssetDir.h
rename to libs/androidfw/include/androidfw/AssetDir.h
diff --git a/include/androidfw/AssetManager.h b/libs/androidfw/include/androidfw/AssetManager.h
similarity index 97%
rename from include/androidfw/AssetManager.h
rename to libs/androidfw/include/androidfw/AssetManager.h
index 4377213..0441b9d 100644
--- a/include/androidfw/AssetManager.h
+++ b/libs/androidfw/include/androidfw/AssetManager.h
@@ -33,17 +33,8 @@
 /*
  * Native-app access is via the opaque typedef struct AAssetManager in the C namespace.
  */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 struct AAssetManager { };
 
-#ifdef __cplusplus
-};
-#endif
-
-
 /*
  * Now the proper C++ android-namespace definitions
  */
@@ -83,8 +74,8 @@
     virtual ~AssetManager(void);
 
     static int32_t getGlobalCount();
-    
-    /*                                                                       
+
+    /*
      * Add a new source for assets.  This can be called multiple times to
      * look in multiple places for assets.  It can be either a directory (for
      * finding assets as raw files on the disk) or a ZIP file.  This newly
@@ -178,7 +169,7 @@
      */
     FileType getFileType(const char* fileName);
 
-    /*                                                                       
+    /*
      * Return the complete resource table to find things in the package.
      */
     const ResTable& getResources(bool required = true) const;
@@ -255,12 +246,12 @@
 
         ResTable* getResourceTable();
         ResTable* setResourceTable(ResTable* res);
-        
+
         bool isUpToDate();
 
         void addOverlay(const asset_path& ap);
         bool getOverlay(size_t idx, asset_path* out) const;
-        
+
     protected:
         ~SharedZip();
 
@@ -312,7 +303,7 @@
 
         void addOverlay(const String8& path, const asset_path& overlay);
         bool getOverlay(const String8& path, size_t idx, asset_path* out) const;
-        
+
     private:
         void closeZip(int idx);
 
diff --git a/include/androidfw/AttributeResolution.h b/libs/androidfw/include/androidfw/AttributeResolution.h
similarity index 100%
rename from include/androidfw/AttributeResolution.h
rename to libs/androidfw/include/androidfw/AttributeResolution.h
diff --git a/include/androidfw/BackupHelpers.h b/libs/androidfw/include/androidfw/BackupHelpers.h
similarity index 100%
rename from include/androidfw/BackupHelpers.h
rename to libs/androidfw/include/androidfw/BackupHelpers.h
diff --git a/include/androidfw/ByteBucketArray.h b/libs/androidfw/include/androidfw/ByteBucketArray.h
similarity index 100%
rename from include/androidfw/ByteBucketArray.h
rename to libs/androidfw/include/androidfw/ByteBucketArray.h
diff --git a/include/androidfw/CursorWindow.h b/libs/androidfw/include/androidfw/CursorWindow.h
similarity index 100%
rename from include/androidfw/CursorWindow.h
rename to libs/androidfw/include/androidfw/CursorWindow.h
diff --git a/include/androidfw/DisplayEventDispatcher.h b/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
similarity index 100%
rename from include/androidfw/DisplayEventDispatcher.h
rename to libs/androidfw/include/androidfw/DisplayEventDispatcher.h
diff --git a/include/androidfw/LocaleData.h b/libs/androidfw/include/androidfw/LocaleData.h
similarity index 100%
rename from include/androidfw/LocaleData.h
rename to libs/androidfw/include/androidfw/LocaleData.h
diff --git a/include/androidfw/ObbFile.h b/libs/androidfw/include/androidfw/ObbFile.h
similarity index 96%
rename from include/androidfw/ObbFile.h
rename to libs/androidfw/include/androidfw/ObbFile.h
index 47559cd..3dbf997 100644
--- a/include/androidfw/ObbFile.h
+++ b/libs/androidfw/include/androidfw/ObbFile.h
@@ -124,20 +124,13 @@
     /* Flags for this OBB type. */
     int32_t mFlags;
 
-    /* Whether the file is salted. */
-    bool mSalted;
-
     /* The encryption salt. */
     unsigned char mSalt[8];
 
     const char* mFileName;
 
-    size_t mFileSize;
-
     size_t mFooterStart;
 
-    unsigned char* mReadBuf;
-
     bool parseObbFile(int fd);
 };
 
diff --git a/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
similarity index 99%
rename from include/androidfw/ResourceTypes.h
rename to libs/androidfw/include/androidfw/ResourceTypes.h
index 6349e86..08d6591 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/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/StreamingZipInflater.h b/libs/androidfw/include/androidfw/StreamingZipInflater.h
similarity index 100%
rename from include/androidfw/StreamingZipInflater.h
rename to libs/androidfw/include/androidfw/StreamingZipInflater.h
diff --git a/include/androidfw/TypeWrappers.h b/libs/androidfw/include/androidfw/TypeWrappers.h
similarity index 97%
rename from include/androidfw/TypeWrappers.h
rename to libs/androidfw/include/androidfw/TypeWrappers.h
index 7bdf8af..f1daf33 100644
--- a/include/androidfw/TypeWrappers.h
+++ b/libs/androidfw/include/androidfw/TypeWrappers.h
@@ -18,6 +18,7 @@
 #define __TYPE_WRAPPERS_H
 
 #include <androidfw/ResourceTypes.h>
+#include <utils/ByteOrder.h>
 
 namespace android {
 
@@ -30,6 +31,7 @@
         iterator& operator=(const iterator& rhs) {
             mTypeVariant = rhs.mTypeVariant;
             mIndex = rhs.mIndex;
+            return *this;
         }
 
         bool operator==(const iterator& rhs) const {
diff --git a/include/androidfw/ZipFileRO.h b/libs/androidfw/include/androidfw/ZipFileRO.h
similarity index 100%
rename from include/androidfw/ZipFileRO.h
rename to libs/androidfw/include/androidfw/ZipFileRO.h
diff --git a/include/androidfw/ZipUtils.h b/libs/androidfw/include/androidfw/ZipUtils.h
similarity index 100%
rename from include/androidfw/ZipUtils.h
rename to libs/androidfw/include/androidfw/ZipUtils.h
diff --git a/include/androidfw/misc.h b/libs/androidfw/include/androidfw/misc.h
similarity index 100%
rename from include/androidfw/misc.h
rename to libs/androidfw/include/androidfw/misc.h
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 0aa7808..8dc502a 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -18,6 +18,16 @@
     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/SkiaOpenGLPipeline.cpp \
+    pipeline/skia/SkiaPipeline.cpp \
+    pipeline/skia/SkiaProfileRenderer.cpp \
+    pipeline/skia/SkiaRecordingCanvas.cpp \
+    pipeline/skia/SkiaVulkanPipeline.cpp \
     renderstate/Blend.cpp \
     renderstate/MeshState.cpp \
     renderstate/OffscreenBufferPool.cpp \
@@ -38,7 +48,6 @@
     utils/Blur.cpp \
     utils/GLUtils.cpp \
     utils/LinearAllocator.cpp \
-    utils/NinePatchImpl.cpp \
     utils/StringUtils.cpp \
     utils/TestWindowContext.cpp \
     utils/VectorDrawableUtils.cpp \
@@ -80,6 +89,7 @@
     PathParser.cpp \
     PathTessellator.cpp \
     PixelBuffer.cpp \
+    ProfileRenderer.cpp \
     Program.cpp \
     ProgramCache.cpp \
     Properties.cpp \
@@ -94,7 +104,6 @@
     ShadowTessellator.cpp \
     SkiaCanvas.cpp \
     SkiaCanvasProxy.cpp \
-    SkiaDisplayList.cpp \
     SkiaShader.cpp \
     Snapshot.cpp \
     SpotShadow.cpp \
@@ -169,6 +178,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 +275,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,11 +294,13 @@
     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 \
     tests/unit/SkiaBehaviorTests.cpp \
     tests/unit/SkiaDisplayListTests.cpp \
+    tests/unit/SkiaPipelineTests.cpp \
     tests/unit/SkiaCanvasTests.cpp \
     tests/unit/SnapshotTests.cpp \
     tests/unit/StringUtilsTests.cpp \
@@ -348,6 +361,7 @@
     tests/microbench/FrameBuilderBench.cpp \
     tests/microbench/LinearAllocatorBench.cpp \
     tests/microbench/PathParserBench.cpp \
+    tests/microbench/RenderNodeBench.cpp \
     tests/microbench/ShadowBench.cpp \
     tests/microbench/TaskManagerBench.cpp
 
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
index 4cfbb2a..700642e 100644
--- a/libs/hwui/DeviceInfo.cpp
+++ b/libs/hwui/DeviceInfo.cpp
@@ -41,6 +41,13 @@
     });
 }
 
+void DeviceInfo::initialize(int maxTextureSize) {
+    std::call_once(sInitializedFlag, [maxTextureSize]() {
+        sDeviceInfo = new DeviceInfo();
+        sDeviceInfo->mMaxTextureSize = maxTextureSize;
+    });
+}
+
 void DeviceInfo::load() {
     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
 }
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
index e551eb9..aff84b0 100644
--- a/libs/hwui/DeviceInfo.h
+++ b/libs/hwui/DeviceInfo.h
@@ -32,6 +32,7 @@
     // only call this after GL has been initialized, or at any point if compiled
     // with HWUI_NULL_GPU
     static void initialize();
+    static void initialize(int maxTextureSize);
 
     int maxTextureSize() const { return mMaxTextureSize; }
 
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..34c7934 100644
--- a/libs/hwui/Glop.h
+++ b/libs/hwui/Glop.h
@@ -25,7 +25,6 @@
 
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
-#include <SkXfermode.h>
 
 namespace android {
 namespace uirenderer {
@@ -119,7 +118,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..34e6d39 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -257,7 +257,7 @@
             // If the blend mode cannot be implemented using shaders, fall
             // back to the default SrcOver blend mode instead
             if (CC_UNLIKELY(mCaches.extensions().hasFramebufferFetch())) {
-                mDescription.framebufferMode = (SkXfermode::Mode)mode;
+                mDescription.framebufferMode = mode;
                 mDescription.swapSrcDst = (modeUsage == Blend::ModeOrderSwap::Swap);
                 // blending in shader, don't enable
             } else {
@@ -271,11 +271,11 @@
 
     if (colorFilter) {
         SkColor color;
-        SkXfermode::Mode xmode;
+        SkBlendMode bmode;
         SkScalar srcColorMatrix[20];
-        if (colorFilter->asColorMode(&color, &xmode)) {
+        if (colorFilter->asColorMode(&color, &bmode)) {
             mOutGlop->fill.filterMode = mDescription.colorOp = ProgramDescription::ColorFilterMode::Blend;
-            mDescription.colorMode = xmode;
+            mDescription.colorMode = bmode;
             mOutGlop->fill.filter.color.set(color);
         } else if (colorFilter->asColorMatrix(srcColorMatrix)) {
             mOutGlop->fill.filterMode = mDescription.colorOp = ProgramDescription::ColorFilterMode::Matrix;
@@ -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/Program.h b/libs/hwui/Program.h
index f5beb62..e410d71 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -22,7 +22,7 @@
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
-#include <SkXfermode.h>
+#include <SkBlendMode.h>
 
 #include "Debug.h"
 #include "FloatColor.h"
@@ -142,7 +142,7 @@
     Gradient gradientType;
     bool isSimpleGradient;
 
-    SkXfermode::Mode shadersMode;
+    SkBlendMode shadersMode;
 
     bool isBitmapFirst;
     GLenum bitmapWrapS;
@@ -150,11 +150,11 @@
 
     // Color operations
     ColorFilterMode colorOp;
-    SkXfermode::Mode colorMode;
+    SkBlendMode colorMode;
 
     // Framebuffer blending (requires Extensions.hasFramebufferFetch())
-    // Ignored for all values < SkXfermode::kPlus_Mode
-    SkXfermode::Mode framebufferMode;
+    // Ignored for all values < SkBlendMode::kPlus
+    SkBlendMode framebufferMode;
     bool swapSrcDst;
 
     bool hasDebugHighlight;
@@ -186,16 +186,16 @@
         gradientType = kGradientLinear;
         isSimpleGradient = false;
 
-        shadersMode = SkXfermode::kClear_Mode;
+        shadersMode = SkBlendMode::kClear;
 
         isBitmapFirst = false;
         bitmapWrapS = GL_CLAMP_TO_EDGE;
         bitmapWrapT = GL_CLAMP_TO_EDGE;
 
         colorOp = ColorFilterMode::None;
-        colorMode = SkXfermode::kClear_Mode;
+        colorMode = SkBlendMode::kClear;
 
-        framebufferMode = SkXfermode::kClear_Mode;
+        framebufferMode = SkBlendMode::kClear;
         swapSrcDst = false;
 
         hasDebugHighlight = false;
@@ -244,7 +244,7 @@
         key |= programid(gradientType) << PROGRAM_GRADIENT_TYPE_SHIFT;
         if (isBitmapFirst) key |= PROGRAM_KEY_BITMAP_FIRST;
         if (hasBitmap && hasGradient) {
-            key |= (shadersMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_SHADER_SHIFT;
+            key |= ((int)shadersMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_SHADER_SHIFT;
         }
         switch (colorOp) {
             case ColorFilterMode::Matrix:
@@ -252,12 +252,12 @@
                 break;
             case ColorFilterMode::Blend:
                 key |= PROGRAM_KEY_COLOR_BLEND;
-                key |= (colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT;
+                key |= ((int)colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT;
                 break;
             case ColorFilterMode::None:
                 break;
         }
-        key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
+        key |= ((int)framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
         if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST;
         if (modulate) key |= programid(0x1) << PROGRAM_MODULATE_SHIFT;
         if (hasVertexAlpha) key |= programid(0x1) << PROGRAM_HAS_VERTEX_ALPHA_SHIFT;
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 4ef6b85..1afc978 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -572,7 +572,7 @@
 String8 ProgramCache::generateFragmentShader(const ProgramDescription& description) {
     String8 shader(gFS_Header_Start);
 
-    const bool blendFramebuffer = description.framebufferMode >= SkXfermode::kPlus_Mode;
+    const bool blendFramebuffer = description.framebufferMode >= SkBlendMode::kPlus;
     if (blendFramebuffer) {
         shader.append(gFS_Header_Extension_FramebufferFetch);
     }
@@ -809,12 +809,12 @@
     return shader;
 }
 
-void ProgramCache::generateBlend(String8& shader, const char* name, SkXfermode::Mode mode) {
+void ProgramCache::generateBlend(String8& shader, const char* name, SkBlendMode mode) {
     shader.append("\nvec4 ");
     shader.append(name);
     shader.append("(vec4 src, vec4 dst) {\n");
     shader.append("    ");
-    shader.append(gBlendOps[mode]);
+    shader.append(gBlendOps[(int)mode]);
     shader.append("}\n");
 }
 
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index 292ecdf..c2f715d 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -51,7 +51,7 @@
     Program* generateProgram(const ProgramDescription& description, programid key);
     String8 generateVertexShader(const ProgramDescription& description);
     String8 generateFragmentShader(const ProgramDescription& description);
-    void generateBlend(String8& shader, const char* name, SkXfermode::Mode mode);
+    void generateBlend(String8& shader, const char* name, SkBlendMode mode);
     void generateTextureWrap(String8& shader, GLenum wrapS, GLenum wrapT);
 
     void printLongString(const String8& shader) const;
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/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index f5bcba2..9d18484 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -666,7 +666,6 @@
     SkBitmap bitmap;
     SkShader::TileMode xy[2];
     if (shader->isABitmap(&bitmap, nullptr, xy)) {
-        // TODO: create  hwui-owned BitmapShader.
         Bitmap* hwuiBitmap = static_cast<Bitmap*>(bitmap.pixelRef());
         refBitmap(*hwuiBitmap);
         return;
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index a8fcfeb..f93e8b8 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -26,7 +26,6 @@
 #include "hwui/Canvas.h"
 #include "utils/LinearAllocator.h"
 #include "utils/Macros.h"
-#include "utils/NinePatch.h"
 
 #include <SkDrawFilter.h>
 #include <SkPaint.h>
@@ -316,7 +315,7 @@
     const ClipBase* mDeferredBarrierClip = nullptr;
     DisplayList* mDisplayList = nullptr;
     bool mHighContrastText = false;
-    SkAutoTUnref<SkDrawFilter> mDrawFilter;
+    sk_sp<SkDrawFilter> mDrawFilter;
 }; // class RecordingCanvas
 
 }; // namespace uirenderer
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index a05c744..b8964f0 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -32,7 +32,8 @@
 #include "DisplayList.h"
 #include "Matrix.h"
 #include "RenderProperties.h"
-#include "SkiaDisplayList.h"
+#include "pipeline/skia/SkiaDisplayList.h"
+#include "pipeline/skia/SkiaLayer.h"
 
 #include <vector>
 
@@ -50,7 +51,6 @@
 class FrameBuilder;
 class OffscreenBuffer;
 class Rect;
-class SkiaDisplayList;
 class SkiaShader;
 struct RenderNodeOp;
 
@@ -294,14 +294,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);
     }
 
@@ -309,14 +309,23 @@
      * Returns true if an offscreen layer from any renderPipeline is attached
      * to this node.
      */
-    bool hasLayer() const { return mLayer || mLayerSurface.get(); }
+    bool hasLayer() const { return mLayer || mSkiaLayer.get(); }
 
     /**
      * Used by the RenderPipeline to attach an offscreen surface to the RenderNode.
      * The surface is then will be used to store the contents of a layer.
      */
-    void setLayerSurface(sk_sp<SkSurface> layer) { mLayerSurface = layer; }
-
+    void setLayerSurface(sk_sp<SkSurface> layer) {
+        if (layer.get()) {
+            if (!mSkiaLayer.get()) {
+                mSkiaLayer = std::make_unique<skiapipeline::SkiaLayer>();
+            }
+            mSkiaLayer->layerSurface = std::move(layer);
+            mSkiaLayer->inverseTransformInWindow.loadIdentity();
+        } else {
+            mSkiaLayer.reset();
+        }
+    }
 
     /**
      * If the RenderNode is of type LayerType::RenderLayer then this method will
@@ -327,7 +336,13 @@
      * NOTE: this function is only guaranteed to return accurate results after
      *       prepareTree has been run for this RenderNode
      */
-    SkSurface* getLayerSurface() const { return mLayerSurface.get(); }
+    SkSurface* getLayerSurface() const {
+        return mSkiaLayer.get() ? mSkiaLayer->layerSurface.get() : nullptr;
+    }
+
+    skiapipeline::SkiaLayer* getSkiaLayer() const {
+        return mSkiaLayer.get();
+    }
 
 private:
     /**
@@ -337,13 +352,13 @@
      *  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
      * when it has been set to draw as a LayerType::RenderLayer.
      */
-    sk_sp<SkSurface> mLayerSurface;
+    std::unique_ptr<skiapipeline::SkiaLayer> mSkiaLayer;
 }; // class RenderNode
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 11aaebd..7c97e77 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>
@@ -56,6 +58,8 @@
     mCanvas.reset(new SkCanvas(bitmap));
 }
 
+SkiaCanvas::~SkiaCanvas() {}
+
 void SkiaCanvas::reset(SkCanvas* skiaCanvas) {
     mCanvas.reset(SkRef(skiaCanvas));
     mSaveStack.reset(nullptr);
@@ -542,7 +546,7 @@
 #endif
     const int ptCount = vertexCount >> 1;
     mCanvas->drawVertices(vertexMode, ptCount, (SkPoint*)verts, (SkPoint*)texs,
-                          (SkColor*)colors, NULL, indices, indexCount, paint);
+                          (SkColor*)colors, indices, indexCount, paint);
 }
 
 // ----------------------------------------------------------------------------
@@ -666,83 +670,10 @@
     tmpPaint.setShader(image->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode));
 
     mCanvas->drawVertices(SkCanvas::kTriangles_VertexMode, ptCount, (SkPoint*)vertices,
-                         texs, (const SkColor*)colors, NULL, indices,
+                         texs, (const SkColor*)colors, indices,
                          indexCount, tmpPaint);
 }
 
-static inline void set_lattice_divs(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 num_distinct_rects(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 set_lattice_flags(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;
-    }
-}
-
 void SkiaCanvas::drawNinePatch(Bitmap& hwuiBitmap, const Res_png_9patch& chunk,
         float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) {
 
@@ -750,11 +681,11 @@
     hwuiBitmap.getSkBitmap(&bitmap);
 
     SkCanvas::Lattice lattice;
-    set_lattice_divs(&lattice, chunk, bitmap.width(), bitmap.height());
+    NinePatchUtils::SetLatticeDivs(&lattice, chunk, bitmap.width(), bitmap.height());
 
     lattice.fFlags = nullptr;
     int numFlags = 0;
-    if (chunk.numColors > 0 && chunk.numColors == num_distinct_rects(lattice)) {
+    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);
@@ -762,7 +693,7 @@
 
     SkAutoSTMalloc<25, SkCanvas::Lattice::Flags> flags(numFlags);
     if (numFlags > 0) {
-        set_lattice_flags(&lattice, flags.get(), numFlags, chunk);
+        NinePatchUtils::SetLatticeFlags(&lattice, flags.get(), numFlags, chunk);
     }
 
     lattice.fBounds = nullptr;
@@ -836,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());
 }
 
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index d1edff9..a0cdfcb 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -40,6 +40,8 @@
      */
     explicit SkiaCanvas(SkCanvas* canvas);
 
+    virtual ~SkiaCanvas();
+
     virtual SkCanvas* asSkCanvas() override {
         return mCanvas.get();
     }
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index 863146e..5978abc 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -27,6 +27,7 @@
 #include <SkRRect.h>
 #include <SkRSXform.h>
 #include <SkSurface.h>
+#include <SkTextBlobRunIterator.h>
 
 #include <memory>
 
@@ -140,8 +141,9 @@
 }
 
 void SkiaCanvasProxy::onDrawVertices(VertexMode mode, int vertexCount, const SkPoint vertices[],
-        const SkPoint texs[], const SkColor colors[], SkXfermode*, const uint16_t indices[],
+        const SkPoint texs[], const SkColor colors[], SkBlendMode, const uint16_t indices[],
         int indexCount, const SkPaint& paint) {
+    // TODO: should we pass through blendmode
     if (mFilterHwuiCalls) {
         return;
     }
@@ -370,11 +372,46 @@
 
 void SkiaCanvasProxy::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
         const SkPaint& paint) {
-    SkDEBUGFAIL("SkiaCanvasProxy::onDrawTextBlob is not supported");
+    SkPaint runPaint = paint;
+
+     SkTextBlobRunIterator it(blob);
+     for (;!it.done(); it.next()) {
+         size_t textLen = it.glyphCount() * sizeof(uint16_t);
+         const SkPoint& offset = it.offset();
+         // applyFontToPaint() always overwrites the exact same attributes,
+         // so it is safe to not re-seed the paint for this reason.
+         it.applyFontToPaint(&runPaint);
+
+         switch (it.positioning()) {
+         case SkTextBlob::kDefault_Positioning:
+             this->drawText(it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint);
+             break;
+         case SkTextBlob::kHorizontal_Positioning: {
+             std::unique_ptr<SkPoint[]> pts(new SkPoint[it.glyphCount()]);
+             for (size_t i = 0; i < it.glyphCount(); i++) {
+                 pts[i].set(x + offset.x() + it.pos()[i], y + offset.y());
+             }
+             this->drawPosText(it.glyphs(), textLen, pts.get(), runPaint);
+             break;
+         }
+         case SkTextBlob::kFull_Positioning: {
+             std::unique_ptr<SkPoint[]> pts(new SkPoint[it.glyphCount()]);
+             for (size_t i = 0; i < it.glyphCount(); i++) {
+                 const size_t xIndex = i*2;
+                 const size_t yIndex = xIndex + 1;
+                 pts[i].set(x + offset.x() + it.pos()[xIndex], y + offset.y() + it.pos()[yIndex]);
+             }
+             this->drawPosText(it.glyphs(), textLen, pts.get(), runPaint);
+             break;
+         }
+         default:
+             SkFAIL("unhandled positioning mode");
+         }
+     }
 }
 
 void SkiaCanvasProxy::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
-        const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) {
+        const SkPoint texCoords[4], SkBlendMode bmode, const SkPaint& paint) {
     if (mFilterHwuiCalls) {
         return;
     }
@@ -388,7 +425,7 @@
     // If it fails to generate the vertices, then we do not draw.
     if (SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(), lod.height())) {
         this->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
-                           data.fTexCoords, data.fColors, xmode, data.fIndices, data.fIndexCount,
+                           data.fTexCoords, data.fColors, bmode, data.fIndices, data.fIndexCount,
                            paint);
     }
 }
diff --git a/libs/hwui/SkiaCanvasProxy.h b/libs/hwui/SkiaCanvasProxy.h
index 3ee8c6e..0111815 100644
--- a/libs/hwui/SkiaCanvasProxy.h
+++ b/libs/hwui/SkiaCanvasProxy.h
@@ -67,7 +67,7 @@
     virtual void onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
                                   const SkRect& dst, const SkPaint*) override;
     virtual void onDrawVertices(VertexMode, int vertexCount, const SkPoint vertices[],
-                                const SkPoint texs[], const SkColor colors[], SkXfermode*,
+                                const SkPoint texs[], const SkColor colors[], SkBlendMode,
                                 const uint16_t indices[], int indexCount,
                                 const SkPaint&) override;
 
@@ -87,7 +87,7 @@
                                 const SkPaint& paint) override;
 
     virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
-                             const SkPoint texCoords[4], SkXfermode* xmode,
+                             const SkPoint texCoords[4], SkBlendMode,
                              const SkPaint& paint) override;
 
     virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
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 489a306..971c2a3 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -309,10 +309,7 @@
         storeCompose(caches, *rec.fShaderB, *rec.fShaderA,
                 transform, textureUnit, description, outData);
     }
-    if (!SkXfermode::AsMode(rec.fMode, &description->shadersMode)) {
-        // TODO: Support other modes.
-        description->shadersMode = SkXfermode::kSrcOver_Mode;
-    }
+    description->shadersMode = rec.fBlendMode;
     return true;
 }
 
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index 5854289..d2f37cd 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -22,7 +22,6 @@
 
 #include <GLES2/gl2.h>
 #include <SkShader.h>
-#include <SkXfermode.h>
 #include <cutils/compiler.h>
 
 namespace android {
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
index 908f572..5b5b74e 100644
--- a/libs/hwui/Texture.cpp
+++ b/libs/hwui/Texture.cpp
@@ -48,54 +48,62 @@
     }
 }
 
-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);
     }
 }
 
 void Texture::deleteTexture() {
     mCaches.textureState().deleteTexture(mId);
     mId = 0;
+    mTarget = GL_NONE;
+    if (mEglImageHandle != EGL_NO_IMAGE_KHR) {
+        EGLDisplay eglDisplayHandle = eglGetCurrentDisplay();
+        eglDestroyImageKHR(eglDisplayHandle, mEglImageHandle);
+        mEglImageHandle = EGL_NO_IMAGE_KHR;
+    }
 }
 
-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 +118,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;
@@ -127,6 +135,17 @@
     GL_CHECKPOINT(MODERATE);
 }
 
+void Texture::uploadHardwareBitmapToTexture(GraphicBuffer* buffer) {
+    EGLDisplay eglDisplayHandle = eglGetCurrentDisplay();
+    if (mEglImageHandle != EGL_NO_IMAGE_KHR) {
+        eglDestroyImageKHR(eglDisplayHandle, mEglImageHandle);
+        mEglImageHandle = EGL_NO_IMAGE_KHR;
+    }
+    mEglImageHandle = eglCreateImageKHR(eglDisplayHandle, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
+            buffer->getNativeBuffer(), 0);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, mEglImageHandle);
+}
+
 static void uploadToTexture(bool resize, GLint internalFormat, GLenum format, GLenum type,
         GLsizei stride, GLsizei bpp, GLsizei width, GLsizei height, const GLvoid * data) {
 
@@ -171,13 +190,7 @@
     }
 }
 
-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,
+void Texture::colorTypeToGlFormatAndType(const Caches& caches, SkColorType colorType,
         bool needSRGB, GLint* outInternalFormat, GLint* outFormat, GLint* outType) {
     switch (colorType) {
     case kAlpha_8_SkColorType:
@@ -218,9 +231,25 @@
     }
 }
 
-void Texture::upload(const SkBitmap& bitmap) {
-    SkAutoLockPixels alp(bitmap);
+SkBitmap Texture::uploadToN32(const SkBitmap& bitmap, bool hasSRGB, sk_sp<SkColorSpace> sRGB) {
+    SkBitmap rgbaBitmap;
+    rgbaBitmap.allocPixels(SkImageInfo::MakeN32(bitmap.width(), bitmap.height(),
+            bitmap.info().alphaType(), hasSRGB ? sRGB : nullptr));
+    rgbaBitmap.eraseColor(0);
+    SkCanvas canvas(rgbaBitmap);
+    canvas.drawBitmap(bitmap, 0.0f, 0.0f, nullptr);
+    return rgbaBitmap;
+}
 
+bool Texture::hasUnsupportedColorType(const SkImageInfo& info, bool hasSRGB, SkColorSpace* sRGB) {
+    bool needSRGB = info.colorSpace() == sRGB;
+    return info.colorType() == kARGB_4444_SkColorType
+        || info.colorType() == kIndex_8_SkColorType
+        || (info.colorType() == kRGB_565_SkColorType && hasSRGB && needSRGB);
+}
+
+
+void Texture::upload(Bitmap& bitmap) {
     if (!bitmap.readyToDraw()) {
         ALOGE("Cannot generate texture from bitmap");
         return;
@@ -243,36 +272,32 @@
         setDefaultParams = true;
     }
 
-    sk_sp<SkColorSpace> sRGB = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
-    bool needSRGB = bitmap.colorSpace() == sRGB.get();
+    sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
+    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)) {
-        needsAlloc = true;
-    }
+    GLenum target = bitmap.isHardware() ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D;
+    needsAlloc |= updateSize(bitmap.width(), bitmap.height(), internalFormat, format, target);
 
     blend = !bitmap.isOpaque();
-    mCaches.textureState().bindTexture(mId);
+    mCaches.textureState().bindTexture(mTarget, mId);
 
     // TODO: Handle sRGB gray bitmaps
     bool hasSRGB = mCaches.extensions().hasSRGB();
-    if (CC_UNLIKELY(bitmap.colorType() == kARGB_4444_SkColorType
-            || bitmap.colorType() == kIndex_8_SkColorType
-            || (bitmap.colorType() == kRGB_565_SkColorType && hasSRGB && needSRGB))) {
-
-        SkBitmap rgbaBitmap;
-        rgbaBitmap.allocPixels(SkImageInfo::MakeN32(
-                mWidth, mHeight, bitmap.alphaType(), hasSRGB ? sRGB : nullptr));
-        rgbaBitmap.eraseColor(0);
-
-        SkCanvas canvas(rgbaBitmap);
-        canvas.drawBitmap(bitmap, 0.0f, 0.0f, nullptr);
-
-        uploadSkBitmapToTexture(rgbaBitmap, needsAlloc, internalFormat, format, type);
+    if (CC_UNLIKELY(hasUnsupportedColorType(bitmap.info(), hasSRGB, sRGB.get()))) {
+        SkBitmap skBitmap;
+        bitmap.getSkBitmap(&skBitmap);
+        SkBitmap rgbaBitmap = uploadToN32(skBitmap, hasSRGB, std::move(sRGB));
+        uploadToTexture(needsAlloc, internalFormat, format, type, rgbaBitmap.rowBytesAsPixels(),
+                rgbaBitmap.bytesPerPixel(), rgbaBitmap.width(),
+                rgbaBitmap.height(), rgbaBitmap.getPixels());
+    } else if (bitmap.isHardware()) {
+        uploadHardwareBitmapToTexture(bitmap.graphicBuffer());
     } 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 +313,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..c75e88f 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -18,11 +18,17 @@
 #define ANDROID_HWUI_TEXTURE_H
 
 #include "GpuMemoryTracker.h"
+#include "hwui/Bitmap.h"
 
 #include <GLES2/gl2.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
 #include <SkBitmap.h>
 
 namespace android {
+
+class GraphicBuffer;
+
 namespace uirenderer {
 
 class Caches;
@@ -34,6 +40,11 @@
  */
 class Texture : public GpuMemoryTracker {
 public:
+    static SkBitmap uploadToN32(const SkBitmap& bitmap, bool hasSRGB, sk_sp<SkColorSpace> sRGB);
+    static bool hasUnsupportedColorType(const SkImageInfo& info, bool hasSRGB, SkColorSpace* sRGB);
+    static void colorTypeToGlFormatAndType(const Caches& caches, SkColorType colorType,
+            bool needSRGB, GLint* outInternalFormat, GLint* outFormat, GLint* outType);
+
     explicit Texture(Caches& caches)
         : GpuMemoryTracker(GpuObjectType::Texture)
         , mCaches(caches)
@@ -41,21 +52,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 +83,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 +100,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 +123,10 @@
         return mInternalFormat;
     }
 
+    GLenum target() const {
+        return mTarget;
+    }
+
     /**
      * Generation of the backing bitmap,
      */
@@ -144,7 +158,6 @@
      * the current frame. This is reset at the start of a new frame.
      */
     void* isInUse = nullptr;
-
 private:
     // TODO: Temporarily grant private access to Layer, remove once
     // Layer can be de-tangled from being a dual-purpose render target
@@ -152,7 +165,9 @@
     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 uploadHardwareBitmapToTexture(GraphicBuffer* buffer);
     void resetCachedParams();
 
     GLuint mId = 0;
@@ -160,6 +175,8 @@
     uint32_t mHeight = 0;
     GLint mFormat = 0;
     GLint mInternalFormat = 0;
+    GLenum mTarget = GL_NONE;
+    EGLImageKHR mEglImageHandle = EGL_NO_IMAGE_KHR;
 
     /* 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 08641b7..14ffc85 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -127,9 +127,7 @@
             texture = new Texture(Caches::getInstance());
             texture->bitmapSize = size;
             texture->generation = bitmap->getGenerationID();
-            SkBitmap skBitmap;
-            bitmap->getSkBitmap(&skBitmap);
-            texture->upload(skBitmap);
+            texture->upload(*bitmap);
 
             mSize += size;
             TEXTURE_LOGD("TextureCache::get: create texture(%p): name, size, mSize = %d, %d, %d",
@@ -142,9 +140,7 @@
     } else if (!texture->isInUse && bitmap->getGenerationID() != texture->generation) {
         // Texture was in the cache but is dirty, re-upload
         // TODO: Re-adjust the cache size if the bitmap's dimensions have changed
-        SkBitmap skBitmap;
-        bitmap->getSkBitmap(&skBitmap);
-        texture->upload(skBitmap);
+        texture->upload(*bitmap);
         texture->generation = bitmap->getGenerationID();
     }
 
@@ -174,9 +170,7 @@
         const uint32_t size = bitmap->rowBytes() * bitmap->height();
         texture = new Texture(Caches::getInstance());
         texture->bitmapSize = size;
-        SkBitmap skBitmap;
-        bitmap->getSkBitmap(&skBitmap);
-        texture->upload(skBitmap);
+        texture->upload(*bitmap);
         texture->generation = bitmap->getGenerationID();
         texture->cleanup = true;
     }
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index b50647a..97b7dd7 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -564,7 +564,7 @@
 #ifndef ANDROID_ENABLE_LINEAR_BLENDING
         sk_sp<SkColorSpace> colorSpace = nullptr;
 #else
-        sk_sp<SkColorSpace> colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
+        sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
 #endif
         SkImageInfo info = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType, colorSpace);
         cache.bitmap = Bitmap::allocateHeapBitmap(info);
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 31fbe68..b8f7d9f 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -16,11 +16,27 @@
 #include "Bitmap.h"
 
 #include "Caches.h"
+#include "renderthread/RenderThread.h"
+#include "renderthread/RenderProxy.h"
 
 #include <cutils/log.h>
 #include <sys/mman.h>
 #include <cutils/ashmem.h>
 
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+
+#include <gui/IGraphicBufferAlloc.h>
+#include <gui/ISurfaceComposer.h>
+#include <private/gui/ComposerService.h>
+#include <binder/IServiceManager.h>
+#include <ui/PixelFormat.h>
+
+#include <SkCanvas.h>
+
 namespace android {
 
 static bool computeAllocationSize(size_t rowBytes, int height, size_t* size) {
@@ -76,6 +92,167 @@
     return sk_sp<Bitmap>(new Bitmap(addr, size, info, rowBytes, ctable));
 }
 
+#define FENCE_TIMEOUT 2000000000
+
+// TODO: handle SRGB sanely
+static PixelFormat internalFormatToPixelFormat(GLint internalFormat) {
+    switch (internalFormat) {
+    case GL_ALPHA:
+        return PIXEL_FORMAT_TRANSPARENT;
+    case GL_LUMINANCE:
+        return PIXEL_FORMAT_RGBA_8888;
+    case GL_SRGB8_ALPHA8:
+        return PIXEL_FORMAT_RGBA_8888;
+    case GL_RGBA:
+        return PIXEL_FORMAT_RGBA_8888;
+    default:
+        LOG_ALWAYS_FATAL("Unsupported bitmap colorType: %d", internalFormat);
+        return PIXEL_FORMAT_UNKNOWN;
+    }
+}
+
+class AutoEglFence {
+public:
+    AutoEglFence(EGLDisplay display)
+            : mDisplay(display) {
+        fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
+    }
+
+    ~AutoEglFence() {
+        if (fence != EGL_NO_SYNC_KHR) {
+            eglDestroySyncKHR(mDisplay, fence);
+        }
+    }
+
+    EGLSyncKHR fence = EGL_NO_SYNC_KHR;
+private:
+    EGLDisplay mDisplay = EGL_NO_DISPLAY;
+};
+
+class AutoEglImage {
+public:
+    AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer)
+            : mDisplay(display) {
+        EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+        image = eglCreateImageKHR(display, EGL_NO_CONTEXT,
+                EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
+    }
+
+    ~AutoEglImage() {
+        if (image != EGL_NO_IMAGE_KHR) {
+            eglDestroyImageKHR(mDisplay, image);
+        }
+    }
+
+    EGLImageKHR image = EGL_NO_IMAGE_KHR;
+private:
+    EGLDisplay mDisplay = EGL_NO_DISPLAY;
+};
+
+static bool uploadBitmapToGraphicBuffer(uirenderer::Caches& caches, SkBitmap& bitmap,
+        GraphicBuffer& buffer, GLint format, GLint type) {
+    SkAutoLockPixels alp(bitmap);
+    EGLDisplay display = eglGetCurrentDisplay();
+    LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY,
+                "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
+                uirenderer::renderthread::EglManager::eglErrorString());
+    // These objects are initialized below but the default "null"
+    // values are used to cleanup properly at any point in the
+    // initialization sequenc
+    GLuint texture = 0;
+    // We use an EGLImage to access the content of the GraphicBuffer
+    // The EGL image is later bound to a 2D texture
+    EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer.getNativeBuffer();
+    AutoEglImage autoImage(display, clientBuffer);
+    if (autoImage.image == EGL_NO_IMAGE_KHR) {
+        ALOGW("Could not create EGL image, err =%s",
+                uirenderer::renderthread::EglManager::eglErrorString());
+        return false;
+    }
+    glGenTextures(1, &texture);
+    caches.textureState().bindTexture(texture);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
+
+    GL_CHECKPOINT(MODERATE);
+
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
+            format, type, bitmap.getPixels());
+
+    GL_CHECKPOINT(MODERATE);
+
+    // The fence is used to wait for the texture upload to finish
+    // properly. We cannot rely on glFlush() and glFinish() as
+    // some drivers completely ignore these API calls
+    AutoEglFence autoFence(display);
+    if (autoFence.fence == EGL_NO_SYNC_KHR) {
+        LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError());
+        return false;
+    }
+    // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
+    // pipeline flush (similar to what a glFlush() would do.)
+    EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence,
+            EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
+    if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
+        LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError());
+        return false;
+    }
+    return true;
+}
+
+sk_sp<Bitmap> Bitmap::allocateHardwareBitmap(uirenderer::renderthread::RenderThread& renderThread,
+        SkBitmap& skBitmap) {
+    renderThread.eglManager().initialize();
+    uirenderer::Caches& caches = uirenderer::Caches::getInstance();
+
+    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
+    sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc());
+    if (alloc == NULL) {
+        ALOGW("createGraphicBufferAlloc() failed in GraphicBuffer.create()");
+        return nullptr;
+    }
+
+    const SkImageInfo& info = skBitmap.info();
+    if (info.colorType() == kUnknown_SkColorType) {
+        ALOGW("unable to create hardware bitmap of configuration");
+        return nullptr;
+    }
+
+    sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
+    bool needSRGB = skBitmap.info().colorSpace() == sRGB.get();
+    bool hasSRGB = caches.extensions().hasSRGB();
+    GLint format, type, internalFormat;
+    uirenderer::Texture::colorTypeToGlFormatAndType(caches, skBitmap.colorType(),
+            needSRGB, &internalFormat, &format, &type);
+
+    PixelFormat pixelFormat = internalFormatToPixelFormat(internalFormat);
+    status_t error;
+    sp<GraphicBuffer> buffer = alloc->createGraphicBuffer(info.width(), info.height(), pixelFormat,
+            GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_WRITE_NEVER
+            | GraphicBuffer::USAGE_SW_READ_NEVER , &error);
+
+    if (!buffer.get()) {
+        ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
+        return nullptr;
+    }
+
+    SkBitmap bitmap;
+    if (CC_UNLIKELY(uirenderer::Texture::hasUnsupportedColorType(skBitmap.info(),
+            hasSRGB, sRGB.get()))) {
+        bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasSRGB, std::move(sRGB));
+    } else {
+        bitmap = skBitmap;
+    }
+
+    if (!uploadBitmapToGraphicBuffer(caches, bitmap, *buffer, format, type)) {
+        return nullptr;
+    }
+    return sk_sp<Bitmap>(new Bitmap(std::move(buffer), info));
+}
+
+sk_sp<Bitmap> Bitmap::allocateHardwareBitmap(SkBitmap& bitmap) {
+    return uirenderer::renderthread::RenderProxy::allocateHardwareBitmap(bitmap);
+}
+
 sk_sp<Bitmap> Bitmap::allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable) {
    return allocateBitmap(bitmap, ctable, &android::allocateHeapBitmap);
 }
@@ -130,7 +307,7 @@
     }
     mRowBytes = rowBytes;
     if (mColorTable.get() != ctable) {
-        mColorTable.reset(ctable);
+        mColorTable.reset(SkSafeRef(ctable));
     }
 
     // Need to validate the alpha type to filter against the color type
@@ -183,6 +360,16 @@
     reconfigure(info, rowBytes, ctable);
 }
 
+Bitmap::Bitmap(sp<GraphicBuffer>&& buffer, const SkImageInfo& info)
+        : SkPixelRef(info)
+        , mPixelStorageType(PixelStorageType::Hardware) {
+    auto rawBuffer = buffer.get();
+    mPixelStorage.hardware.buffer = rawBuffer;
+    if (rawBuffer) {
+        rawBuffer->incStrong(rawBuffer);
+    }
+    mRowBytes = bytesPerPixel(buffer->getPixelFormat()) * buffer->getStride();
+}
 Bitmap::~Bitmap() {
     switch (mPixelStorageType) {
     case PixelStorageType::External:
@@ -196,6 +383,12 @@
     case PixelStorageType::Heap:
         free(mPixelStorage.heap.address);
         break;
+    case PixelStorageType::Hardware:
+        auto buffer = mPixelStorage.hardware.buffer;
+        buffer->decStrong(buffer);
+        mPixelStorage.hardware.buffer = nullptr;
+        break;
+
     }
 
     if (android::uirenderer::Caches::hasInstance()) {
@@ -219,6 +412,9 @@
         return mPixelStorage.ashmem.address;
     case PixelStorageType::Heap:
         return mPixelStorage.heap.address;
+    case PixelStorageType::Hardware:
+        LOG_ALWAYS_FATAL_IF("Can't get address for hardware bitmap");
+        return nullptr;
     }
 }
 
@@ -264,6 +460,11 @@
 }
 
 void Bitmap::getSkBitmap(SkBitmap* outBitmap) {
+    if (isHardware()) {
+        //TODO: use readback to get pixels
+        LOG_ALWAYS_FATAL("Not implemented");
+        return;
+    }
     outBitmap->setInfo(info(), rowBytes());
     outBitmap->setPixelRef(this);
     outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
@@ -274,4 +475,11 @@
     bounds->set(0, 0, SkIntToScalar(info().width()), SkIntToScalar(info().height()));
 }
 
-} // namespace android
\ No newline at end of file
+GraphicBuffer* Bitmap::graphicBuffer() {
+    if (isHardware()) {
+        return mPixelStorage.hardware.buffer;
+    }
+    return nullptr;
+}
+
+} // namespace android
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index e86ac11..3940381 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -20,6 +20,7 @@
 #include <SkImageInfo.h>
 #include <SkPixelRef.h>
 #include <cutils/compiler.h>
+#include <ui/GraphicBuffer.h>
 
 namespace android {
 
@@ -27,8 +28,17 @@
     External,
     Heap,
     Ashmem,
+    Hardware,
 };
 
+namespace uirenderer {
+namespace renderthread {
+    class RenderThread;
+}
+}
+
+class PixelStorage;
+
 typedef void (*FreeFunc)(void* addr, void* context);
 
 class ANDROID_API Bitmap : public SkPixelRef {
@@ -36,17 +46,24 @@
     static sk_sp<Bitmap> allocateHeapBitmap(SkBitmap* bitmap, SkColorTable* ctable);
     static sk_sp<Bitmap> allocateHeapBitmap(const SkImageInfo& info);
 
+    static sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& bitmap);
+
     static sk_sp<Bitmap> allocateAshmemBitmap(SkBitmap* bitmap, SkColorTable* ctable);
     static sk_sp<Bitmap> allocateAshmemBitmap(size_t allocSize, const SkImageInfo& info,
         size_t rowBytes, SkColorTable* ctable);
 
     static sk_sp<Bitmap> createFrom(const SkImageInfo&, SkPixelRef&);
+
+    static sk_sp<Bitmap> allocateHardwareBitmap(uirenderer::renderthread::RenderThread&,
+            SkBitmap& bitmap);
+
     Bitmap(void* address, size_t allocSize, const SkImageInfo& info, size_t rowBytes,
             SkColorTable* ctable);
     Bitmap(void* address, void* context, FreeFunc freeFunc,
             const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
     Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info,
             size_t rowBytes, SkColorTable* ctable);
+    Bitmap(sp<GraphicBuffer>&& buffer, const SkImageInfo& info);
 
     int width() const { return info().width(); }
     int height() const { return info().height(); }
@@ -57,6 +74,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);
@@ -73,13 +95,21 @@
     SkColorType colorType() const { return info().colorType(); }
     void getBounds(SkRect* bounds) const;
 
+    bool readyToDraw() const {
+        return this->colorType() != kIndex_8_SkColorType || mColorTable;
+    }
+
+    bool isHardware() const {
+        return mPixelStorageType == PixelStorageType::Hardware;
+    }
+
+    GraphicBuffer* graphicBuffer();
 protected:
     virtual bool onNewLockPixels(LockRec* rec) override;
     virtual void onUnlockPixels() override { };
     virtual size_t getAllocatedSizeInBytes() const override;
 private:
     virtual ~Bitmap();
-    void doFreePixels();
     void* getStorage() const;
 
     PixelStorageType mPixelStorageType;
@@ -103,6 +133,9 @@
             void* address;
             size_t size;
         } heap;
+        struct {
+            GraphicBuffer* buffer;
+        } hardware;
     } mPixelStorage;
 };
 
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index 1ea8bd2..2dc8ce8 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -20,6 +20,8 @@
 #include "RenderNode.h"
 #include "MinikinUtils.h"
 #include "Paint.h"
+#include "Properties.h"
+#include "pipeline/skia/SkiaRecordingCanvas.h"
 #include "Typeface.h"
 
 #include <SkDrawFilter.h>
@@ -27,6 +29,9 @@
 namespace android {
 
 Canvas* Canvas::create_recording_canvas(int width, int height, uirenderer::RenderNode* renderNode) {
+    if (uirenderer::Properties::isSkiaEnabled()) {
+        return new uirenderer::skiapipeline::SkiaRecordingCanvas(renderNode, width, height);
+    }
     return new uirenderer::RecordingCanvas(width, height);
 }
 
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index f275ce1..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>
diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp
index 33ee108..50bc6c3 100644
--- a/libs/hwui/hwui/Typeface.cpp
+++ b/libs/hwui/hwui/Typeface.cpp
@@ -49,62 +49,10 @@
 }
 
 Typeface* gDefaultTypeface = NULL;
-pthread_once_t gDefaultTypefaceOnce = PTHREAD_ONCE_INIT;
-
-// This installs a default typeface (from a hardcoded path) that allows
-// layouts to work (not crash on null pointer) before the default
-// typeface is set.
-// TODO: investigate why layouts are being created before Typeface.java
-// class initialization.
-static minikin::FontCollection *makeFontCollection() {
-    std::vector<minikin::FontFamily *>typefaces;
-    const char *fns[] = {
-        "/system/fonts/Roboto-Regular.ttf",
-    };
-
-    minikin::FontFamily *family = new minikin::FontFamily();
-    for (size_t i = 0; i < sizeof(fns)/sizeof(fns[0]); i++) {
-        const char *fn = fns[i];
-        ALOGD("makeFontCollection adding %s", fn);
-        sk_sp<SkTypeface> skFace = SkTypeface::MakeFromFile(fn);
-        if (skFace != NULL) {
-            // TODO: might be a nice optimization to get access to the underlying font
-            // data, but would require us opening the file ourselves and passing that
-            // to the appropriate Create method of SkTypeface.
-            minikin::MinikinFont *font = new MinikinFontSkia(std::move(skFace), NULL, 0, 0);
-            family->addFont(font);
-            font->Unref();
-        } else {
-            ALOGE("failed to create font %s", fn);
-        }
-    }
-    typefaces.push_back(family);
-
-    minikin::FontCollection *result = new minikin::FontCollection(typefaces);
-    family->Unref();
-    return result;
-}
-
-static void getDefaultTypefaceOnce() {
-  minikin::Layout::init();
-    if (gDefaultTypeface == NULL) {
-        // We expect the client to set a default typeface, but provide a
-        // default so we can make progress before that happens.
-        gDefaultTypeface = new Typeface;
-        gDefaultTypeface->fFontCollection = makeFontCollection();
-        gDefaultTypeface->fSkiaStyle = SkTypeface::kNormal;
-        gDefaultTypeface->fBaseWeight = 400;
-        resolveStyle(gDefaultTypeface);
-    }
-}
 
 Typeface* Typeface::resolveDefault(Typeface* src) {
-    if (src == NULL) {
-        pthread_once(&gDefaultTypefaceOnce, getDefaultTypefaceOnce);
-        return gDefaultTypeface;
-    } else {
-        return src;
-    }
+    LOG_ALWAYS_FATAL_IF(gDefaultTypeface == nullptr);
+    return src == nullptr ? gDefaultTypeface : src;
 }
 
 Typeface* Typeface::createFromTypeface(Typeface* src, SkTypeface::Style style) {
diff --git a/libs/hwui/hwui_static_deps.mk b/libs/hwui/hwui_static_deps.mk
index 2990952..dca78b3 100644
--- a/libs/hwui/hwui_static_deps.mk
+++ b/libs/hwui/hwui_static_deps.mk
@@ -24,7 +24,8 @@
     libprotobuf-cpp-lite \
     libharfbuzz_ng \
     libft2 \
-    libminikin
+    libminikin \
+    libandroidfw
 
 ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT))
     LOCAL_SHARED_LIBRARIES += libRS libRScpp
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..13a0ed8
--- /dev/null
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -0,0 +1,60 @@
+/*
+ * 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 "SkColorFilter.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::MakeFromTexture(context, textureDescription);
+    if (layerImage) {
+        SkPaint paint;
+        paint.setAlpha(mLayer->getAlpha());
+        paint.setBlendMode(mLayer->getMode());
+        paint.setColorFilter(sk_ref_sp(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..accbabd
--- /dev/null
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -0,0 +1,253 @@
+/*
+ * 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 "SkiaPipeline.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 this render node drawable is in
+    //a reordering section
+    if ((!mInReorderingSection) || MathUtils::isZero(mRenderNode->properties().getZ())) {
+        this->forceDraw(canvas);
+    }
+}
+
+void RenderNodeDrawable::forceDraw(SkCanvas* canvas) {
+    RenderNode* renderNode = mRenderNode.get();
+    if (SkiaPipeline::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(sk_ref_sp(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..a2ffc6c
--- /dev/null
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
@@ -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.
+ */
+
+#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,
+            bool inReorderingSection = false)
+            : mRenderNode(node)
+            , mRecordedTransform(canvas->getTotalMatrix())
+            , mComposeLayer(composeLayer)
+            , mInReorderingSection(inReorderingSection) {}
+
+    /**
+     * 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;
+
+    /*
+     * True if the render node is in a reordering section
+     */
+    bool mInReorderingSection;
+
+    /*
+     *  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..a204d5c
--- /dev/null
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -0,0 +1,708 @@
+/*
+ * 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 "SkiaPipeline.h"
+
+#include <SkBlurMask.h>
+#include <SkBlurMaskFilter.h>
+#include <SkGaussianEdgeShader.h>
+#include <SkPathOps.h>
+#include <SkRRectsGaussianEdgeMaskFilter.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 = SkiaPipeline::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 = SkiaPipeline::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 = SkiaPipeline::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 = SkiaPipeline::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 || insetAmount < 0.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.setMaskFilter(SkRRectsGaussianEdgeMaskFilter::Make(devSpaceAmbientRRect,
+            devSpaceAmbientClipRR, devSpaceAmbientRadius));
+        canvas->drawRect(cover, paint);
+    }
+
+    if (spotAlpha > 0.0f) {
+        const Vector3 lightPos = SkiaPipeline::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 = SkiaPipeline::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.setMaskFilter(SkRRectsGaussianEdgeMaskFilter::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 be empty when bounds clipping is disabled
+    bool casterIsClippedByRect = !casterClipRect.isEmpty();
+    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 = SkiaPipeline::getAmbientShadowAlpha()*casterAlpha;
+    float spotAlpha = SkiaPipeline::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::MakeEmpty();
+    if (clippedToBounds) {
+        Rect clipBounds;
+        casterProperties.getClippingRectForFlags(CLIP_TO_CLIP_BOUNDS, &clipBounds);
+        casterClipRect = clipBounds.toSkRect();
+        if (casterClipRect.isEmpty()) {
+            // An empty clip rect means nothing is drawn
+            return;
+        }
+    }
+
+    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/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/libs/hwui/pipeline/skia/SkiaLayer.h
similarity index 60%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to libs/hwui/pipeline/skia/SkiaLayer.h
index 5f66d16..0988d7e 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/libs/hwui/pipeline/skia/SkiaLayer.h
@@ -14,6 +14,25 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+#pragma once
 
-parcelable PublishConfig;
+#include <SkSurface.h>
+#include "Matrix.h"
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+/**
+ * An offscreen rendering target used to contain the contents a RenderNode.
+ */
+struct SkiaLayer
+{
+    sk_sp<SkSurface> layerSurface;
+    Matrix4 inverseTransformInWindow;
+};
+
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
new file mode 100644
index 0000000..494f14d
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -0,0 +1,182 @@
+/*
+ * 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 "SkiaOpenGLPipeline.h"
+
+#include "DeferredLayerUpdater.h"
+#include "renderthread/EglManager.h"
+#include "renderstate/RenderState.h"
+#include "Readback.h"
+#include "SkiaPipeline.h"
+#include "SkiaProfileRenderer.h"
+#include "utils/TraceUtils.h"
+
+#include <android/native_window.h>
+#include <cutils/properties.h>
+#include <strings.h>
+
+using namespace android::uirenderer::renderthread;
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+SkiaOpenGLPipeline::SkiaOpenGLPipeline(RenderThread& thread)
+        : SkiaPipeline(thread)
+        , mEglManager(thread.eglManager()) {
+}
+
+MakeCurrentResult SkiaOpenGLPipeline::makeCurrent() {
+    // TODO: Figure out why this workaround is needed, see b/13913604
+    // In the meantime this matches the behavior of GLRenderer, so it is not a regression
+    EGLint error = 0;
+    if (!mEglManager.makeCurrent(mEglSurface, &error)) {
+        return MakeCurrentResult::AlreadyCurrent;
+    }
+    return error ? MakeCurrentResult::Failed : MakeCurrentResult::Succeeded;
+}
+
+Frame SkiaOpenGLPipeline::getFrame() {
+    LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE,
+                "drawRenderNode called on a context with no surface!");
+    return mEglManager.beginFrame(mEglSurface);
+}
+
+bool SkiaOpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty,
+        const SkRect& dirty,
+        const FrameBuilder::LightGeometry& lightGeometry,
+        LayerUpdateQueue* layerUpdateQueue,
+        const Rect& contentDrawBounds, bool opaque,
+        const BakedOpRenderer::LightInfo& lightInfo,
+        const std::vector<sp<RenderNode>>& renderNodes,
+        FrameInfoVisualizer* profiler) {
+
+    mEglManager.damageFrame(frame, dirty);
+
+    // setup surface for fbo0
+    GrBackendRenderTargetDesc renderTargetDesc;
+    renderTargetDesc.fWidth = frame.width();
+    renderTargetDesc.fHeight = frame.height();
+    renderTargetDesc.fConfig = kRGBA_8888_GrPixelConfig;
+    renderTargetDesc.fOrigin = kBottomLeft_GrSurfaceOrigin;
+    renderTargetDesc.fSampleCnt = 0;
+    renderTargetDesc.fStencilBits = STENCIL_BUFFER_SIZE;
+    renderTargetDesc.fRenderTargetHandle = 0;
+
+    SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
+
+    SkASSERT(mRenderThread.getGrContext() != nullptr);
+    sk_sp<SkSurface> surface(SkSurface::MakeFromBackendRenderTarget(
+            mRenderThread.getGrContext(), renderTargetDesc, &props));
+
+    SkiaPipeline::updateLighting(lightGeometry, lightInfo);
+    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    layerUpdateQueue->clear();
+
+    // Draw visual debugging features
+    if (CC_UNLIKELY(Properties::showDirtyRegions
+            || ProfileType::None == Properties::getProfileType())) {
+        SkCanvas* profileCanvas = surface->getCanvas();
+        SkiaProfileRenderer profileRenderer(profileCanvas);
+        profiler->draw(profileRenderer);
+        profileCanvas->flush();
+    }
+
+    return true;
+}
+
+bool SkiaOpenGLPipeline::swapBuffers(const Frame& frame, bool drew,
+        const SkRect& screenDirty, FrameInfo* currentFrameInfo, bool* requireSwap) {
+
+    GL_CHECKPOINT(LOW);
+
+    // Even if we decided to cancel the frame, from the perspective of jank
+    // metrics the frame was swapped at this point
+    currentFrameInfo->markSwapBuffers();
+
+    *requireSwap = drew || mEglManager.damageRequiresSwap();
+
+    if (*requireSwap && (CC_UNLIKELY(!mEglManager.swapBuffers(frame, screenDirty)))) {
+        return false;
+    }
+
+    return *requireSwap;
+}
+
+bool SkiaOpenGLPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
+    layer->apply();
+    return Readback::copyTextureLayerInto(mRenderThread, *(layer->backingLayer()), bitmap)
+            == CopyResult::Success;
+}
+
+DeferredLayerUpdater* SkiaOpenGLPipeline::createTextureLayer() {
+    mEglManager.initialize();
+    Layer* layer = new Layer(mRenderThread.renderState(), 0, 0);
+    layer->generateTexture();
+    return new DeferredLayerUpdater(layer);
+}
+
+void SkiaOpenGLPipeline::onStop() {
+    if (mEglManager.isCurrent(mEglSurface)) {
+        mEglManager.makeCurrent(EGL_NO_SURFACE);
+    }
+}
+
+bool SkiaOpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) {
+
+    if (mEglSurface != EGL_NO_SURFACE) {
+        mEglManager.destroySurface(mEglSurface);
+        mEglSurface = EGL_NO_SURFACE;
+    }
+
+    if (surface) {
+        mEglSurface = mEglManager.createSurface(surface);
+    }
+
+    if (mEglSurface != EGL_NO_SURFACE) {
+        const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer);
+        mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer);
+        return true;
+    }
+
+    return false;
+}
+
+bool SkiaOpenGLPipeline::isSurfaceReady() {
+    return CC_UNLIKELY(mEglSurface != EGL_NO_SURFACE);
+}
+
+bool SkiaOpenGLPipeline::isContextReady() {
+    return CC_LIKELY(mEglManager.hasEglContext());
+}
+
+void SkiaOpenGLPipeline::invokeFunctor(const RenderThread& thread, Functor* functor) {
+    DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
+    if (thread.eglManager().hasEglContext()) {
+        mode = DrawGlInfo::kModeProcess;
+    }
+
+    (*functor)(mode, nullptr);
+
+    // If there's no context we don't need to reset as there's no gl state to save/restore
+    if (mode != DrawGlInfo::kModeProcessNoContext) {
+        thread.getGrContext()->resetContext();
+    }
+}
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
new file mode 100644
index 0000000..36685dd
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
@@ -0,0 +1,58 @@
+/*
+ * 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 "SkiaPipeline.h"
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+class SkiaOpenGLPipeline : public SkiaPipeline {
+public:
+    SkiaOpenGLPipeline(renderthread::RenderThread& thread);
+    virtual ~SkiaOpenGLPipeline() {}
+
+    renderthread::MakeCurrentResult makeCurrent() override;
+    renderthread::Frame getFrame() override;
+    bool draw(const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
+            const FrameBuilder::LightGeometry& lightGeometry,
+            LayerUpdateQueue* layerUpdateQueue,
+            const Rect& contentDrawBounds, bool opaque,
+            const BakedOpRenderer::LightInfo& lightInfo,
+            const std::vector< sp<RenderNode> >& renderNodes,
+            FrameInfoVisualizer* profiler) override;
+    bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty,
+            FrameInfo* currentFrameInfo, bool* requireSwap) override;
+    bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) override;
+    DeferredLayerUpdater* createTextureLayer() override;
+    bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior) override;
+    void onStop() override;
+    bool isSurfaceReady() override;
+    bool isContextReady() override;
+
+    static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor);
+
+private:
+    renderthread::EglManager& mEglManager;
+    EGLSurface mEglSurface = EGL_NO_SURFACE;
+    bool mBufferPreserved = false;
+};
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
new file mode 100644
index 0000000..03fa266
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -0,0 +1,258 @@
+/*
+ * 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 "SkiaPipeline.h"
+
+#include "utils/TraceUtils.h"
+#include <SkOSFile.h>
+#include <SkPicture.h>
+#include <SkPictureRecorder.h>
+#include <SkPixelSerializer.h>
+#include <SkStream.h>
+
+using namespace android::uirenderer::renderthread;
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+float   SkiaPipeline::mLightRadius = 0;
+uint8_t SkiaPipeline::mAmbientShadowAlpha = 0;
+uint8_t SkiaPipeline::mSpotShadowAlpha = 0;
+
+Vector3 SkiaPipeline::mLightCenter = {FLT_MIN, FLT_MIN, FLT_MIN};
+
+SkiaPipeline::SkiaPipeline(RenderThread& thread) :  mRenderThread(thread) { }
+
+TaskManager* SkiaPipeline::getTaskManager() {
+    return &mTaskManager;
+}
+
+void SkiaPipeline::onDestroyHardwareResources() {
+    // No need to flush the caches here. There is a timer
+    // which will flush temporary resources over time.
+}
+
+void SkiaPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
+        LayerUpdateQueue* layerUpdateQueue, bool opaque,
+        const BakedOpRenderer::LightInfo& lightInfo) {
+    updateLighting(lightGeometry, lightInfo);
+    ATRACE_NAME("draw layers");
+    renderLayersImpl(*layerUpdateQueue, opaque);
+    layerUpdateQueue->clear();
+}
+
+void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers, bool opaque) {
+    // Render all layers that need to be updated, in order.
+    for (size_t i = 0; i < layers.entries().size(); i++) {
+        RenderNode* layerNode = layers.entries()[i].renderNode;
+        // only schedule repaint if node still on layer - possible it may have been
+        // removed during a dropped frame, but layers may still remain scheduled so
+        // as not to lose info on what portion is damaged
+        if (CC_LIKELY(layerNode->getLayerSurface() != nullptr)) {
+            SkASSERT(layerNode->getLayerSurface());
+            SkASSERT(layerNode->getDisplayList()->isSkiaDL());
+            SkiaDisplayList* displayList = (SkiaDisplayList*)layerNode->getDisplayList();
+            if (!displayList || displayList->isEmpty()) {
+                SkDEBUGF(("%p drawLayers(%s) : missing drawable", this, layerNode->getName()));
+                return;
+            }
+
+            const Rect& layerDamage = layers.entries()[i].damage;
+
+            SkCanvas* layerCanvas = layerNode->getLayerSurface()->getCanvas();
+
+            int saveCount = layerCanvas->save();
+            SkASSERT(saveCount == 1);
+
+            layerCanvas->clipRect(layerDamage.toSkRect(), SkRegion::kReplace_Op);
+
+            auto savedLightCenter = mLightCenter;
+            // map current light center into RenderNode's coordinate space
+            layerNode->getSkiaLayer()->inverseTransformInWindow.mapPoint3d(mLightCenter);
+
+            const RenderProperties& properties = layerNode->properties();
+            const SkRect bounds = SkRect::MakeWH(properties.getWidth(), properties.getHeight());
+            if (properties.getClipToBounds() && layerCanvas->quickReject(bounds)) {
+                return;
+            }
+
+            layerCanvas->clear(SK_ColorTRANSPARENT);
+
+            RenderNodeDrawable root(layerNode, layerCanvas, false);
+            root.forceDraw(layerCanvas);
+            layerCanvas->restoreToCount(saveCount);
+            layerCanvas->flush();
+            mLightCenter = savedLightCenter;
+        }
+    }
+}
+
+bool SkiaPipeline::createOrUpdateLayer(RenderNode* node,
+        const DamageAccumulator& damageAccumulator) {
+    SkSurface* layer = node->getLayerSurface();
+    if (!layer || layer->width() != node->getWidth() || layer->height() != node->getHeight()) {
+        SkImageInfo info = SkImageInfo::MakeN32Premul(node->getWidth(), node->getHeight());
+        SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
+        SkASSERT(mRenderThread.getGrContext() != nullptr);
+        node->setLayerSurface(
+                SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes,
+                        info, 0, &props));
+        if (node->getLayerSurface()) {
+            // update the transform in window of the layer to reset its origin wrt light source
+            // position
+            Matrix4 windowTransform;
+            damageAccumulator.computeCurrentTransform(&windowTransform);
+            node->getSkiaLayer()->inverseTransformInWindow = windowTransform;
+        }
+        return true;
+    }
+    return false;
+}
+
+void SkiaPipeline::destroyLayer(RenderNode* node) {
+    node->setLayerSurface(nullptr);
+}
+
+void SkiaPipeline::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
+    GrContext* context = thread.getGrContext();
+    if (context) {
+        ATRACE_FORMAT("Bitmap#prepareToDraw %dx%d", bitmap->width(), bitmap->height());
+        SkBitmap skiaBitmap;
+        bitmap->getSkBitmap(&skiaBitmap);
+        sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skiaBitmap, kNever_SkCopyPixelsMode);
+        SkImage_pinAsTexture(image.get(), context);
+        SkImage_unpinAsTexture(image.get(), context);
+    }
+}
+
+// Encodes to PNG, unless there is already encoded data, in which case that gets
+// used.
+class PngPixelSerializer : public SkPixelSerializer {
+public:
+    bool onUseEncodedData(const void*, size_t) override { return true; }
+    SkData* onEncode(const SkPixmap& pixmap) override {
+        return SkImageEncoder::EncodeData(pixmap.info(), pixmap.addr(), pixmap.rowBytes(),
+                                          SkImageEncoder::kPNG_Type, 100);
+    }
+};
+
+void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
+        const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds,
+        sk_sp<SkSurface> surface) {
+
+    // unpin all mutable images that were attached to nodes deleted while on the UI thread
+    SkiaDisplayList::cleanupImages(surface->getCanvas()->getGrContext());
+
+    // draw all layers up front
+    renderLayersImpl(layers, opaque);
+
+    // initialize the canvas for the current frame
+    SkCanvas* canvas = surface->getCanvas();
+
+    std::unique_ptr<SkPictureRecorder> recorder;
+    bool recordingPicture = false;
+    char prop[PROPERTY_VALUE_MAX];
+    if (skpCaptureEnabled()) {
+        property_get("debug.hwui.capture_frame_as_skp", prop, "0");
+        recordingPicture = prop[0] != '0' && !sk_exists(prop);
+        if (recordingPicture) {
+            recorder.reset(new SkPictureRecorder());
+            canvas = recorder->beginRecording(surface->width(), surface->height(),
+                    nullptr, SkPictureRecorder::kPlaybackDrawPicture_RecordFlag);
+        }
+    }
+
+    canvas->clipRect(clip, SkRegion::kReplace_Op);
+
+    if (!opaque) {
+        canvas->clear(SK_ColorTRANSPARENT);
+    }
+
+    // If there are multiple render nodes, they are laid out as follows:
+    // #0 - backdrop (content + caption)
+    // #1 - content (positioned at (0,0) and clipped to - its bounds mContentDrawBounds)
+    // #2 - additional overlay nodes
+    // Usually the backdrop cannot be seen since it will be entirely covered by the content. While
+    // resizing however it might become partially visible. The following render loop will crop the
+    // backdrop against the content and draw the remaining part of it. It will then draw the content
+    // cropped to the backdrop (since that indicates a shrinking of the window).
+    //
+    // Additional nodes will be drawn on top with no particular clipping semantics.
+
+    // The bounds of the backdrop against which the content should be clipped.
+    Rect backdropBounds = contentDrawBounds;
+    // Usually the contents bounds should be mContentDrawBounds - however - we will
+    // move it towards the fixed edge to give it a more stable appearance (for the moment).
+    // If there is no content bounds we ignore the layering as stated above and start with 2.
+    int layer = (contentDrawBounds.isEmpty() || nodes.size() == 1) ? 2 : 0;
+
+    for (const sp<RenderNode>& node : nodes) {
+        if (node->nothingToDraw()) continue;
+
+        SkASSERT(node->getDisplayList()->isSkiaDL());
+
+        int count = canvas->save();
+
+        if (layer == 0) {
+            const RenderProperties& properties = node->properties();
+            Rect targetBounds(properties.getLeft(), properties.getTop(),
+                              properties.getRight(), properties.getBottom());
+            // Move the content bounds towards the fixed corner of the backdrop.
+            const int x = targetBounds.left;
+            const int y = targetBounds.top;
+            // Remember the intersection of the target bounds and the intersection bounds against
+            // which we have to crop the content.
+            backdropBounds.set(x, y, x + backdropBounds.getWidth(), y + backdropBounds.getHeight());
+            backdropBounds.doIntersect(targetBounds);
+        } else if (layer == 1) {
+            // We shift and clip the content to match its final location in the window.
+            const SkRect clip = SkRect::MakeXYWH(contentDrawBounds.left, contentDrawBounds.top,
+                                                 backdropBounds.getWidth(), backdropBounds.getHeight());
+            const float dx = backdropBounds.left - contentDrawBounds.left;
+            const float dy = backdropBounds.top - contentDrawBounds.top;
+            canvas->translate(dx, dy);
+            // It gets cropped against the bounds of the backdrop to stay inside.
+            canvas->clipRect(clip, SkRegion::kIntersect_Op);
+        }
+
+        RenderNodeDrawable root(node.get(), canvas);
+        root.draw(canvas);
+        canvas->restoreToCount(count);
+        layer++;
+    }
+
+    if (skpCaptureEnabled() && recordingPicture) {
+        sk_sp<SkPicture> picture = recorder->finishRecordingAsPicture();
+        if (picture->approximateOpCount() > 0) {
+            SkFILEWStream stream(prop);
+            if (stream.isValid()) {
+                PngPixelSerializer serializer;
+                picture->serialize(&stream, &serializer);
+                stream.flush();
+                SkDebugf("Captured Drawing Output (%d bytes) for frame. %s", stream.bytesWritten(), prop);
+            }
+        }
+        surface->getCanvas()->drawPicture(picture);
+    }
+
+    ATRACE_NAME("flush commands");
+    canvas->flush();
+}
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
new file mode 100644
index 0000000..160046a
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -0,0 +1,112 @@
+/*
+ * 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 "renderthread/CanvasContext.h"
+#include "FrameBuilder.h"
+#include "renderthread/IRenderPipeline.h"
+#include <SkSurface.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+class SkiaPipeline : public renderthread::IRenderPipeline {
+public:
+    SkiaPipeline(renderthread::RenderThread& thread);
+    virtual ~SkiaPipeline() {}
+
+    TaskManager* getTaskManager() override;
+
+    void onDestroyHardwareResources() override;
+
+    void renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
+            LayerUpdateQueue* layerUpdateQueue, bool opaque,
+            const BakedOpRenderer::LightInfo& lightInfo) override;
+
+    bool createOrUpdateLayer(RenderNode* node,
+            const DamageAccumulator& damageAccumulator) override;
+
+    void renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
+            const std::vector< sp<RenderNode> >& nodes, bool opaque, const Rect &contentDrawBounds,
+            sk_sp<SkSurface> surface);
+
+    static void destroyLayer(RenderNode* node);
+
+    static void prepareToDraw(const renderthread::RenderThread& thread, Bitmap* bitmap);
+
+    static void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque);
+
+    static bool skpCaptureEnabled() { return false; }
+
+    static float getLightRadius() {
+        if (CC_UNLIKELY(Properties::overrideLightRadius > 0)) {
+            return Properties::overrideLightRadius;
+        }
+        return mLightRadius;
+    }
+
+    static uint8_t getAmbientShadowAlpha() {
+        if (CC_UNLIKELY(Properties::overrideAmbientShadowStrength >= 0)) {
+            return Properties::overrideAmbientShadowStrength;
+        }
+        return mAmbientShadowAlpha;
+    }
+
+    static uint8_t getSpotShadowAlpha() {
+        if (CC_UNLIKELY(Properties::overrideSpotShadowStrength >= 0)) {
+            return Properties::overrideSpotShadowStrength;
+        }
+        return mSpotShadowAlpha;
+    }
+
+    static Vector3 getLightCenter() {
+        if (CC_UNLIKELY(Properties::overrideLightPosY > 0 || Properties::overrideLightPosZ > 0)) {
+            Vector3 adjustedLightCenter = mLightCenter;
+            if (CC_UNLIKELY(Properties::overrideLightPosY > 0)) {
+                // negated since this shifts up
+                adjustedLightCenter.y = - Properties::overrideLightPosY;
+            }
+            if (CC_UNLIKELY(Properties::overrideLightPosZ > 0)) {
+                adjustedLightCenter.z = Properties::overrideLightPosZ;
+            }
+            return adjustedLightCenter;
+        }
+        return mLightCenter;
+    }
+
+    static void updateLighting(const FrameBuilder::LightGeometry& lightGeometry,
+            const BakedOpRenderer::LightInfo& lightInfo) {
+        mLightRadius = lightGeometry.radius;
+        mAmbientShadowAlpha = lightInfo.ambientShadowAlpha;
+        mSpotShadowAlpha = lightInfo.spotShadowAlpha;
+        mLightCenter = lightGeometry.center;
+    }
+protected:
+    renderthread::RenderThread& mRenderThread;
+
+private:
+    TaskManager mTaskManager;
+    static float mLightRadius;
+    static uint8_t mAmbientShadowAlpha;
+    static uint8_t mSpotShadowAlpha;
+    static Vector3 mLightCenter;
+};
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaProfileRenderer.cpp b/libs/hwui/pipeline/skia/SkiaProfileRenderer.cpp
new file mode 100644
index 0000000..d97fb37
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaProfileRenderer.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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 "SkiaProfileRenderer.h"
+
+namespace android {
+namespace uirenderer {
+
+void SkiaProfileRenderer::drawRect(float left, float top, float right, float bottom,
+        const SkPaint& paint) {
+    SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
+    mCanvas->drawRect(rect, paint);
+}
+
+void SkiaProfileRenderer::drawRects(const float* rects, int count, const SkPaint& paint) {
+    for (int index = 0; index + 4 <= count; index += 4) {
+        SkRect rect = SkRect::MakeLTRB(rects[index + 0], rects[index + 1], rects[index + 2],
+                rects[index + 3]);
+        mCanvas->drawRect(rect, paint);
+    }
+}
+
+uint32_t SkiaProfileRenderer::getViewportWidth() {
+    return mCanvas->imageInfo().width();
+}
+
+uint32_t SkiaProfileRenderer::getViewportHeight() {
+    return mCanvas->imageInfo().height();
+}
+
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaProfileRenderer.h b/libs/hwui/pipeline/skia/SkiaProfileRenderer.h
new file mode 100644
index 0000000..e6b7f83
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaProfileRenderer.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 SkiaProfileRenderer : public IProfileRenderer {
+public:
+    SkiaProfileRenderer(SkCanvas* canvas)
+            : mCanvas(canvas) {}
+
+    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 ~SkiaProfileRenderer() {}
+
+private:
+    // Does not have ownership.
+    SkCanvas* mCanvas;
+};
+
+} /* 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..ecc6d51
--- /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(), true, mCurrentBarrier);
+    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/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
new file mode 100644
index 0000000..8fffe91
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -0,0 +1,156 @@
+/*
+ * 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 "SkiaVulkanPipeline.h"
+
+#include "DeferredLayerUpdater.h"
+#include "renderthread/EglManager.h" // needed for Frame
+#include "Readback.h"
+#include "renderstate/RenderState.h"
+#include "SkiaPipeline.h"
+#include "SkiaProfileRenderer.h"
+
+#include <SkTypes.h>
+#include <WindowContextFactory_android.h>
+#include <VulkanWindowContext.h>
+
+#include <android/native_window.h>
+#include <cutils/properties.h>
+#include <strings.h>
+
+using namespace android::uirenderer::renderthread;
+using namespace sk_app;
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+MakeCurrentResult SkiaVulkanPipeline::makeCurrent() {
+    return (mWindowContext != nullptr) ?
+        MakeCurrentResult::AlreadyCurrent : MakeCurrentResult::Failed;
+}
+
+Frame SkiaVulkanPipeline::getFrame() {
+    LOG_ALWAYS_FATAL_IF(mWindowContext == nullptr, "Tried to draw into null vulkan context!");
+    mBackbuffer = mWindowContext->getBackbufferSurface();
+    if (mBackbuffer.get() == nullptr) {
+        // try recreating the context?
+        SkDebugf("failed to get backbuffer");
+        return Frame(-1, -1, 0);
+    }
+
+    // TODO: support buffer age if Vulkan API can do it
+    Frame frame(mBackbuffer->width(), mBackbuffer->height(), 0);
+    return frame;
+}
+
+bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty,
+        const SkRect& dirty,
+        const FrameBuilder::LightGeometry& lightGeometry,
+        LayerUpdateQueue* layerUpdateQueue,
+        const Rect& contentDrawBounds, bool opaque,
+        const BakedOpRenderer::LightInfo& lightInfo,
+        const std::vector<sp<RenderNode>>& renderNodes,
+        FrameInfoVisualizer* profiler) {
+
+    if (mBackbuffer.get() == nullptr) {
+        return false;
+    }
+    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, mBackbuffer);
+    layerUpdateQueue->clear();
+
+    // Draw visual debugging features
+    if (CC_UNLIKELY(Properties::showDirtyRegions
+            || ProfileType::None == Properties::getProfileType())) {
+        SkCanvas* profileCanvas = mBackbuffer->getCanvas();
+        SkiaProfileRenderer profileRenderer(profileCanvas);
+        profiler->draw(profileRenderer);
+        profileCanvas->flush();
+    }
+
+    return true;
+}
+
+bool SkiaVulkanPipeline::swapBuffers(const Frame& frame, bool drew,
+        const SkRect& screenDirty, FrameInfo* currentFrameInfo, bool* requireSwap) {
+
+    *requireSwap = drew;
+
+    // Even if we decided to cancel the frame, from the perspective of jank
+    // metrics the frame was swapped at this point
+    currentFrameInfo->markSwapBuffers();
+
+    if (*requireSwap) {
+        mWindowContext->swapBuffers();
+    }
+
+    mBackbuffer.reset();
+
+    return *requireSwap;
+}
+
+bool SkiaVulkanPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
+    // TODO: implement copyLayerInto for vulkan.
+    return false;
+}
+
+DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() {
+    Layer* layer = new Layer(mRenderThread.renderState(), 0, 0);
+    return new DeferredLayerUpdater(layer);
+}
+
+void SkiaVulkanPipeline::onStop() {
+}
+
+bool SkiaVulkanPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) {
+
+    if (mWindowContext) {
+        delete mWindowContext;
+        mWindowContext = nullptr;
+    }
+
+    if (surface) {
+        DisplayParams displayParams;
+        mWindowContext = window_context_factory::NewVulkanForAndroid(surface, displayParams);
+        if (mWindowContext) {
+            DeviceInfo::initialize(mWindowContext->getGrContext()->caps()->maxRenderTargetSize());
+        }
+    }
+
+
+    // this doesn't work for if there is more than one CanvasContext available at one time!
+    mRenderThread.setGrContext(mWindowContext ? mWindowContext->getGrContext() : nullptr);
+
+    return mWindowContext != nullptr;
+}
+
+bool SkiaVulkanPipeline::isSurfaceReady() {
+    return CC_LIKELY(mWindowContext != nullptr) && mWindowContext->isValid();
+}
+
+bool SkiaVulkanPipeline::isContextReady() {
+    return CC_LIKELY(mWindowContext != nullptr);
+}
+
+void SkiaVulkanPipeline::invokeFunctor(const RenderThread& thread, Functor* functor) {
+    // TODO: we currently don't support OpenGL WebView's
+    DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
+    (*functor)(mode, nullptr);
+}
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
new file mode 100644
index 0000000..cdc8692
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -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.
+ */
+
+#pragma once
+
+#include "SkiaPipeline.h"
+#include <SkSurface.h>
+
+namespace sk_app {
+class WindowContext;
+}
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+class SkiaVulkanPipeline : public SkiaPipeline {
+public:
+    SkiaVulkanPipeline(renderthread::RenderThread& thread) : SkiaPipeline(thread) {}
+    virtual ~SkiaVulkanPipeline() {}
+
+    renderthread::MakeCurrentResult makeCurrent() override;
+    renderthread::Frame getFrame() override;
+    bool draw(const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
+            const FrameBuilder::LightGeometry& lightGeometry,
+            LayerUpdateQueue* layerUpdateQueue,
+            const Rect& contentDrawBounds, bool opaque,
+            const BakedOpRenderer::LightInfo& lightInfo,
+            const std::vector< sp<RenderNode> >& renderNodes,
+            FrameInfoVisualizer* profiler) override;
+    bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty,
+            FrameInfo* currentFrameInfo, bool* requireSwap) override;
+    bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) override;
+    DeferredLayerUpdater* createTextureLayer() override;
+    bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior) override;
+    void onStop() override;
+    bool isSurfaceReady() override;
+    bool isContextReady() override;
+
+    static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor);
+
+private:
+    sk_app::WindowContext* mWindowContext = nullptr;
+    sk_sp<SkSurface> mBackbuffer;
+};
+
+} /* 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..c561c86 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -19,17 +19,18 @@
 
 #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"
 #include "renderstate/Stencil.h"
 #include "protos/hwui.pb.h"
 #include "OpenGLPipeline.h"
+#include "pipeline/skia/SkiaOpenGLPipeline.h"
+#include "pipeline/skia/SkiaPipeline.h"
+#include "pipeline/skia/SkiaVulkanPipeline.h"
 #include "utils/GLUtils.h"
 #include "utils/TimeUtils.h"
 
@@ -71,13 +72,11 @@
             return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
                     std::make_unique<OpenGLPipeline>(thread));
         case RenderPipelineType::SkiaGL:
-            //TODO: implement SKIA GL
-            LOG_ALWAYS_FATAL("skiaGL canvas type not implemented.");
-            break;
+            return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
+                    std::make_unique<skiapipeline::SkiaOpenGLPipeline>(thread));
         case RenderPipelineType::SkiaVulkan:
-            //TODO: implement Vulkan
-            LOG_ALWAYS_FATAL("Vulkan canvas type not implemented.");
-            break;
+            return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,
+                                std::make_unique<skiapipeline::SkiaVulkanPipeline>(thread));
         default:
             LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
             break;
@@ -91,6 +90,45 @@
         case RenderPipelineType::OpenGL:
             OpenGLPipeline::destroyLayer(node);
             break;
+        case RenderPipelineType::SkiaGL:
+        case RenderPipelineType::SkiaVulkan:
+            skiapipeline::SkiaPipeline::destroyLayer(node);
+            break;
+        default:
+            LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+            break;
+    }
+}
+
+void CanvasContext::invokeFunctor(const RenderThread& thread, Functor* functor) {
+    ATRACE_CALL();
+    auto renderType = Properties::getRenderPipelineType();
+    switch (renderType) {
+        case RenderPipelineType::OpenGL:
+            OpenGLPipeline::invokeFunctor(thread, functor);
+            break;
+        case RenderPipelineType::SkiaGL:
+            skiapipeline::SkiaOpenGLPipeline::invokeFunctor(thread, functor);
+            break;
+        case RenderPipelineType::SkiaVulkan:
+            skiapipeline::SkiaVulkanPipeline::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;
+        case RenderPipelineType::SkiaGL:
+        case RenderPipelineType::SkiaVulkan:
+            skiapipeline::SkiaPipeline::prepareToDraw(thread, bitmap);
+            break;
         default:
             LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
             break;
@@ -425,8 +463,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 +497,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 +551,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..beaa85e 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -16,6 +16,7 @@
 
 #include "EglManager.h"
 
+#include "Texture.h"
 #include "Caches.h"
 #include "DeviceInfo.h"
 #include "Properties.h"
@@ -25,6 +26,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
@@ -58,7 +61,7 @@
         return "Unknown error";
     }
 }
-static const char* egl_error_str() {
+const char* EglManager::eglErrorString() {
     return egl_error_str(eglGetError());
 }
 
@@ -101,11 +104,11 @@
 
     mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY,
-            "Failed to get EGL_DEFAULT_DISPLAY! err=%s", egl_error_str());
+            "Failed to get EGL_DEFAULT_DISPLAY! err=%s", eglErrorString());
 
     EGLint major, minor;
     LOG_ALWAYS_FATAL_IF(eglInitialize(mEglDisplay, &major, &minor) == EGL_FALSE,
-            "Failed to initialize display %p! err=%s", mEglDisplay, egl_error_str());
+            "Failed to initialize display %p! err=%s", mEglDisplay, eglErrorString());
 
     ALOGI("Initialized EGL, version %d.%d", (int)major, (int)minor);
 
@@ -126,6 +129,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() {
@@ -173,7 +187,7 @@
             loadConfig();
         } else {
             // Failed to get a valid config
-            LOG_ALWAYS_FATAL("Failed to choose config, error = %s", egl_error_str());
+            LOG_ALWAYS_FATAL("Failed to choose config, error = %s", eglErrorString());
         }
     }
 }
@@ -185,7 +199,7 @@
     };
     mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attribs);
     LOG_ALWAYS_FATAL_IF(mEglContext == EGL_NO_CONTEXT,
-        "Failed to create context, error = %s", egl_error_str());
+        "Failed to create context, error = %s", eglErrorString());
 }
 
 void EglManager::createPBufferSurface() {
@@ -212,12 +226,12 @@
     EGLSurface surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, window, attribs);
     LOG_ALWAYS_FATAL_IF(surface == EGL_NO_SURFACE,
             "Failed to create EGLSurface for window %p, eglErr = %s",
-            (void*) window, egl_error_str());
+            (void*) window, eglErrorString());
 
     if (mSwapBehavior != SwapBehavior::Preserved) {
         LOG_ALWAYS_FATAL_IF(eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED) == EGL_FALSE,
                             "Failed to set swap behavior to destroyed for window %p, eglErr = %s",
-                            (void*) window, egl_error_str());
+                            (void*) window, eglErrorString());
     }
 
     return surface;
@@ -228,13 +242,14 @@
         makeCurrent(EGL_NO_SURFACE);
     }
     if (!eglDestroySurface(mEglDisplay, surface)) {
-        ALOGW("Failed to destroy surface %p, error=%s", (void*)surface, egl_error_str());
+        ALOGW("Failed to destroy surface %p, error=%s", (void*)surface, eglErrorString());
     }
 }
 
 void EglManager::destroy() {
     if (mEglDisplay == EGL_NO_DISPLAY) return;
 
+    mRenderThread.setGrContext(nullptr);
     mRenderThread.renderState().onGLContextDestroyed();
     eglDestroyContext(mEglDisplay, mEglContext);
     eglDestroySurface(mEglDisplay, mPBufferSurface);
@@ -262,7 +277,7 @@
                     (void*)surface, egl_error_str(*errOut));
         } else {
             LOG_ALWAYS_FATAL("Failed to make current on surface %p, error=%s",
-                    (void*)surface, egl_error_str());
+                    (void*)surface, eglErrorString());
         }
     }
     mCurrentSurface = surface;
@@ -303,7 +318,7 @@
         frame.map(dirty, rects);
         if (!eglSetDamageRegionKHR(mEglDisplay, frame.mSurface, rects, 1)) {
             LOG_ALWAYS_FATAL("Failed to set damage region on surface %p, error=%s",
-                    (void*)frame.mSurface, egl_error_str());
+                    (void*)frame.mSurface, eglErrorString());
         }
     }
 #endif
@@ -357,14 +372,14 @@
             preserve ? EGL_BUFFER_PRESERVED : EGL_BUFFER_DESTROYED);
     if (!preserved) {
         ALOGW("Failed to set EGL_SWAP_BEHAVIOR on surface %p, error=%s",
-                (void*) surface, egl_error_str());
+                (void*) surface, eglErrorString());
         // Maybe it's already set?
         EGLint swapBehavior;
         if (eglQuerySurface(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, &swapBehavior)) {
             preserved = (swapBehavior == EGL_BUFFER_PRESERVED);
         } else {
             ALOGW("Failed to query EGL_SWAP_BEHAVIOR on surface %p, error=%p",
-                                (void*) surface, egl_error_str());
+                                (void*) surface, eglErrorString());
         }
     }
 
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index ba4a3e1..b12522e 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -31,6 +31,11 @@
 
 class Frame {
 public:
+    Frame(EGLint width, EGLint height, EGLint bufferAge)
+            : mWidth(width)
+            , mHeight(height)
+            , mBufferAge(bufferAge) { }
+
     EGLint width() const { return mWidth; }
     EGLint height() const { return mHeight; }
 
@@ -39,6 +44,7 @@
     EGLint bufferAge() const { return mBufferAge; }
 
 private:
+    Frame() {}
     friend class EglManager;
 
     EGLSurface mSurface;
@@ -55,6 +61,7 @@
 // and EGLConfig, which are re-used by CanvasContext
 class EglManager {
 public:
+    static const char* eglErrorString();
     // Returns true on success, false on failure
     void initialize();
 
@@ -83,7 +90,6 @@
 
 private:
     friend class RenderThread;
-
     explicit EglManager(RenderThread& thread);
     // EglContext is never destroyed, method is purposely not implemented
     ~EglManager();
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 42da293..39e5931 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -618,10 +618,7 @@
 }
 
 CREATE_BRIDGE2(prepareToDraw, RenderThread* thread, Bitmap* bitmap) {
-    if (Caches::hasInstance() && args->thread->eglManager().hasEglContext()) {
-        ATRACE_NAME("Bitmap#prepareToDraw task");
-        Caches::getInstance().textureCache.prefetch(args->bitmap);
-    }
+    CanvasContext::prepareToDraw(*args->thread, args->bitmap);
     args->bitmap->unref();
     args->bitmap = nullptr;
     return nullptr;
@@ -653,6 +650,19 @@
     }
 }
 
+CREATE_BRIDGE2(allocateHardwareBitmap, RenderThread* thread, SkBitmap* bitmap) {
+    sk_sp<Bitmap> hardwareBitmap = Bitmap::allocateHardwareBitmap(*args->thread, *args->bitmap);
+    return hardwareBitmap.release();
+}
+
+sk_sp<Bitmap> RenderProxy::allocateHardwareBitmap(SkBitmap& bitmap) {
+    SETUP_TASK(allocateHardwareBitmap);
+    args->bitmap = &bitmap;
+    args->thread = &RenderThread::getInstance();
+    sk_sp<Bitmap> hardwareBitmap(reinterpret_cast<Bitmap*>(staticPostAndWait(task)));
+    return hardwareBitmap;
+}
+
 void RenderProxy::post(RenderTask* task) {
     mRenderThread.queue(task);
 }
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index ae9330d..e559142 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -130,6 +130,7 @@
             int left, int top, int right, int bottom, SkBitmap* bitmap);
     ANDROID_API static void prepareToDraw(Bitmap& bitmap);
 
+    static sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& bitmap);
 private:
     RenderThread& mRenderThread;
     CanvasContext* mContext;
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/BitmapAllocationTestUtils.h b/libs/hwui/tests/common/BitmapAllocationTestUtils.h
new file mode 100644
index 0000000..6dadd3e3
--- /dev/null
+++ b/libs/hwui/tests/common/BitmapAllocationTestUtils.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "TestScene.h"
+
+#include <SkBitmap.h>
+#include <string>
+
+namespace android {
+namespace uirenderer {
+namespace test {
+
+class BitmapAllocationTestUtils {
+public:
+    static sk_sp<Bitmap> allocateHeapBitmap(int width, int height,
+            SkColorType colorType, std::function<void(SkBitmap& bitmap)> setup) {
+         sk_sp<Bitmap> bitmap = TestUtils::createBitmap(width, height, colorType);
+         SkBitmap skBitmap;
+         bitmap->getSkBitmap(&skBitmap);
+         setup(skBitmap);
+         return bitmap;
+    }
+
+    static sk_sp<Bitmap> allocateHardwareBitmap(int width, int height,
+            SkColorType colorType, std::function<void(SkBitmap& bitmap)> setup) {
+        SkBitmap skBitmap;
+        sk_sp<Bitmap> heapBitmap(TestUtils::createBitmap(width, height, &skBitmap));
+        setup(skBitmap);
+        return Bitmap::allocateHardwareBitmap(skBitmap);
+    }
+
+    typedef sk_sp<Bitmap> (*BitmapAllocator) (int, int, SkColorType,
+            std::function<void(SkBitmap& bitmap)> setup);
+
+    template <class T, BitmapAllocator allocator>
+    static test::TestScene* createBitmapAllocationScene(const TestScene::Options&) {
+        return new T(allocator);
+    }
+
+    template <class BaseScene>
+    static bool registerBitmapAllocationScene(std::string name, std::string  description) {
+        TestScene::registerScene({
+            name + "GlTex",
+            description + " (GlTex version).",
+            createBitmapAllocationScene<BaseScene, &allocateHeapBitmap>
+        });
+
+        TestScene::registerScene({
+            name + "EglImage",
+            description + " (EglImage version).",
+            createBitmapAllocationScene<BaseScene, &allocateHardwareBitmap>
+        });
+        return true;
+    }
+};
+
+} // namespace test
+} // namespace uirenderer
+} // namespace android
\ No newline at end of file
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 cdaa705..0ce598d 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -22,6 +22,7 @@
 #include <Rect.h>
 #include <RenderNode.h>
 #include <hwui/Bitmap.h>
+#include <pipeline/skia/SkiaRecordingCanvas.h>
 #include <renderstate/RenderState.h>
 #include <renderthread/RenderThread.h>
 #include <Snapshot.h>
@@ -196,6 +197,35 @@
        node.setStagingDisplayList(canvas->finishRecording(), nullptr);
     }
 
+    static sp<RenderNode> createSkiaNode(int left, int top, int right, int bottom,
+            std::function<void(RenderProperties& props, skiapipeline::SkiaRecordingCanvas& canvas)> setup,
+            const char* name = nullptr, skiapipeline::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<skiapipeline::SkiaRecordingCanvas> canvas(
+                new skiapipeline::SkiaRecordingCanvas(nullptr,
+                props.getWidth(), props.getHeight()));
+            setup(props, *canvas.get());
+            node->setStagingDisplayList(canvas->finishRecording(), nullptr);
+        }
+        node->setPropertyFieldsDirty(0xFFFFFFFF);
+        TestUtils::syncHierarchyPropertiesAndDisplayList(node);
+        return node;
+    }
+
     /**
      * Forces a sync of a tree of RenderNode, such that every descendant will have its staging
      * properties and DisplayList moved to the render copies.
@@ -249,6 +279,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/BitmapFillrate.cpp b/libs/hwui/tests/common/scenes/BitmapFillrate.cpp
new file mode 100644
index 0000000..be58d09
--- /dev/null
+++ b/libs/hwui/tests/common/scenes/BitmapFillrate.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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 "TestSceneBase.h"
+#include "tests/common/BitmapAllocationTestUtils.h"
+#include "utils/Color.h"
+
+#include <SkBitmap.h>
+
+using namespace android;
+using namespace android::uirenderer;
+
+class BitmapFillrate;
+
+static bool _BitmapFillrate(
+        BitmapAllocationTestUtils::registerBitmapAllocationScene<BitmapFillrate>(
+                "bitmapFillrate", "Draws multiple large half transparent bitmaps."));
+
+class BitmapFillrate : public TestScene {
+public:
+    BitmapFillrate(BitmapAllocationTestUtils::BitmapAllocator allocator)
+        : TestScene()
+        , mAllocator(allocator) { }
+
+    void createContent(int width, int height, Canvas& canvas) override {
+        canvas.drawColor(Color::White, SkBlendMode::kSrcOver);
+        createNode(canvas, 0x909C27B0, 0, 0, width, height);
+        createNode(canvas, 0xA0CDDC39, width / 3, height / 3, width, height);
+        createNode(canvas, 0x90009688, width / 3, 0, width, height);
+        createNode(canvas, 0xA0FF5722, 0, height / 3, width, height);
+        createNode(canvas, 0x9000796B, width / 6, height/6, width, height);
+        createNode(canvas, 0xA0FFC107, width / 6, 0, width, height);
+    }
+
+    void doFrame(int frameNr) override {
+        for (size_t ci = 0; ci < mNodes.size(); ci++) {
+            mNodes[ci]->mutateStagingProperties().setTranslationX(frameNr % 200);
+            mNodes[ci]->mutateStagingProperties().setTranslationY(frameNr % 200);
+            mNodes[ci]->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+        }
+    }
+private:
+    void createNode(Canvas& canvas, SkColor color, int left, int top,
+            int width, int height) {
+        int itemWidth = 2 * width / 3;
+        int itemHeight = 2 * height / 3;
+        auto card = TestUtils::createNode(left, top, left + itemWidth , top + itemHeight,
+                [this, itemWidth, itemHeight, color](RenderProperties& props, Canvas& canvas) {
+            sk_sp<Bitmap> bitmap = mAllocator(itemWidth, itemHeight, kRGBA_8888_SkColorType,
+                    [color](SkBitmap& skBitmap) {
+                 skBitmap.eraseColor(color);
+            });
+            canvas.drawBitmap(*bitmap, 0, 0, nullptr);
+        });
+        canvas.drawRenderNode(card.get());
+        mNodes.push_back(card);
+    }
+
+    BitmapAllocationTestUtils::BitmapAllocator mAllocator;
+    std::vector< sp<RenderNode> > mNodes;
+};
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/libs/hwui/tests/microbench/RenderNodeBench.cpp
similarity index 61%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to libs/hwui/tests/microbench/RenderNodeBench.cpp
index 5f66d16..a5bed00 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/libs/hwui/tests/microbench/RenderNodeBench.cpp
@@ -14,6 +14,20 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+#include <benchmark/benchmark.h>
 
-parcelable PublishConfig;
+#include "RenderNode.h"
+
+using namespace android;
+using namespace android::uirenderer;
+
+void BM_RenderNode_create(benchmark::State& state) {
+    while (state.KeepRunning()) {
+        auto node = new RenderNode();
+        node->incStrong(0);
+        benchmark::DoNotOptimize(node);
+        node->decStrong(0);
+    }
+}
+BENCHMARK(BM_RenderNode_create);
+
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/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 134497c..dda432e 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -776,7 +776,7 @@
                 SkShader::TileMode::kRepeat_TileMode);
 
         sk_sp<SkShader> composeShader = SkShader::MakeComposeShader(std::move(shader1), std::move(shader2),
-                SkXfermode::kMultiply_Mode);
+                SkBlendMode::kMultiply);
         paint.setShader(std::move(composeShader));
         canvas.drawRoundRect(0, 0, 100, 100, 20.0f, 20.0f, paint);
     });
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
new file mode 100644
index 0000000..623d971
--- /dev/null
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -0,0 +1,177 @@
+/*
+ * 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;
+
+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());
+}
+
+static void drawOrderedRect(Canvas* canvas, uint8_t expectedDrawOrder) {
+    SkPaint paint;
+    // order put in blue channel, transparent so overlapped content doesn't get rejected
+    paint.setColor(SkColorSetARGB(1, 0, 0, expectedDrawOrder));
+    canvas->drawRect(0, 0, 100, 100, paint);
+}
+
+static void drawOrderedNode(Canvas* canvas, uint8_t expectedDrawOrder, float z) {
+    auto node = TestUtils::createSkiaNode(0, 0, 100, 100,
+            [expectedDrawOrder, z](RenderProperties& props, SkiaRecordingCanvas& canvas) {
+        drawOrderedRect(&canvas, expectedDrawOrder);
+        props.setTranslationZ(z);
+    });
+    canvas->drawRenderNode(node.get()); // canvas takes reference/sole ownership
+}
+
+TEST(RenderNodeDrawable, zReorder) {
+    class ZReorderCanvas : public SkCanvas {
+    public:
+        ZReorderCanvas(int width, int height) : SkCanvas(width, height) {}
+        void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
+            int expectedOrder = SkColorGetB(paint.getColor()); // extract order from blue channel
+            EXPECT_EQ(expectedOrder, mIndex++) << "An op was drawn out of order";
+        }
+        int getIndex() { return mIndex; }
+    protected:
+        int mIndex = 0;
+    };
+
+    auto parent = TestUtils::createSkiaNode(0, 0, 100, 100,
+            [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
+        drawOrderedNode(&canvas, 0, 10.0f); // in reorder=false at this point, so played inorder
+        drawOrderedRect(&canvas, 1);
+        canvas.insertReorderBarrier(true);
+        drawOrderedNode(&canvas, 6, 2.0f);
+        drawOrderedRect(&canvas, 3);
+        drawOrderedNode(&canvas, 4, 0.0f);
+        drawOrderedRect(&canvas, 5);
+        drawOrderedNode(&canvas, 2, -2.0f);
+        drawOrderedNode(&canvas, 7, 2.0f);
+        canvas.insertReorderBarrier(false);
+        drawOrderedRect(&canvas, 8);
+        drawOrderedNode(&canvas, 9, -10.0f); // in reorder=false at this point, so played inorder
+    });
+
+    //create a canvas not backed by any device/pixels, but with dimensions to avoid quick rejection
+    ZReorderCanvas canvas(100, 100);
+    RenderNodeDrawable drawable(parent.get(), &canvas, false);
+    canvas.drawDrawable(&drawable);
+    EXPECT_EQ(10, canvas.getIndex());
+}
+
+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 = TestUtils::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 = TestUtils::createSkiaNode(0, 0, 1, 1,
+        [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
+            redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
+        }, "redNode");
+
+    auto greenNodeWithRedChild = TestUtils::createSkiaNode(0, 0, 1, 1,
+        [&](RenderProperties& props, SkiaRecordingCanvas& greenCanvasWithRedChild) {
+            greenCanvasWithRedChild.drawRenderNode(redNode.get());
+            greenCanvasWithRedChild.drawColor(SK_ColorGREEN, SkBlendMode::kSrcOver);
+        }, "greenNodeWithRedChild");
+
+    auto rootNode = TestUtils::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/SkiaBehaviorTests.cpp b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
index 49c4da6..f32d97a 100644
--- a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
+++ b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
@@ -69,10 +69,10 @@
                 SkColorMatrixFilter::MakeLightingFilter(0x11223344, 0));
 
         SkColor observedColor;
-        SkXfermode::Mode observedMode;
+        SkBlendMode observedMode;
         ASSERT_TRUE(filter->asColorMode(&observedColor, &observedMode));
         EXPECT_EQ(0xFF223344, observedColor);
-        EXPECT_EQ(SkXfermode::Mode::kModulate_Mode, observedMode);
+        EXPECT_EQ(SkBlendMode::kModulate, observedMode);
     }
 
     {
@@ -93,7 +93,7 @@
 }
 
 TEST(SkiaBehavior, srgbColorSpaceIsSingleton) {
-    sk_sp<SkColorSpace> sRGB1 = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
-    sk_sp<SkColorSpace> sRGB2 = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
+    sk_sp<SkColorSpace> sRGB1 = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
+    sk_sp<SkColorSpace> sRGB2 = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
     ASSERT_EQ(sRGB1.get(), sRGB2.get());
 }
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/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
new file mode 100644
index 0000000..7a2fa57
--- /dev/null
+++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
@@ -0,0 +1,181 @@
+/*
+ * 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 "pipeline/skia/SkiaOpenGLPipeline.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;
+
+RENDERTHREAD_TEST(SkiaPipeline, renderFrame) {
+    auto redNode = TestUtils::createSkiaNode(0, 0, 1, 1,
+        [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
+            redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
+        });
+    LayerUpdateQueue layerUpdateQueue;
+    SkRect dirty = SkRect::MakeLargest();
+    std::vector<sp<RenderNode>> renderNodes;
+    renderNodes.push_back(redNode);
+    bool opaque = true;
+    android::uirenderer::Rect contentDrawBounds(0, 0, 1, 1);
+    auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
+    auto surface = SkSurface::MakeRasterN32Premul(1, 1);
+    surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
+}
+
+RENDERTHREAD_TEST(SkiaPipeline, renderFrameCheckBounds) {
+    auto backdropRedNode = TestUtils::createSkiaNode(1, 1, 4, 4,
+        [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
+            redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
+        });
+    auto contentGreenNode = TestUtils::createSkiaNode(2, 2, 5, 5,
+        [](RenderProperties& props, SkiaRecordingCanvas& blueCanvas) {
+            blueCanvas.drawColor(SK_ColorGREEN, SkBlendMode::kSrcOver);
+        });
+    LayerUpdateQueue layerUpdateQueue;
+    SkRect dirty = SkRect::MakeLargest();
+    std::vector<sp<RenderNode>> renderNodes;
+    renderNodes.push_back(backdropRedNode);  //first node is backdrop
+    renderNodes.push_back(contentGreenNode); //second node is content drawn on top of the backdrop
+    android::uirenderer::Rect contentDrawBounds(1, 1, 3, 3);
+    auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
+    auto surface = SkSurface::MakeRasterN32Premul(5, 5);
+    surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+    //backdropBounds is (1, 1, 3, 3), content clip is (1, 1, 3, 3), content translate is (0, 0)
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+    ASSERT_EQ(TestUtils::getColor(surface, 1, 1), SK_ColorRED);
+    ASSERT_EQ(TestUtils::getColor(surface, 2, 2), SK_ColorGREEN);
+    ASSERT_EQ(TestUtils::getColor(surface, 3, 3), SK_ColorRED);
+    ASSERT_EQ(TestUtils::getColor(surface, 4, 4), SK_ColorBLUE);
+
+    surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
+    contentDrawBounds.set(0, 0, 5, 5);
+    //backdropBounds is (1, 1, 4, 4), content clip is (0, 0, 3, 3), content translate is (1, 1)
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+    ASSERT_EQ(TestUtils::getColor(surface, 1, 1), SK_ColorRED);
+    ASSERT_EQ(TestUtils::getColor(surface, 2, 2), SK_ColorRED);
+    ASSERT_EQ(TestUtils::getColor(surface, 3, 3), SK_ColorGREEN);
+    ASSERT_EQ(TestUtils::getColor(surface, 4, 4), SK_ColorBLUE);
+}
+
+RENDERTHREAD_TEST(SkiaPipeline, renderFrameCheckOpaque) {
+    auto halfGreenNode = TestUtils::createSkiaNode(0, 0, 2, 2,
+        [](RenderProperties& props, SkiaRecordingCanvas& bottomHalfGreenCanvas) {
+            SkPaint greenPaint;
+            greenPaint.setColor(SK_ColorGREEN);
+            greenPaint.setStyle(SkPaint::kFill_Style);
+            bottomHalfGreenCanvas.drawRect(0, 1, 2, 2, greenPaint);
+        });
+    LayerUpdateQueue layerUpdateQueue;
+    SkRect dirty = SkRect::MakeLargest();
+    std::vector<sp<RenderNode>> renderNodes;
+    renderNodes.push_back(halfGreenNode);
+    android::uirenderer::Rect contentDrawBounds(0, 0, 2, 2);
+    auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
+    auto surface = SkSurface::MakeRasterN32Premul(2, 2);
+    surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, false, contentDrawBounds, surface);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), (unsigned int)SK_ColorTRANSPARENT);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN);
+}
+
+RENDERTHREAD_TEST(SkiaPipeline, renderFrameCheckDirtyRect) {
+    auto redNode = TestUtils::createSkiaNode(0, 0, 2, 2,
+        [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
+            redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
+        });
+    LayerUpdateQueue layerUpdateQueue;
+    SkRect dirty = SkRect::MakeXYWH(0, 1, 2, 1);
+    std::vector<sp<RenderNode>> renderNodes;
+    renderNodes.push_back(redNode);
+    android::uirenderer::Rect contentDrawBounds(0, 0, 2, 2);
+    auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
+    auto surface = SkSurface::MakeRasterN32Premul(2, 2);
+    surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+    pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+    ASSERT_EQ(TestUtils::getColor(surface, 1, 0), SK_ColorBLUE);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorRED);
+    ASSERT_EQ(TestUtils::getColor(surface, 1, 1), SK_ColorRED);
+}
+
+RENDERTHREAD_TEST(SkiaPipeline, renderLayer) {
+    auto redNode = TestUtils::createSkiaNode(0, 0, 1, 1,
+        [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
+            redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
+        });
+    auto surfaceLayer1 = SkSurface::MakeRasterN32Premul(1, 1);
+    surfaceLayer1->getCanvas()->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
+    ASSERT_EQ(TestUtils::getColor(surfaceLayer1, 0, 0), SK_ColorWHITE);
+    redNode->setLayerSurface(surfaceLayer1);
+
+    //create a 2nd 2x2 layer and add it to the queue as well.
+    //make the layer's dirty area one half of the layer and verify only the dirty half is updated.
+    auto blueNode = TestUtils::createSkiaNode(0, 0, 2, 2,
+        [](RenderProperties& props, SkiaRecordingCanvas& blueCanvas) {
+            blueCanvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
+        });
+    auto surfaceLayer2 = SkSurface::MakeRasterN32Premul(2, 2);
+    surfaceLayer2->getCanvas()->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
+    ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 0), SK_ColorWHITE);
+    blueNode->setLayerSurface(surfaceLayer2);
+
+    //attach both layers to the update queue
+    LayerUpdateQueue layerUpdateQueue;
+    SkRect dirty = SkRect::MakeLargest();
+    layerUpdateQueue.enqueueLayerWithDamage(redNode.get(), dirty);
+    layerUpdateQueue.enqueueLayerWithDamage(blueNode.get(), SkRect::MakeWH(2, 1));
+    ASSERT_EQ(layerUpdateQueue.entries().size(), 2UL);
+
+    bool opaque = true;
+    FrameBuilder::LightGeometry lightGeometry;
+    lightGeometry.radius = 1.0f;
+    lightGeometry.center = { 0.0f, 0.0f, 0.0f };
+    BakedOpRenderer::LightInfo lightInfo;
+    auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
+    pipeline->renderLayers(lightGeometry, &layerUpdateQueue, opaque, lightInfo);
+    ASSERT_EQ(TestUtils::getColor(surfaceLayer1, 0, 0), SK_ColorRED);
+    ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 0), SK_ColorBLUE);
+    ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 1), SK_ColorWHITE);
+    ASSERT_TRUE(layerUpdateQueue.entries().empty());
+    redNode->setLayerSurface(sk_sp<SkSurface>());
+    blueNode->setLayerSurface(sk_sp<SkSurface>());
+}
diff --git a/libs/hwui/utils/GLUtils.h b/libs/hwui/utils/GLUtils.h
index b49c1eb..94818b2 100644
--- a/libs/hwui/utils/GLUtils.h
+++ b/libs/hwui/utils/GLUtils.h
@@ -27,7 +27,7 @@
 #if DEBUG_OPENGL
 #define GL_CHECKPOINT(LEVEL) \
     do { if (DEBUG_OPENGL >= DEBUG_LEVEL_##LEVEL) {\
-    LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(),\
+    LOG_ALWAYS_FATAL_IF(android::uirenderer::GLUtils::dumpGLErrors(),\
             "GL errors! %s:%d", __FILE__, __LINE__);\
     } } while (0)
 #else
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/libs/hwui/utils/PaintUtils.h b/libs/hwui/utils/PaintUtils.h
index 710e063..845a3ea 100644
--- a/libs/hwui/utils/PaintUtils.h
+++ b/libs/hwui/utils/PaintUtils.h
@@ -21,7 +21,6 @@
 #include <SkColorFilter.h>
 #include <SkDrawLooper.h>
 #include <SkShader.h>
-#include <SkXfermode.h>
 
 namespace android {
 namespace uirenderer {
diff --git a/libs/hwui/utils/TestWindowContext.cpp b/libs/hwui/utils/TestWindowContext.cpp
index 624d207..fa3e13d 100644
--- a/libs/hwui/utils/TestWindowContext.cpp
+++ b/libs/hwui/utils/TestWindowContext.cpp
@@ -110,7 +110,7 @@
     }
 
     bool capturePixels(SkBitmap* bmp) {
-        sk_sp<SkColorSpace> colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
+        sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
         SkImageInfo destinationConfig =
             SkImageInfo::Make(mSize.width(), mSize.height(),
                               kRGBA_8888_SkColorType, kPremul_SkAlphaType, colorSpace);
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index 89b4fb2..0b22ad5 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -31,7 +31,7 @@
 #include <SkCanvas.h>
 #include <SkColor.h>
 #include <SkPaint.h>
-#include <SkXfermode.h>
+#include <SkBlendMode.h>
 #pragma GCC diagnostic pop
 
 namespace android {
diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp
index 6941dba..18ebd47 100644
--- a/libs/input/SpriteController.cpp
+++ b/libs/input/SpriteController.cpp
@@ -30,7 +30,6 @@
 #include <SkCanvas.h>
 #include <SkColor.h>
 #include <SkPaint.h>
-#include <SkXfermode.h>
 #pragma GCC diagnostic pop
 
 #include <android/native_window.h>
diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp
index 74638e7..fe1ee02 100644
--- a/libs/storage/IMountService.cpp
+++ b/libs/storage/IMountService.cpp
@@ -553,7 +553,7 @@
     }
 };
 
-IMPLEMENT_META_INTERFACE(MountService, "IMountService")
+IMPLEMENT_META_INTERFACE(MountService, "android.os.storage.IMountService")
 
 // ----------------------------------------------------------------------
 
diff --git a/libs/storage/IMountServiceListener.cpp b/libs/storage/IMountServiceListener.cpp
index 11b53fd..6a093fd 100644
--- a/libs/storage/IMountServiceListener.cpp
+++ b/libs/storage/IMountServiceListener.cpp
@@ -24,6 +24,20 @@
     TRANSACTION_onStorageStateChanged,
 };
 
+class BpMountServiceListener: public BpInterface<IMountServiceListener> {
+public:
+    explicit BpMountServiceListener(const sp<IBinder>& impl)
+            : BpInterface<IMountServiceListener>(impl) { }
+
+    virtual void onUsbMassStorageConnectionChanged(const bool /* connected */) { }
+    virtual void onStorageStateChanged(const String16& /* path */,
+            const String16& /* oldState */, const String16& /* newState */) { }
+};
+
+IMPLEMENT_META_INTERFACE(MountServiceListener, "android.os.storage.IMountServiceListener")
+
+// ----------------------------------------------------------------------
+
 status_t BnMountServiceListener::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
diff --git a/libs/storage/IMountShutdownObserver.cpp b/libs/storage/IMountShutdownObserver.cpp
index a74a768..6114d4a 100644
--- a/libs/storage/IMountShutdownObserver.cpp
+++ b/libs/storage/IMountShutdownObserver.cpp
@@ -23,6 +23,16 @@
     TRANSACTION_onShutDownComplete = IBinder::FIRST_CALL_TRANSACTION,
 };
 
+class BpMountShutdownObserver: public BpInterface<IMountShutdownObserver> {
+public:
+    explicit BpMountShutdownObserver(const sp<IBinder>& impl)
+            : BpInterface<IMountShutdownObserver>(impl) { }
+
+    virtual void onShutDownComplete(const int32_t /* statusCode */) {}
+};
+
+IMPLEMENT_META_INTERFACE(MountShutdownObserver, "android.os.storage.IMountShutdownObserver")
+
 status_t BnMountShutdownObserver::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
diff --git a/libs/storage/IObbActionListener.cpp b/libs/storage/IObbActionListener.cpp
index a71341b..797393ac 100644
--- a/libs/storage/IObbActionListener.cpp
+++ b/libs/storage/IObbActionListener.cpp
@@ -34,7 +34,7 @@
                              const int32_t /* state */) { }
 };
 
-IMPLEMENT_META_INTERFACE(ObbActionListener, "IObbActionListener")
+IMPLEMENT_META_INTERFACE(ObbActionListener, "android.os.storage.IObbActionListener")
 
 // ----------------------------------------------------------------------
 
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index bd68fec..64576ec 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -236,18 +236,16 @@
          */
         public static final int VOICE_CALL = 4;
 
-        /** Microphone audio source with same orientation as camera if available, the main
-         *  device microphone otherwise */
+        /** Microphone audio source tuned for video recording, with the same orientation
+         *  as the camera if available. */
         public static final int CAMCORDER = 5;
 
-        /** Microphone audio source tuned for voice recognition if available, behaves like
-         *  {@link #DEFAULT} otherwise. */
+        /** Microphone audio source tuned for voice recognition. */
         public static final int VOICE_RECOGNITION = 6;
 
         /** Microphone audio source tuned for voice communications such as VoIP. It
          *  will for instance take advantage of echo cancellation or automatic gain control
-         *  if available. It otherwise behaves like {@link #DEFAULT} if no voice processing
-         *  is applied.
+         *  if available.
          */
         public static final int VOICE_COMMUNICATION = 7;
 
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 44f7e56..9b217fb 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -31,7 +31,6 @@
     libutils \
     libbinder \
     libmedia \
-    libmediadrm \
     libskia \
     libui \
     liblog \
@@ -41,9 +40,9 @@
     libstagefright_foundation \
     libcamera_client \
     libmtp \
-    libusbhost \
     libexif \
-    libpiex
+    libpiex \
+    libandroidfw
 
 LOCAL_STATIC_LIBRARIES := \
 
diff --git a/media/jni/audioeffect/Android.mk b/media/jni/audioeffect/Android.mk
index 91dd8a5..777636b 100644
--- a/media/jni/audioeffect/Android.mk
+++ b/media/jni/audioeffect/Android.mk
@@ -11,7 +11,8 @@
     libutils \
     libandroid_runtime \
     libnativehelper \
-    libmedia
+    libmedia \
+    libaudioclient \
 
 LOCAL_MODULE:= libaudioeffect_jni
 
diff --git a/media/jni/soundpool/Android.mk b/media/jni/soundpool/Android.mk
index 2bc41b5..509a59b 100644
--- a/media/jni/soundpool/Android.mk
+++ b/media/jni/soundpool/Android.mk
@@ -12,7 +12,7 @@
     libutils \
     libandroid_runtime \
     libnativehelper \
-    libmedia \
+    libaudioclient \
     libmediandk \
     libbinder
 
diff --git a/media/tests/audiotests/Android.mk b/media/tests/audiotests/Android.mk
index 57be372..01e42bd 100644
--- a/media/tests/audiotests/Android.mk
+++ b/media/tests/audiotests/Android.mk
@@ -15,7 +15,8 @@
     libutils \
     libbinder \
     libhardware_legacy \
-    libmedia
+    libmedia \
+    libaudioclient \
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/media/tests/players/Android.mk b/media/tests/players/Android.mk
index 7ab6458..35aba4d 100644
--- a/media/tests/players/Android.mk
+++ b/media/tests/players/Android.mk
@@ -20,6 +20,7 @@
 
 LOCAL_SHARED_LIBRARIES:= \
     libbinder \
+    libmedia \
     libutils \
     liblog
 
diff --git a/media/tests/players/invoke_mock_media_player.cpp b/media/tests/players/invoke_mock_media_player.cpp
index 0d0c7ad..aa756ed 100644
--- a/media/tests/players/invoke_mock_media_player.cpp
+++ b/media/tests/players/invoke_mock_media_player.cpp
@@ -82,7 +82,7 @@
     virtual status_t    stop() { return OK; }
     virtual status_t    pause() { return OK; }
     virtual bool        isPlaying() { return true; }
-    virtual status_t    seekTo(int /* msec */) { return OK; }
+    virtual status_t    seekTo(int /* msec */, bool /* precise */) { return OK; }
     virtual status_t    getCurrentPosition(int* /* msec */) { return OK; }
     virtual status_t    getDuration(int* /* msec */) { return OK; }
     virtual status_t    reset() {return OK;}
diff --git a/native/graphics/jni/Android.mk b/native/graphics/jni/Android.mk
index 175f730..4c8a9db 100644
--- a/native/graphics/jni/Android.mk
+++ b/native/graphics/jni/Android.mk
@@ -20,7 +20,8 @@
 
 LOCAL_SHARED_LIBRARIES := \
     libandroid_runtime \
-    libskia
+    libskia \
+    libandroidfw
 
 LOCAL_C_INCLUDES += \
     frameworks/base/native/include \
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/ExtServices/src/android/ext/services/notification/Ranker.java b/packages/ExtServices/src/android/ext/services/notification/Ranker.java
index 63fc157..2feb51f 100644
--- a/packages/ExtServices/src/android/ext/services/notification/Ranker.java
+++ b/packages/ExtServices/src/android/ext/services/notification/Ranker.java
@@ -16,8 +16,6 @@
 
 package android.ext.services.notification;
 
-import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
-
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.service.notification.Adjustment;
@@ -36,6 +34,7 @@
 
 /**
  * Class that provides an updatable ranker module for the notification manager.
+ * TODO: delete
  */
 public final class Ranker extends NotificationRankerService {
     private static final String TAG = "RocketRanker";
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 662a1cd..9af20d0 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 {
@@ -444,7 +445,7 @@
     }
 
     @Override
-    public Path findPath(String childDocId, @Nullable String parentDocId)
+    public Path findDocumentPath(String childDocId, @Nullable String parentDocId)
             throws FileNotFoundException {
         LinkedList<String> path = new LinkedList<>();
 
diff --git a/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java b/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
index 474ffea..327d218 100644
--- a/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
@@ -76,12 +76,6 @@
     void playTrustedSound();
 
     /**
-     * @return true if and only if Keyguard is showing or if Keyguard is disabled by an external app
-     *         (legacy API)
-     */
-    boolean isInputRestricted();
-
-    /**
      * @return true if the screen is on
      */
     boolean isScreenOn();
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index 1823711..3fcc600 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -35,23 +35,21 @@
 import android.os.ParcelFileDescriptor;
 import android.os.storage.StorageManager;
 import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Path;
 import android.provider.DocumentsContract.Root;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsProvider;
 import android.provider.Settings;
 import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.io.File;
-import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeoutException;
@@ -349,6 +347,34 @@
                 throw new UnsupportedOperationException(
                         "Writing operation is not supported by the device.");
             }
+
+            final int parentObjectHandle;
+            final int storageId;
+            switch (parentId.mDocumentType) {
+                case MtpDatabaseConstants.DOCUMENT_TYPE_DEVICE:
+                    final String[] storageDocumentIds =
+                            mDatabase.getStorageDocumentIds(parentId.mDocumentId);
+                    if (storageDocumentIds.length == 1) {
+                        final String newDocumentId =
+                                createDocument(storageDocumentIds[0], mimeType, displayName);
+                        notifyChildDocumentsChange(parentDocumentId);
+                        return newDocumentId;
+                    } else {
+                        throw new UnsupportedOperationException(
+                                "Cannot create a file under the device.");
+                    }
+                case MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE:
+                    storageId = parentId.mStorageId;
+                    parentObjectHandle = -1;
+                    break;
+                case MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT:
+                    storageId = parentId.mStorageId;
+                    parentObjectHandle = parentId.mObjectHandle;
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unexpected document type.");
+            }
+
             pipe = ParcelFileDescriptor.createReliablePipe();
             int objectHandle = -1;
             MtpObjectInfo info = null;
@@ -359,8 +385,8 @@
                         MtpConstants.FORMAT_ASSOCIATION :
                         MediaFile.getFormatCode(displayName, mimeType);
                 info = new MtpObjectInfo.Builder()
-                        .setStorageId(parentId.mStorageId)
-                        .setParent(parentId.mObjectHandle)
+                        .setStorageId(storageId)
+                        .setParent(parentObjectHandle)
                         .setFormat(formatCode)
                         .setName(displayName)
                         .build();
@@ -414,6 +440,51 @@
         }
     }
 
+    @Override
+    public Path findDocumentPath(String childDocumentId, String parentDocumentId)
+            throws FileNotFoundException {
+        final LinkedList<String> ids = new LinkedList<>();
+        final Identifier childIdentifier = mDatabase.createIdentifier(childDocumentId);
+
+        Identifier i = childIdentifier;
+        outer: while (true) {
+            if (i.mDocumentId.equals(parentDocumentId)) {
+                ids.addFirst(i.mDocumentId);
+                break;
+            }
+            switch (i.mDocumentType) {
+                case MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT:
+                    ids.addFirst(i.mDocumentId);
+                    i = mDatabase.getParentIdentifier(i.mDocumentId);
+                    break;
+                case MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE: {
+                    // Check if there is the multiple storage.
+                    final Identifier deviceIdentifier =
+                            mDatabase.getParentIdentifier(i.mDocumentId);
+                    final String[] storageIds =
+                            mDatabase.getStorageDocumentIds(deviceIdentifier.mDocumentId);
+                    // Add storage's document ID to the path only when the device has multiple
+                    // storages.
+                    if (storageIds.length > 1) {
+                        ids.addFirst(i.mDocumentId);
+                        break outer;
+                    }
+                    i = deviceIdentifier;
+                    break;
+                }
+                case MtpDatabaseConstants.DOCUMENT_TYPE_DEVICE:
+                    ids.addFirst(i.mDocumentId);
+                    break outer;
+            }
+        }
+
+        if (parentDocumentId != null) {
+            return new Path(null, ids);
+        } else {
+            return new Path(/* Should be same with root ID */ i.mDocumentId, ids);
+        }
+    }
+
     void openDevice(int deviceId) throws IOException {
         synchronized (mDeviceListLock) {
             if (mDeviceToolkits.containsKey(deviceId)) {
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/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
index 3f7e8b6..194e8c7 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
@@ -21,9 +21,9 @@
 import android.mtp.MtpObjectInfo;
 import android.net.Uri;
 import android.os.ParcelFileDescriptor;
-import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
 import android.os.storage.StorageManager;
 import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Path;
 import android.provider.DocumentsContract.Root;
 import android.system.Os;
 import android.system.OsConstants;
@@ -34,6 +34,9 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.Objects;
+import java.util.Queue;
 import java.util.concurrent.TimeoutException;
 
 import static com.android.mtp.MtpDatabase.strings;
@@ -546,7 +549,7 @@
     public void testOpenDocument_writing() throws Exception {
         setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         setupRoots(0, new MtpRoot[] {
-                new MtpRoot(0, 0, "Storage", 0, 0, "")
+                new MtpRoot(0, 100, "Storage", 0, 0, "")
         });
         final String documentId = mProvider.createDocument("2", "text/plain", "test.txt");
         {
@@ -689,6 +692,29 @@
         }
     }
 
+    public void testCreateDocument() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+        setupRoots(0, new MtpRoot[] {
+                new MtpRoot(0, 100, "Storage A", 100, 100, null)
+        });
+        final String documentId = mProvider.createDocument("1", "text/plain", "note.txt");
+        final Uri deviceUri = DocumentsContract.buildChildDocumentsUri(
+                MtpDocumentsProvider.AUTHORITY, "1");
+        final Uri storageUri = DocumentsContract.buildChildDocumentsUri(
+                MtpDocumentsProvider.AUTHORITY, "2");
+        mResolver.waitForNotification(storageUri, 1);
+        mResolver.waitForNotification(deviceUri, 1);
+        try (final Cursor cursor = mProvider.queryDocument(documentId, null)) {
+            assertTrue(cursor.moveToNext());
+            assertEquals(
+                    "note.txt",
+                    cursor.getString(cursor.getColumnIndex(Document.COLUMN_DISPLAY_NAME)));
+            assertEquals(
+                    "text/plain",
+                    cursor.getString(cursor.getColumnIndex(Document.COLUMN_MIME_TYPE)));
+        }
+    }
+
     public void testCreateDocument_noWritingSupport() throws Exception {
         setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         mMtpManager.addValidDevice(new MtpDeviceRecord(
@@ -770,6 +796,64 @@
         assertEquals(0x400000000L, cursor.getLong(0));
     }
 
+    public void testFindDocumentPath_singleStorage_toRoot() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+        setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Storage", 1000, 1000, "") });
+        setupHierarchyDocuments("1");
+
+        final Path path = mProvider.findDocumentPath("15", null);
+        assertEquals("1", path.getRootId());
+        assertEquals(4, path.getPath().size());
+        assertEquals("1", path.getPath().get(0));
+        assertEquals("3", path.getPath().get(1));
+        assertEquals("6", path.getPath().get(2));
+        assertEquals("15", path.getPath().get(3));
+    }
+
+    public void testFindDocumentPath_singleStorage_toDoc() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+        setupRoots(0, new MtpRoot[] { new MtpRoot(0, 0, "Storage", 1000, 1000, "") });
+        setupHierarchyDocuments("1");
+
+        final Path path = mProvider.findDocumentPath("18", "3");
+        assertNull(path.getRootId());
+        assertEquals(3, path.getPath().size());
+        assertEquals("3", path.getPath().get(0));
+        assertEquals("7", path.getPath().get(1));
+        assertEquals("18", path.getPath().get(2));
+    }
+
+    public void testFindDocumentPath_multiStorage_toRoot() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+        setupRoots(0, new MtpRoot[] {
+                new MtpRoot(0, 0, "Storage A", 1000, 1000, ""),
+                new MtpRoot(0, 1, "Storage B", 1000, 1000, "") });
+        setupHierarchyDocuments("2");
+
+        final Path path = mProvider.findDocumentPath("16", null);
+        assertEquals("2", path.getRootId());
+        assertEquals(4, path.getPath().size());
+        assertEquals("2", path.getPath().get(0));
+        assertEquals("4", path.getPath().get(1));
+        assertEquals("7", path.getPath().get(2));
+        assertEquals("16", path.getPath().get(3));
+    }
+
+    public void testFindDocumentPath_multiStorage_toDoc() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+        setupRoots(0, new MtpRoot[] {
+                new MtpRoot(0, 0, "Storage A", 1000, 1000, ""),
+                new MtpRoot(0, 1, "Storage B", 1000, 1000, "") });
+        setupHierarchyDocuments("2");
+
+        final Path path = mProvider.findDocumentPath("19", "4");
+        assertNull(path.getRootId());
+        assertEquals(3, path.getPath().size());
+        assertEquals("4", path.getPath().get(0));
+        assertEquals("8", path.getPath().get(1));
+        assertEquals("19", path.getPath().get(2));
+    }
+
     private void setupProvider(int flag) {
         mDatabase = new MtpDatabase(getContext(), flag);
         mProvider = new MtpDocumentsProvider();
@@ -816,11 +900,70 @@
         final int[] handles = new int[objects.length];
         int i = 0;
         for (final MtpObjectInfo info : objects) {
-            handles[i] = info.getObjectHandle();
+            handles[i++] = info.getObjectHandle();
             mMtpManager.setObjectInfo(deviceId, info);
         }
         mMtpManager.setObjectHandles(deviceId, storageId, parentHandle, handles);
         return getStrings(mProvider.queryChildDocuments(
                 parentDocumentId, strings(DocumentsContract.Document.COLUMN_DOCUMENT_ID), null));
     }
+
+    static class HierarchyDocument {
+        int depth;
+        String documentId;
+        int objectHandle;
+        int parentHandle;
+
+        HierarchyDocument createChildDocument(int newHandle) {
+            final HierarchyDocument doc = new HierarchyDocument();
+            doc.depth = depth - 1;
+            doc.objectHandle = newHandle;
+            doc.parentHandle = objectHandle;
+            return doc;
+        }
+
+        MtpObjectInfo toObjectInfo() {
+            return new MtpObjectInfo.Builder()
+                    .setName("doc_" + documentId)
+                    .setFormat(depth > 0 ?
+                            MtpConstants.FORMAT_ASSOCIATION : MtpConstants.FORMAT_TEXT)
+                    .setObjectHandle(objectHandle)
+                    .setParent(parentHandle)
+                    .build();
+        }
+    }
+
+    private void setupHierarchyDocuments(String documentId) throws Exception {
+        final Queue<HierarchyDocument> ids = new LinkedList<>();
+        final HierarchyDocument firstDocument = new HierarchyDocument();
+        firstDocument.depth = 3;
+        firstDocument.documentId = documentId;
+        firstDocument.objectHandle = MtpManager.OBJECT_HANDLE_ROOT_CHILDREN;
+        ids.add(firstDocument);
+
+        int objectHandle = 100;
+        while (!ids.isEmpty()) {
+            final HierarchyDocument document = ids.remove();
+            final HierarchyDocument[] children = new HierarchyDocument[] {
+                    document.createChildDocument(objectHandle++),
+                    document.createChildDocument(objectHandle++),
+                    document.createChildDocument(objectHandle++),
+            };
+            final String[] childDocIds = setupDocuments(
+                    0, 0, document.objectHandle, document.documentId, new MtpObjectInfo[] {
+                            children[0].toObjectInfo(),
+                            children[1].toObjectInfo(),
+                            children[2].toObjectInfo(),
+                    });
+            children[0].documentId = childDocIds[0];
+            children[1].documentId = childDocIds[1];
+            children[2].documentId = childDocIds[2];
+
+            if (children[0].depth > 0) {
+                ids.add(children[0]);
+                ids.add(children[1]);
+                ids.add(children[2]);
+            }
+        }
+    }
 }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
index 30d529a..f20bbec 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
@@ -26,6 +26,7 @@
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
+import junit.framework.Assert;
 
 public class TestMtpManager extends MtpManager {
     public static final int CREATED_DOCUMENT_HANDLE = 1000;
@@ -151,6 +152,9 @@
     @Override
     int createDocument(int deviceId, MtpObjectInfo objectInfo, ParcelFileDescriptor source)
             throws IOException {
+        Assert.assertNotSame(0, objectInfo.getStorageId());
+        Assert.assertNotSame(-1, objectInfo.getStorageId());
+        Assert.assertNotSame(0, objectInfo.getParent());
         final String key = pack(deviceId, CREATED_DOCUMENT_HANDLE);
         if (mObjectInfos.containsKey(key)) {
             throw new IOException();
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-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index caad889..58aab1d 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -91,7 +91,7 @@
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Point d\'accès Wi-Fi mobile"</string>
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Via Bluetooth"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Partage de connexion"</string>
-    <string name="tether_settings_title_all" msgid="8356136101061143841">"Partage de connexion et point d\'accès mobile"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"Partage de connexion"</string>
     <string name="managed_user_title" msgid="8109605045406748842">"Toutes les applis profess."</string>
     <string name="user_guest" msgid="8475274842845401871">"Invité"</string>
     <string name="unknown" msgid="1592123443519355854">"Inconnu"</string>
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-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 78e1ee1..5dcad7a 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -132,10 +132,10 @@
     <item msgid="8903157781070679765">"Normaal"</item>
     <item msgid="164347302621392996">"Snel"</item>
     <item msgid="5794028588101562009">"Sneller"</item>
-    <item msgid="7163942783888652942">"Zeer snel"</item>
-    <item msgid="7831712693748700507">"Vlug"</item>
-    <item msgid="5194774745031751806">"Zeer vlug"</item>
-    <item msgid="9085102246155045744">"Snelst"</item>
+    <item msgid="7163942783888652942">"Nog sneller"</item>
+    <item msgid="7831712693748700507">"Heel erg snel"</item>
+    <item msgid="5194774745031751806">"Snelst"</item>
+    <item msgid="9085102246155045744">"Allerallersnelst"</item>
   </string-array>
     <string name="choose_profile" msgid="8229363046053568878">"Profiel kiezen"</string>
     <string name="category_personal" msgid="1299663247844969448">"Persoonlijk"</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/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 7f0e27a..1ea592d 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -22,6 +22,7 @@
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothHeadsetClient;
 import android.bluetooth.BluetoothMap;
+import android.bluetooth.BluetoothMapClient;
 import android.bluetooth.BluetoothInputDevice;
 import android.bluetooth.BluetoothPan;
 import android.bluetooth.BluetoothPbapClient;
@@ -81,12 +82,14 @@
     private HeadsetProfile mHeadsetProfile;
     private HfpClientProfile mHfpClientProfile;
     private MapProfile mMapProfile;
+    private MapClientProfile mMapClientProfile;
     private final HidProfile mHidProfile;
     private OppProfile mOppProfile;
     private final PanProfile mPanProfile;
     private PbapClientProfile mPbapClientProfile;
     private final PbapServerProfile mPbapProfile;
     private final boolean mUsePbapPce;
+    private final boolean mUseMapClient;
 
     /**
      * Mapping from profile name, e.g. "HEADSET" to profile object.
@@ -104,6 +107,8 @@
         mDeviceManager = deviceManager;
         mEventManager = eventManager;
         mUsePbapPce = mContext.getResources().getBoolean(R.bool.enable_pbap_pce_profile);
+        // MAP Client is typically used in the same situations as PBAP Client
+        mUseMapClient = mContext.getResources().getBoolean(R.bool.enable_pbap_pce_profile);
         // pass this reference to adapter and event manager (circular dependency)
         mLocalAdapter.setProfileManager(this);
         mEventManager.setProfileManager(this);
@@ -125,10 +130,15 @@
                 BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
 
         if(DEBUG) Log.d(TAG, "Adding local MAP profile");
-        mMapProfile = new MapProfile(mContext, mLocalAdapter,
-                mDeviceManager, this);
-        addProfile(mMapProfile, MapProfile.NAME,
-                BluetoothMap.ACTION_CONNECTION_STATE_CHANGED);
+        if (mUseMapClient) {
+            mMapClientProfile = new MapClientProfile(mContext, mLocalAdapter, mDeviceManager, this);
+            addProfile(mMapClientProfile, MapClientProfile.NAME,
+                BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED);
+        } else {
+            mMapProfile = new MapProfile(mContext, mLocalAdapter, mDeviceManager, this);
+            addProfile(mMapProfile, MapProfile.NAME,
+                    BluetoothMap.ACTION_CONNECTION_STATE_CHANGED);
+        }
 
        //Create PBAP server profile, but do not add it to list of profiles
        // as we do not need to monitor the profile as part of profile list
@@ -199,6 +209,22 @@
             Log.d(TAG, "Handsfree Uuid not found.");
         }
 
+        // Message Access Profile Client
+        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.MNS)) {
+            if (mMapClientProfile == null) {
+                if(DEBUG) Log.d(TAG, "Adding local Map Client profile");
+                mMapClientProfile =
+                        new MapClientProfile(mContext, mLocalAdapter, mDeviceManager, this);
+                addProfile(mMapClientProfile, MapClientProfile.NAME,
+                        BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED);
+            }
+        } else if (mMapClientProfile != null) {
+            Log.w(TAG,
+                    "Warning: MAP Client profile was previously added but the UUID is now missing.");
+        } else {
+            Log.d(TAG, "MAP Client Uuid not found.");
+        }
+
         // OPP
         if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush)) {
             if (mOppProfile == null) {
@@ -383,6 +409,10 @@
         return mMapProfile;
     }
 
+    public MapClientProfile getMapClientProfile() {
+        return mMapClientProfile;
+    }
+
     /**
      * Fill in a list of LocalBluetoothProfile objects that are supported by
      * the local device and the remote device.
@@ -465,6 +495,11 @@
             mMapProfile.setPreferred(device, true);
         }
 
+        if (mMapClientProfile != null) {
+            profiles.add(mMapClientProfile);
+            removedProfiles.remove(mMapClientProfile);
+        }
+
         if (mUsePbapPce) {
             profiles.add(mPbapClientProfile);
             removedProfiles.remove(mPbapClientProfile);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
new file mode 100644
index 0000000..a7621fc
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.bluetooth;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothMapClient;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothUuid;
+import android.content.Context;
+import android.os.ParcelUuid;
+import android.util.Log;
+
+import com.android.settingslib.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * MapClientProfile handles Bluetooth MAP profile.
+ */
+public final class MapClientProfile implements LocalBluetoothProfile {
+    private static final String TAG = "MapClientProfile";
+    private static boolean V = false;
+
+    private BluetoothMapClient mService;
+    private boolean mIsProfileReady;
+
+    private final LocalBluetoothAdapter mLocalAdapter;
+    private final CachedBluetoothDeviceManager mDeviceManager;
+    private final LocalBluetoothProfileManager mProfileManager;
+
+    static final ParcelUuid[] UUIDS = {
+        BluetoothUuid.MAP,
+        BluetoothUuid.MNS,
+        BluetoothUuid.MAS,
+    };
+
+    static final String NAME = "MAP Client";
+
+    // Order of this profile in device profiles list
+    private static final int ORDINAL = 0;
+
+    // These callbacks run on the main thread.
+    private final class MapClientServiceListener
+            implements BluetoothProfile.ServiceListener {
+
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            if (V) Log.d(TAG,"Bluetooth service connected");
+            mService = (BluetoothMapClient) proxy;
+            // We just bound to the service, so refresh the UI for any connected MAP devices.
+            List<BluetoothDevice> deviceList = mService.getConnectedDevices();
+            while (!deviceList.isEmpty()) {
+                BluetoothDevice nextDevice = deviceList.remove(0);
+                CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice);
+                // we may add a new device here, but generally this should not happen
+                if (device == null) {
+                    Log.w(TAG, "MapProfile found new device: " + nextDevice);
+                    device = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, nextDevice);
+                }
+                device.onProfileStateChanged(MapClientProfile.this,
+                        BluetoothProfile.STATE_CONNECTED);
+                device.refresh();
+            }
+
+            mProfileManager.callServiceConnectedListeners();
+            mIsProfileReady=true;
+        }
+
+        public void onServiceDisconnected(int profile) {
+            if (V) Log.d(TAG,"Bluetooth service disconnected");
+            mProfileManager.callServiceDisconnectedListeners();
+            mIsProfileReady=false;
+        }
+    }
+
+    public boolean isProfileReady() {
+        if(V) Log.d(TAG,"isProfileReady(): "+ mIsProfileReady);
+        return mIsProfileReady;
+    }
+
+    MapClientProfile(Context context, LocalBluetoothAdapter adapter,
+            CachedBluetoothDeviceManager deviceManager,
+            LocalBluetoothProfileManager profileManager) {
+        mLocalAdapter = adapter;
+        mDeviceManager = deviceManager;
+        mProfileManager = profileManager;
+        mLocalAdapter.getProfileProxy(context, new MapClientServiceListener(),
+                BluetoothProfile.MAP_CLIENT);
+    }
+
+    public boolean isConnectable() {
+        return true;
+    }
+
+    public boolean isAutoConnectable() {
+        return true;
+    }
+
+    public boolean connect(BluetoothDevice device) {
+        if (mService == null) return false;
+        List<BluetoothDevice> connectedDevices = getConnectedDevices();
+        if (connectedDevices != null) {
+            for (BluetoothDevice connectedDevice : connectedDevices) {
+                mService.disconnect(connectedDevice);
+            }
+        }
+        return mService.connect(device);
+    }
+
+    public boolean disconnect(BluetoothDevice device) {
+        if (mService == null) return false;
+        // Downgrade priority as user is disconnecting.
+        if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
+            mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+        }
+        return mService.disconnect(device);
+    }
+
+    public int getConnectionStatus(BluetoothDevice device) {
+        if (mService == null) return BluetoothProfile.STATE_DISCONNECTED;
+
+        return mService.getConnectionState(device);
+    }
+
+    public boolean isPreferred(BluetoothDevice device) {
+        if (mService == null) return false;
+        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+    }
+
+    public int getPreferred(BluetoothDevice device) {
+        if (mService == null) return BluetoothProfile.PRIORITY_OFF;
+        return mService.getPriority(device);
+    }
+
+    public void setPreferred(BluetoothDevice device, boolean preferred) {
+        if (mService == null) return;
+        if (preferred) {
+            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
+                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            }
+        } else {
+            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+        }
+    }
+
+    public List<BluetoothDevice> getConnectedDevices() {
+        if (mService == null) return new ArrayList<BluetoothDevice>(0);
+        return mService.getDevicesMatchingConnectionStates(
+              new int[] {BluetoothProfile.STATE_CONNECTED,
+                         BluetoothProfile.STATE_CONNECTING,
+                         BluetoothProfile.STATE_DISCONNECTING});
+    }
+
+    public String toString() {
+        return NAME;
+    }
+
+    public int getOrdinal() {
+        return ORDINAL;
+    }
+
+    public int getNameResource(BluetoothDevice device) {
+        return R.string.bluetooth_profile_map;
+    }
+
+    public int getSummaryResourceForDevice(BluetoothDevice device) {
+        int state = getConnectionStatus(device);
+        switch (state) {
+            case BluetoothProfile.STATE_DISCONNECTED:
+                return R.string.bluetooth_map_profile_summary_use_for;
+
+            case BluetoothProfile.STATE_CONNECTED:
+                return R.string.bluetooth_map_profile_summary_connected;
+
+            default:
+                return Utils.getConnectionStateSummary(state);
+        }
+    }
+
+    public int getDrawableResource(BluetoothClass btClass) {
+        return R.drawable.ic_bt_cellphone;
+    }
+
+    protected void finalize() {
+        if (V) Log.d(TAG, "finalize()");
+        if (mService != null) {
+            try {
+                BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.MAP_CLIENT,
+                                                                       mService);
+                mService = null;
+            }catch (Throwable t) {
+                Log.w(TAG, "Error cleaning up MAP Client proxy", t);
+            }
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
index d7c9eab..72a3b3a 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
@@ -145,7 +145,7 @@
                 }
             }
             for (BluetoothDevice src : srcs) {
-                mService.disconnect(device);
+                mService.disconnect(src);
             }
         }
         Log.d(TAG,"PBAPClientProfile attempting to connect to " + device.getAddress());
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
index c1f5660..b27aad9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
@@ -15,6 +15,9 @@
  */
 package com.android.settingslib.drawer;
 
+import java.util.HashMap;
+import java.util.Map;
+
 public final class CategoryKey {
 
     // Activities in this category shows up in Settings homepage.
@@ -33,4 +36,14 @@
     public static final String CATEGORY_SECURITY = "com.android.settings.category.ia.security";
     public static final String CATEGORY_ACCOUNT = "com.android.settings.category.ia.accounts";
     public static final String CATEGORY_SYSTEM = "com.android.settings.category.ia.system";
+
+    public static final Map<String, String> KEY_COMPAT_MAP;
+
+    static {
+        KEY_COMPAT_MAP = new HashMap<>();
+        KEY_COMPAT_MAP.put("com.android.settings.category.wireless", CATEGORY_NETWORK);
+        KEY_COMPAT_MAP.put("com.android.settings.category.device", CATEGORY_SYSTEM);
+        KEY_COMPAT_MAP.put("com.android.settings.category.personal", CATEGORY_SYSTEM);
+        KEY_COMPAT_MAP.put("com.android.settings.category.system", CATEGORY_SYSTEM);
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
index a51ad76..ed411be 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
@@ -17,14 +17,18 @@
 
 import android.content.ComponentName;
 import android.content.Context;
+import android.support.annotation.VisibleForTesting;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Pair;
 
 import com.android.settingslib.applications.InterestingConfigChanges;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 
 public class CategoryManager {
@@ -106,7 +110,57 @@
             for (DashboardCategory category : mCategories) {
                 mCategoryByKeyMap.put(category.key, category);
             }
+            backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
         }
     }
 
+    @VisibleForTesting
+    synchronized void backwardCompatCleanupForCategory(
+            Map<Pair<String, String>, Tile> tileByComponentCache,
+            Map<String, DashboardCategory> categoryByKeyMap) {
+        // A package can use a) CategoryKey, b) old category keys, c) both.
+        // Check if a package uses old category key only.
+        // If yes, map them to new category key.
+
+        // Build a package name -> tile map first.
+        final Map<String, List<Tile>> packageToTileMap = new HashMap<>();
+        for (Entry<Pair<String, String>, Tile> tileEntry : tileByComponentCache.entrySet()) {
+            final String packageName = tileEntry.getKey().first;
+            List<Tile> tiles = packageToTileMap.get(packageName);
+            if (tiles == null) {
+                tiles = new ArrayList<>();
+                packageToTileMap.put(packageName, tiles);
+            }
+            tiles.add(tileEntry.getValue());
+        }
+
+        for (Entry<String, List<Tile>> entry : packageToTileMap.entrySet()) {
+            final List<Tile> tiles = entry.getValue();
+            // Loop map, find if all tiles from same package uses old key only.
+            boolean useNewKey = false;
+            boolean useOldKey = false;
+            for (Tile tile : tiles) {
+                if (CategoryKey.KEY_COMPAT_MAP.containsKey(tile.category)) {
+                    useOldKey = true;
+                } else {
+                    useNewKey = true;
+                    break;
+                }
+            }
+            // Uses only old key, map them to new keys one by one.
+            if (useOldKey && !useNewKey) {
+                for (Tile tile : tiles) {
+                    final String newCategoryKey = CategoryKey.KEY_COMPAT_MAP.get(tile.category);
+                    tile.category = newCategoryKey;
+                    // move tile to new category.
+                    DashboardCategory newCategory = categoryByKeyMap.get(newCategoryKey);
+                    if (newCategory == null) {
+                        newCategory = new DashboardCategory();
+                        categoryByKeyMap.put(newCategoryKey, newCategory);
+                    }
+                    newCategory.tiles.add(tile);
+                }
+            }
+        }
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java b/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java
index 4e85f2e..512049f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/ProfileSelectDialog.java
@@ -26,10 +26,15 @@
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.util.Log;
+
+import java.util.List;
 
 public class ProfileSelectDialog extends DialogFragment implements OnClickListener {
 
+    private static final String TAG = "ProfileSelectDialog";
     private static final String ARG_SELECTED_TILE = "selectedTile";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private Tile mSelectedTile;
 
@@ -68,4 +73,20 @@
         getActivity().startActivityAsUser(mSelectedTile.intent, user);
         ((SettingsDrawerActivity) getActivity()).onProfileTileOpen();
     }
+
+    public static void updateUserHandlesIfNeeded(Context context, Tile tile) {
+        List<UserHandle> userHandles = tile.userHandle;
+        if (tile.userHandle == null || tile.userHandle.size() <= 1) {
+            return;
+        }
+        final UserManager userManager = UserManager.get(context);
+        for (int i = userHandles.size() - 1; i >= 0; i--) {
+            if (userManager.getUserInfo(userHandles.get(i).getIdentifier()) == null) {
+                if (DEBUG) {
+                    Log.d(TAG, "Delete the user: " + userHandles.get(i).getIdentifier());
+                }
+                userHandles.remove(i);
+            }
+        }
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
index bad7ba4..86514dc 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
@@ -28,10 +28,8 @@
 import android.content.res.TypedArray;
 import android.os.AsyncTask;
 import android.os.Bundle;
-import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
-import android.support.annotation.VisibleForTesting;
 import android.support.v4.widget.DrawerLayout;
 import android.util.ArraySet;
 import android.util.Log;
@@ -312,7 +310,7 @@
             return true;
         }
         try {
-            updateUserHandlesIfNeeded(tile);
+            ProfileSelectDialog.updateUserHandlesIfNeeded(this /* context */, tile);
             int numUserHandles = tile.userHandle.size();
             if (numUserHandles > 1) {
                 ProfileSelectDialog.show(getFragmentManager(), tile);
@@ -334,24 +332,6 @@
         return true;
     }
 
-    private void updateUserHandlesIfNeeded(Tile tile) {
-        List<UserHandle> userHandles = tile.userHandle;
-
-        for (int i = userHandles.size() - 1; i >= 0; i--) {
-            if (mUserManager.getUserInfo(userHandles.get(i).getIdentifier()) == null) {
-                if (DEBUG) {
-                    Log.d(TAG, "Delete the user: " + userHandles.get(i).getIdentifier());
-                }
-                userHandles.remove(i);
-            }
-        }
-    }
-
-    @VisibleForTesting
-    public void setUserManager(UserManager userManager) {
-        mUserManager = userManager;
-    }
-
     protected void onTileClicked(Tile tile) {
         if (openTile(tile)) {
             finish();
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
index ac10ca8..9442458 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
@@ -65,6 +65,13 @@
             "com.android.settings.action.EXTRA_SETTINGS";
 
     /**
+     * @See {@link #EXTRA_SETTINGS_ACTION}.
+     */
+    private static final String IA_SETTINGS_ACTION =
+            "com.android.settings.action.IA_SETTINGS";
+
+
+    /**
      * Same as #EXTRA_SETTINGS_ACTION but used for the platform Settings activities.
      */
     private static final String SETTINGS_ACTION =
@@ -148,6 +155,7 @@
             }
             if (setup) {
                 getTilesForAction(context, user, EXTRA_SETTINGS_ACTION, cache, null, tiles, false);
+                getTilesForAction(context, user, IA_SETTINGS_ACTION, cache, null, tiles, false);
             }
         }
 
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/Android.mk b/packages/SettingsLib/tests/Android.mk
index 4208522..333c41d 100644
--- a/packages/SettingsLib/tests/Android.mk
+++ b/packages/SettingsLib/tests/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2015 The Android Open Source Project
+# 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.
@@ -15,20 +15,5 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_MODULE_TAGS := tests
-LOCAL_CERTIFICATE := platform
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
-
-LOCAL_PACKAGE_NAME := SettingsLibTests
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    android-support-test \
-    espresso-core \
-    mockito-target-minus-junit4
-
-include frameworks/base/packages/SettingsLib/common.mk
-
-include $(BUILD_PACKAGE)
+# Include all makefiles in subdirectories
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/SettingsLib/tests/integ/Android.mk b/packages/SettingsLib/tests/integ/Android.mk
new file mode 100644
index 0000000..4208522
--- /dev/null
+++ b/packages/SettingsLib/tests/integ/Android.mk
@@ -0,0 +1,34 @@
+# 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)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
+
+LOCAL_PACKAGE_NAME := SettingsLibTests
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-test \
+    espresso-core \
+    mockito-target-minus-junit4
+
+include frameworks/base/packages/SettingsLib/common.mk
+
+include $(BUILD_PACKAGE)
diff --git a/packages/SettingsLib/tests/AndroidManifest.xml b/packages/SettingsLib/tests/integ/AndroidManifest.xml
similarity index 94%
rename from packages/SettingsLib/tests/AndroidManifest.xml
rename to packages/SettingsLib/tests/integ/AndroidManifest.xml
index 9fd5a41..00b2164 100644
--- a/packages/SettingsLib/tests/AndroidManifest.xml
+++ b/packages/SettingsLib/tests/integ/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/BaseTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/BaseTest.java
similarity index 100%
rename from packages/SettingsLib/tests/src/com/android/settingslib/BaseTest.java
rename to packages/SettingsLib/tests/integ/src/com/android/settingslib/BaseTest.java
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawer/ProfileSelectDialogTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawer/ProfileSelectDialogTest.java
new file mode 100644
index 0000000..ac2d759
--- /dev/null
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawer/ProfileSelectDialogTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.drawer;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static junit.framework.Assert.assertEquals;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ProfileSelectDialogTest {
+
+    @Mock
+    private Context mContext;
+    @Mock
+    private UserManager mUserManager;
+    private static final UserHandle NORMAL_USER = UserHandle.of(1111);
+    private static final UserHandle REMOVED_USER = UserHandle.of(2222);
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+        final UserInfo userInfo = new UserInfo(
+                NORMAL_USER.getIdentifier(), "test_user", UserInfo.FLAG_RESTRICTED);
+        when(mUserManager.getUserInfo(NORMAL_USER.getIdentifier())).thenReturn(userInfo);
+    }
+
+    @Test
+    public void testUpdateUserHandlesIfNeeded_Normal() {
+        final Tile tile = new Tile();
+        tile.intent = new Intent();
+        tile.userHandle.add(NORMAL_USER);
+
+        ProfileSelectDialog.updateUserHandlesIfNeeded(mContext, tile);
+
+        assertEquals(tile.userHandle.size(), 1);
+        assertEquals(tile.userHandle.get(0).getIdentifier(), NORMAL_USER.getIdentifier());
+        verify(mUserManager, never()).getUserInfo(NORMAL_USER.getIdentifier());
+    }
+
+    @Test
+    public void testUpdateUserHandlesIfNeeded_Remove() {
+        final Tile tile = new Tile();
+        tile.intent = new Intent();
+        tile.userHandle.add(REMOVED_USER);
+        tile.userHandle.add(NORMAL_USER);
+        tile.userHandle.add(REMOVED_USER);
+
+        ProfileSelectDialog.updateUserHandlesIfNeeded(mContext, tile);
+
+        assertEquals(tile.userHandle.size(), 1);
+        assertEquals(tile.userHandle.get(0).getIdentifier(), NORMAL_USER.getIdentifier());
+        verify(mUserManager, times(1)).getUserInfo(NORMAL_USER.getIdentifier());
+        verify(mUserManager, times(2)).getUserInfo(REMOVED_USER.getIdentifier());
+    }
+}
diff --git a/packages/SettingsLib/tests/src/com/android/settingslib/drawer/SettingsDrawerActivityTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawer/SettingsDrawerActivityTest.java
similarity index 61%
rename from packages/SettingsLib/tests/src/com/android/settingslib/drawer/SettingsDrawerActivityTest.java
rename to packages/SettingsLib/tests/integ/src/com/android/settingslib/drawer/SettingsDrawerActivityTest.java
index 4d7d4cf..1e87ea0f 100644
--- a/packages/SettingsLib/tests/src/com/android/settingslib/drawer/SettingsDrawerActivityTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawer/SettingsDrawerActivityTest.java
@@ -19,25 +19,16 @@
 import android.app.Instrumentation;
 import android.content.Intent;
 import android.support.test.InstrumentationRegistry;
-import android.annotation.Nullable;
-import android.content.Intent;
-import android.content.pm.UserInfo;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.os.UserManager;
 import android.support.test.filters.SmallTest;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
 
-import com.android.settingslib.drawer.SettingsDrawerActivity;
-import com.android.settingslib.drawer.Tile;
 import com.android.settingslib.R;
 
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
 import static android.support.test.espresso.Espresso.onView;
@@ -45,66 +36,19 @@
 import static android.support.test.espresso.assertion.ViewAssertions.matches;
 import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
-import static junit.framework.Assert.assertEquals;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.verify;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class SettingsDrawerActivityTest {
-    @Mock
-    private UserManager mUserManager;
+
 
     @Rule
     public ActivityTestRule<TestActivity> mActivityRule =
             new ActivityTestRule<>(TestActivity.class, true, true);
 
-    private static final UserHandle NORMAL_USER = UserHandle.of(1111);
-    private static final UserHandle REMOVED_USER = UserHandle.of(2222);
-
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-
-        final UserInfo userInfo = new UserInfo(
-                NORMAL_USER.getIdentifier(), "test_user", UserInfo.FLAG_RESTRICTED);
-        when(mUserManager.getUserInfo(NORMAL_USER.getIdentifier())).thenReturn(userInfo);
-    }
-
-    @Test
-    public void testUpdateUserHandlesIfNeeded_Normal() {
-        TestActivity activity = mActivityRule.getActivity();
-        activity.setUserManager(mUserManager);
-
-        Tile tile = new Tile();
-        tile.intent = new Intent();
-        tile.userHandle.add(NORMAL_USER);
-
-        activity.openTile(tile);
-
-        assertEquals(tile.userHandle.size(), 1);
-        assertEquals(tile.userHandle.get(0).getIdentifier(), NORMAL_USER.getIdentifier());
-        verify(mUserManager, times(1)).getUserInfo(NORMAL_USER.getIdentifier());
-    }
-
-    @Test
-    public void testUpdateUserHandlesIfNeeded_Remove() {
-        TestActivity activity = mActivityRule.getActivity();
-        activity.setUserManager(mUserManager);
-
-        Tile tile = new Tile();
-        tile.intent = new Intent();
-        tile.userHandle.add(REMOVED_USER);
-        tile.userHandle.add(NORMAL_USER);
-        tile.userHandle.add(REMOVED_USER);
-
-        activity.openTile(tile);
-
-        assertEquals(tile.userHandle.size(), 1);
-        assertEquals(tile.userHandle.get(0).getIdentifier(), NORMAL_USER.getIdentifier());
-        verify(mUserManager, times(1)).getUserInfo(NORMAL_USER.getIdentifier());
-        verify(mUserManager, times(2)).getUserInfo(REMOVED_USER.getIdentifier());
     }
 
     @Test
diff --git a/packages/SettingsLib/tests/src/com/android/settingslib/users/AppRestrictionsHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
similarity index 100%
rename from packages/SettingsLib/tests/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
rename to packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
diff --git a/packages/SettingsLib/tests/src/com/android/settingslib/utils/NetworkPolicyEditorTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/NetworkPolicyEditorTest.java
similarity index 100%
rename from packages/SettingsLib/tests/src/com/android/settingslib/utils/NetworkPolicyEditorTest.java
rename to packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/NetworkPolicyEditorTest.java
diff --git a/packages/SettingsLib/tests/src/com/android/settingslib/utils/ZoneGetterTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java
similarity index 100%
rename from packages/SettingsLib/tests/src/com/android/settingslib/utils/ZoneGetterTest.java
rename to packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java
diff --git a/packages/SettingsLib/tests/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
similarity index 100%
rename from packages/SettingsLib/tests/src/com/android/settingslib/wifi/AccessPointTest.java
rename to packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
new file mode 100644
index 0000000..c650190
--- /dev/null
+++ b/packages/SettingsLib/tests/integ/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/SettingsLib/tests/robotests/Android.mk b/packages/SettingsLib/tests/robotests/Android.mk
new file mode 100644
index 0000000..c1108f6
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/Android.mk
@@ -0,0 +1,82 @@
+# 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.
+
+
+############################################################
+# SettingsLib Shell app just for Robolectric test target.  #
+############################################################
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := SettingsLibShell
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_PRIVILEGED_MODULE := true
+
+LOCAL_JAVA_LIBRARIES := \
+    junit4-target \
+    platform-robolectric-prebuilt
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    platform-system-robolectric \
+    truth-prebuilt
+
+LOCAL_AAPT_FLAGS := --auto-add-overlay \
+
+LOCAL_SRC_FILES := \
+    $(call all-java-files-under, src)
+
+include frameworks/base/packages/SettingsLib/common.mk
+
+include $(BUILD_PACKAGE)
+
+#############################################
+# SettingsLib Robolectric test target. #
+#############################################
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Include the testing libraries (JUnit4 + Robolectric libs).
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    platform-system-robolectric \
+    truth-prebuilt
+
+LOCAL_JAVA_LIBRARIES := \
+    junit4-target \
+    platform-robolectric-prebuilt
+
+LOCAL_INSTRUMENTATION_FOR := SettingsLibShell
+LOCAL_MODULE := SettingsLibRoboTests
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+#############################################################
+# SettingsLib runner target to run the previous target. #
+#############################################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := RunSettingsLibRoboTests
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    SettingsLibRoboTests
+
+LOCAL_TEST_PACKAGE := SettingsLibShell
+
+include prebuilts/misc/common/robolectric/run_robotests.mk
diff --git a/packages/SettingsLib/tests/robotests/AndroidManifest.xml b/packages/SettingsLib/tests/robotests/AndroidManifest.xml
new file mode 100644
index 0000000..9e92fa9
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/AndroidManifest.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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          coreApp="true"
+          package="com.android.settingslib.robotests">
+
+    <application/>
+
+</manifest>
diff --git a/packages/SettingsLib/tests/robotests/readme.md b/packages/SettingsLib/tests/robotests/readme.md
new file mode 100644
index 0000000..fefe3bf
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/readme.md
@@ -0,0 +1,6 @@
+Unit test suite for SettingsLib using Robolectric.
+
+```
+$ croot
+$ make RunSettingsLibRoboTests -j40
+```
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
similarity index 71%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
index 5f66d16..22fd83c 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package com.android.settingslib;
 
-parcelable PublishConfig;
+public class TestConfig {
+    public static final int SDK_VERSION = 23;
+    public static final String MANIFEST_PATH =
+            "frameworks/base/packages/SettingsLib/robotests/AndroidManifest.xml";
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
new file mode 100644
index 0000000..f93c566
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
@@ -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 com.android.settingslib.drawer;
+
+import android.util.ArraySet;
+
+import com.android.settingslib.TestConfig;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+import java.util.Set;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class CategoryKeyTest {
+
+    @Test
+    public void testKeyCompatMap_allOldCategoryKeyAreMapped() {
+        assertThat(CategoryKey.KEY_COMPAT_MAP.size()).isEqualTo(4);
+    }
+
+    @Test
+    public void removingAnyKeyBreaksCompiler() {
+        // The keys in this test can be added but cannot be removed. Removing any key will remove
+        // categories from Settings app. Bad things will happen.
+        final Set<String> allKeys = new ArraySet<>();
+
+        // DO NOT REMOVE ANYTHING BELOW
+        allKeys.add(CategoryKey.CATEGORY_HOMEPAGE);
+        allKeys.add(CategoryKey.CATEGORY_DEVICE);
+        allKeys.add(CategoryKey.CATEGORY_APPS);
+        allKeys.add(CategoryKey.CATEGORY_APPS_DEFAULT);
+        allKeys.add(CategoryKey.CATEGORY_BATTERY);
+        allKeys.add(CategoryKey.CATEGORY_DISPLAY);
+        allKeys.add(CategoryKey.CATEGORY_SOUND);
+        allKeys.add(CategoryKey.CATEGORY_STORAGE);
+        allKeys.add(CategoryKey.CATEGORY_SECURITY);
+        allKeys.add(CategoryKey.CATEGORY_ACCOUNT);
+        allKeys.add(CategoryKey.CATEGORY_SYSTEM);
+        // DO NOT REMOVE ANYTHING ABOVE
+
+        assertThat(allKeys.size()).isEqualTo(11);
+    }
+
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java
new file mode 100644
index 0000000..380f622
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryManagerTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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.drawer;
+
+import android.content.Context;
+import android.util.Pair;
+
+import com.android.settingslib.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class CategoryManagerTest {
+
+    private Context mContext;
+    private CategoryManager mCategoryManager;
+    private Map<Pair<String, String>, Tile> mTileByComponentCache;
+    private Map<String, DashboardCategory> mCategoryByKeyMap;
+
+    @Before
+    public void setUp() {
+        mContext = ShadowApplication.getInstance().getApplicationContext();
+        mTileByComponentCache = new HashMap<>();
+        mCategoryByKeyMap = new HashMap<>();
+        mCategoryManager = CategoryManager.get(mContext);
+    }
+
+    @Test
+    public void getInstance_shouldBeSingleton() {
+        assertThat(mCategoryManager).isSameAs(CategoryManager.get(mContext));
+    }
+
+    @Test
+    public void backwardCompatCleanupForCategory_shouldNotChangeCategoryForNewKeys() {
+        final Tile tile1 = new Tile();
+        final Tile tile2 = new Tile();
+        tile1.category = CategoryKey.CATEGORY_ACCOUNT;
+        tile2.category = CategoryKey.CATEGORY_ACCOUNT;
+        final DashboardCategory category = new DashboardCategory();
+        category.addTile(tile1);
+        category.addTile(tile2);
+        mCategoryByKeyMap.put(CategoryKey.CATEGORY_ACCOUNT, category);
+        mTileByComponentCache.put(new Pair<>("PACKAGE", "1"), tile1);
+        mTileByComponentCache.put(new Pair<>("PACKAGE", "2"), tile2);
+
+        mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
+
+        assertThat(mCategoryByKeyMap.size()).isEqualTo(1);
+        assertThat(mCategoryByKeyMap.get(CategoryKey.CATEGORY_ACCOUNT)).isNotNull();
+    }
+
+    @Test
+    public void backwardCompatCleanupForCategory_shouldNotChangeCategoryForMixedKeys() {
+        final Tile tile1 = new Tile();
+        final Tile tile2 = new Tile();
+        final String oldCategory = "com.android.settings.category.wireless";
+        tile1.category = CategoryKey.CATEGORY_ACCOUNT;
+        tile2.category = oldCategory;
+        final DashboardCategory category1 = new DashboardCategory();
+        category1.addTile(tile1);
+        final DashboardCategory category2 = new DashboardCategory();
+        category2.addTile(tile2);
+        mCategoryByKeyMap.put(CategoryKey.CATEGORY_ACCOUNT, category1);
+        mCategoryByKeyMap.put(oldCategory, category2);
+        mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS1"), tile1);
+        mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS2"), tile2);
+
+        mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
+
+        assertThat(mCategoryByKeyMap.size()).isEqualTo(2);
+        assertThat(mCategoryByKeyMap.get(CategoryKey.CATEGORY_ACCOUNT).tiles.size()).isEqualTo(1);
+        assertThat(mCategoryByKeyMap.get(oldCategory).tiles.size()).isEqualTo(1);
+    }
+
+    @Test
+    public void backwardCompatCleanupForCategory_shouldChangeCategoryForOldKeys() {
+        final Tile tile1 = new Tile();
+        final String oldCategory = "com.android.settings.category.wireless";
+        tile1.category = oldCategory;
+        final DashboardCategory category1 = new DashboardCategory();
+        category1.addTile(tile1);
+        mCategoryByKeyMap.put(oldCategory, category1);
+        mTileByComponentCache.put(new Pair<>("PACKAGE", "CLASS1"), tile1);
+
+        mCategoryManager.backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
+
+        // Added 1 more category to category map.
+        assertThat(mCategoryByKeyMap.size()).isEqualTo(2);
+        // The new category map has CATEGORY_NETWORK type now, which contains 1 tile.
+        assertThat(mCategoryByKeyMap.get(CategoryKey.CATEGORY_NETWORK).tiles.size()).isEqualTo(1);
+        // Old category still exists.
+        assertThat(mCategoryByKeyMap.get(oldCategory).tiles.size()).isEqualTo(1);
+    }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index d55bb4f..dd543a3 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -1310,10 +1310,6 @@
                 loadFractionSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
                         R.fraction.def_accessibility_display_magnification_scale, 1);
                 stmt.close();
-                stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);");
-                loadBooleanSetting(stmt,
-                        Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE,
-                        R.bool.def_accessibility_display_magnification_auto_update);
 
                 db.setTransactionSuccessful();
             } finally {
@@ -2508,10 +2504,6 @@
             loadFractionSetting(stmt, Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
                     R.fraction.def_accessibility_display_magnification_scale, 1);
 
-            loadBooleanSetting(stmt,
-                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE,
-                    R.bool.def_accessibility_display_magnification_auto_update);
-
             loadBooleanSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE,
                     R.bool.def_user_setup_complete);
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 3084b9b..88ee33c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -42,7 +42,6 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.Debug;
 import android.os.DropBoxManager;
 import android.os.Environment;
 import android.os.Handler;
@@ -53,6 +52,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SELinux;
+import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
@@ -62,6 +62,7 @@
 import android.util.ArraySet;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseBooleanArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.content.PackageMonitor;
@@ -75,6 +76,7 @@
 import java.io.FileNotFoundException;
 import java.io.PrintWriter;
 import java.security.SecureRandom;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
@@ -114,7 +116,7 @@
  */
 @SuppressWarnings("deprecation")
 public class SettingsProvider extends ContentProvider {
-    private static final boolean DEBUG = false;
+    static final boolean DEBUG = false;
 
     private static final boolean DROP_DATABASE_ON_MIGRATION = true;
 
@@ -264,6 +266,7 @@
         }
         registerBroadcastReceivers();
         startWatchingUserRestrictionChanges();
+        ServiceManager.addService("settings", new SettingsService(this));
         return true;
     }
 
@@ -560,16 +563,14 @@
         return cacheDir;
     }
 
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+    public void dumpInternal(FileDescriptor fd, PrintWriter pw, String[] args) {
         synchronized (mLock) {
             final long identity = Binder.clearCallingIdentity();
             try {
-                List<UserInfo> users = mUserManager.getUsers(true);
+                SparseBooleanArray users = mSettingsRegistry.getKnownUsersLocked();
                 final int userCount = users.size();
                 for (int i = 0; i < userCount; i++) {
-                    UserInfo user = users.get(i);
-                    dumpForUserLocked(user.id, pw);
+                    dumpForUserLocked(users.keyAt(i), pw);
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -580,49 +581,53 @@
     private void dumpForUserLocked(int userId, PrintWriter pw) {
         if (userId == UserHandle.USER_SYSTEM) {
             pw.println("GLOBAL SETTINGS (user " + userId + ")");
-            Cursor globalCursor = getAllGlobalSettings(ALL_COLUMNS);
-            dumpSettings(globalCursor, pw);
-            pw.println();
-
             SettingsState globalSettings = mSettingsRegistry.getSettingsLocked(
                     SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
+            if (globalSettings != null) {
+                dumpSettingsLocked(globalSettings, pw);
+            }
+            pw.println();
+
             globalSettings.dumpHistoricalOperations(pw);
         }
 
         pw.println("SECURE SETTINGS (user " + userId + ")");
-        Cursor secureCursor = getAllSecureSettings(userId, ALL_COLUMNS);
-        dumpSettings(secureCursor, pw);
-        pw.println();
-
         SettingsState secureSettings = mSettingsRegistry.getSettingsLocked(
                 SETTINGS_TYPE_SECURE, userId);
+        if (secureSettings != null) {
+            dumpSettingsLocked(secureSettings, pw);
+        }
+        pw.println();
+
         secureSettings.dumpHistoricalOperations(pw);
 
         pw.println("SYSTEM SETTINGS (user " + userId + ")");
-        Cursor systemCursor = getAllSystemSettings(userId, ALL_COLUMNS);
-        dumpSettings(systemCursor, pw);
-        pw.println();
-
         SettingsState systemSettings = mSettingsRegistry.getSettingsLocked(
                 SETTINGS_TYPE_SYSTEM, userId);
+        if (systemSettings != null) {
+            dumpSettingsLocked(systemSettings, pw);
+        }
+        pw.println();
+
         systemSettings.dumpHistoricalOperations(pw);
     }
 
-    private void dumpSettings(Cursor cursor, PrintWriter pw) {
-        if (cursor == null || !cursor.moveToFirst()) {
-            return;
-        }
+    private void dumpSettingsLocked(SettingsState settingsState, PrintWriter pw) {
+        List<String> names = settingsState.getSettingNamesLocked();
 
-        final int idColumnIdx = cursor.getColumnIndex(Settings.NameValueTable._ID);
-        final int nameColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.NAME);
-        final int valueColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.VALUE);
+        final int nameCount = names.size();
 
-        do {
-            pw.append("_id:").append(toDumpString(cursor.getString(idColumnIdx)));
-            pw.append(" name:").append(toDumpString(cursor.getString(nameColumnIdx)));
-            pw.append(" value:").append(toDumpString(cursor.getString(valueColumnIdx)));
+        for (int i = 0; i < nameCount; i++) {
+            String name = names.get(i);
+            Setting setting = settingsState.getSettingLocked(name);
+            pw.print("_id:"); pw.print(toDumpString(setting.getId()));
+            pw.print(" name:"); pw.print(toDumpString(name));
+            if (setting.getPackageName() != null) {
+                pw.print(" pkg:"); pw.print(toDumpString(setting.getPackageName()));
+            }
+            pw.print(" value:"); pw.print(toDumpString(setting.getValue()));
             pw.println();
-        } while (cursor.moveToNext());
+        }
     }
 
     private static String toDumpString(String s) {
@@ -916,8 +921,9 @@
 
         // Special case for location (sigh).
         if (isLocationProvidersAllowedRestricted(name, callingUserId, owningUserId)) {
-            return mSettingsRegistry.getSettingsLocked(SETTINGS_TYPE_SECURE,
-                    owningUserId).getNullSetting();
+            SettingsState settings = mSettingsRegistry.getSettingsLocked(SETTINGS_TYPE_SECURE,
+                    owningUserId);
+            return settings != null ? settings.getNullSetting() : null;
         }
 
         // Get the value.
@@ -1267,7 +1273,8 @@
                 && (parentId = getGroupParentLocked(userId)) != userId) {
             // The setting has a dependency and the profile has a parent
             String dependency = sSystemCloneFromParentOnDependency.get(setting);
-            if (getSecureSetting(dependency, userId).getValue().equals("1")) {
+            Setting settingObj = getSecureSetting(dependency, userId);
+            if (settingObj != null && settingObj.getValue().equals("1")) {
                 return parentId;
             }
         }
@@ -1405,6 +1412,9 @@
 
         Setting settingValue = getSecureSetting(
                 Settings.Secure.LOCATION_PROVIDERS_ALLOWED, owningUserId);
+        if (settingValue == null) {
+            return false;
+        }
 
         String oldProviders = (settingValue != null) ? settingValue.getValue() : "";
 
@@ -1491,14 +1501,14 @@
     private Bundle packageValueForCallResult(Setting setting,
             boolean trackingGeneration) {
         if (!trackingGeneration) {
-            if (setting.isNull()) {
+            if (setting == null || setting.isNull()) {
                 return NULL_SETTING_BUNDLE;
             }
             return Bundle.forPair(Settings.NameValueTable.VALUE, setting.getValue());
         }
         Bundle result = new Bundle();
         result.putString(Settings.NameValueTable.VALUE,
-                !setting.isNull() ? setting.getValue() : null);
+                setting != null && !setting.isNull() ? setting.getValue() : null);
         mSettingsRegistry.mGenerationRegistry.addGenerationData(result, setting.getkey());
         return result;
     }
@@ -1554,7 +1564,7 @@
     }
 
     private static void appendSettingToCursor(MatrixCursor cursor, Setting setting) {
-        if (setting.isNull()) {
+        if (setting == null || setting.isNull()) {
             return;
         }
         final int columnCount = cursor.getColumnCount();
@@ -1700,15 +1710,32 @@
         public List<String> getSettingsNamesLocked(int type, int userId) {
             final int key = makeKey(type, userId);
             SettingsState settingsState = peekSettingsStateLocked(key);
+            if (settingsState == null) {
+                return new ArrayList<String>();
+            }
             return settingsState.getSettingNamesLocked();
         }
 
+        public SparseBooleanArray getKnownUsersLocked() {
+            SparseBooleanArray users = new SparseBooleanArray();
+            for (int i = mSettingsStates.size()-1; i >= 0; i--) {
+                users.put(getUserIdFromKey(mSettingsStates.keyAt(i)), true);
+            }
+            return users;
+        }
+
         public SettingsState getSettingsLocked(int type, int userId) {
             final int key = makeKey(type, userId);
             return peekSettingsStateLocked(key);
         }
 
-        public void ensureSettingsForUserLocked(int userId) {
+        public boolean ensureSettingsForUserLocked(int userId) {
+            // First make sure this user actually exists.
+            if (mUserManager.getUserInfo(userId) == null) {
+                Slog.wtf(LOG_TAG, "Requested user " + userId + " does not exist");
+                return false;
+            }
+
             // Migrate the setting for this user if needed.
             migrateLegacySettingsForUserIfNeededLocked(userId);
 
@@ -1733,6 +1760,7 @@
             // Upgrade the settings to the latest version.
             UpgradeController upgrader = new UpgradeController(userId);
             upgrader.upgradeIfNeededLocked();
+            return true;
         }
 
         private void ensureSettingsStateLocked(int key) {
@@ -1790,7 +1818,8 @@
             final int key = makeKey(type, userId);
 
             SettingsState settingsState = peekSettingsStateLocked(key);
-            final boolean success = settingsState.insertSettingLocked(name, value, packageName);
+            final boolean success = settingsState != null
+                    && settingsState.insertSettingLocked(name, value, packageName);
 
             if (forceNotify || success) {
                 notifyForSettingsChange(key, name);
@@ -1802,6 +1831,9 @@
             final int key = makeKey(type, userId);
 
             SettingsState settingsState = peekSettingsStateLocked(key);
+            if (settingsState == null) {
+                return false;
+            }
             final boolean success = settingsState.deleteSettingLocked(name);
 
             if (forceNotify || success) {
@@ -1814,6 +1846,9 @@
             final int key = makeKey(type, userId);
 
             SettingsState settingsState = peekSettingsStateLocked(key);
+            if (settingsState == null) {
+                return null;
+            }
             return settingsState.getSettingLocked(name);
         }
 
@@ -1822,7 +1857,8 @@
             final int key = makeKey(type, userId);
 
             SettingsState settingsState = peekSettingsStateLocked(key);
-            final boolean success = settingsState.updateSettingLocked(name, value, packageName);
+            final boolean success = settingsState != null
+                    && settingsState.updateSettingLocked(name, value, packageName);
 
             if (forceNotify || success) {
                 notifyForSettingsChange(key, name);
@@ -1850,7 +1886,9 @@
                 return settingsState;
             }
 
-            ensureSettingsForUserLocked(getUserIdFromKey(key));
+            if (!ensureSettingsForUserLocked(getUserIdFromKey(key))) {
+                return null;
+            }
             return mSettingsStates.get(key);
         }
 
@@ -2137,7 +2175,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 133;
+            private static final int SETTINGS_VERSION = 135;
 
             private final int mUserId;
 
@@ -2452,6 +2490,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 +2517,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 +2529,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 +2542,15 @@
                         systemSettings.insertSettingLocked(Settings.System.END_BUTTON_BEHAVIOR,
                                 defaultEndButtonBehavior, SettingsState.SYSTEM_PACKAGE_NAME);
                     }
-                    currentVersion = 133;
+                    currentVersion = 134;
+                }
+
+                if (currentVersion == 134) {
+                    // Remove setting that specifies if magnification values should be preserved.
+                    // This setting defaulted to true and never has a UI.
+                    getSecureSettingsLocked(userId).deleteSettingLocked(
+                            Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE);
+                    currentVersion = 135;
                 }
 
                 if (currentVersion != newVersion) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
new file mode 100644
index 0000000..169b01f
--- /dev/null
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsService.java
@@ -0,0 +1,375 @@
+/*
+ * 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.providers.settings;
+
+import android.app.ActivityManagerNative;
+import android.content.IContentProvider;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.os.ShellCommand;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+final public class SettingsService extends Binder {
+    final SettingsProvider mProvider;
+
+    public SettingsService(SettingsProvider provider) {
+        mProvider = provider;
+    }
+
+    @Override
+    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+            String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
+        (new MyShellCommand(mProvider, false)).exec(
+                this, in, out, err, args, callback, resultReceiver);
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mProvider.getContext().checkCallingPermission(android.Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump SettingsProvider from from pid="
+                    + Binder.getCallingPid()
+                    + ", uid=" + Binder.getCallingUid()
+                    + " without permission "
+                    + android.Manifest.permission.DUMP);
+            return;
+        }
+
+        int opti = 0;
+        while (opti < args.length) {
+            String opt = args[opti];
+            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
+                break;
+            }
+            opti++;
+            if ("-h".equals(opt)) {
+                MyShellCommand.dumpHelp(pw, true);
+                return;
+            } else {
+                pw.println("Unknown argument: " + opt + "; use -h for help");
+            }
+        }
+
+        long caller = Binder.clearCallingIdentity();
+        try {
+            mProvider.dumpInternal(fd, pw, args);
+        } finally {
+            Binder.restoreCallingIdentity(caller);
+        }
+    }
+
+    final static class MyShellCommand extends ShellCommand {
+        final SettingsProvider mProvider;
+        final boolean mDumping;
+
+        enum CommandVerb {
+            UNSPECIFIED,
+            GET,
+            PUT,
+            DELETE,
+            LIST,
+        }
+
+        int mUser = -1;     // unspecified
+        CommandVerb mVerb = CommandVerb.UNSPECIFIED;
+        String mTable = null;
+        String mKey = null;
+        String mValue = null;
+
+
+        MyShellCommand(SettingsProvider provider, boolean dumping) {
+            mProvider = provider;
+            mDumping = dumping;
+        }
+
+        @Override
+        public int onCommand(String cmd) {
+            if (cmd == null) {
+                return handleDefaultCommands(cmd);
+            }
+
+            final PrintWriter perr = getErrPrintWriter();
+
+            boolean valid = false;
+            String arg = cmd;
+            do {
+                if ("--user".equals(arg)) {
+                    if (mUser != -1) {
+                        // --user specified more than once; invalid
+                        break;
+                    }
+                    arg = getNextArgRequired();
+                    if ("current".equals(arg) || "cur".equals(arg)) {
+                        mUser = UserHandle.USER_CURRENT;
+                    } else {
+                        mUser = Integer.parseInt(arg);
+                    }
+                } else if (mVerb == CommandVerb.UNSPECIFIED) {
+                    if ("get".equalsIgnoreCase(arg)) {
+                        mVerb = CommandVerb.GET;
+                    } else if ("put".equalsIgnoreCase(arg)) {
+                        mVerb = CommandVerb.PUT;
+                    } else if ("delete".equalsIgnoreCase(arg)) {
+                        mVerb = CommandVerb.DELETE;
+                    } else if ("list".equalsIgnoreCase(arg)) {
+                        mVerb = CommandVerb.LIST;
+                    } else {
+                        // invalid
+                        perr.println("Invalid command: " + arg);
+                        return -1;
+                    }
+                } else if (mTable == null) {
+                    if (!"system".equalsIgnoreCase(arg)
+                            && !"secure".equalsIgnoreCase(arg)
+                            && !"global".equalsIgnoreCase(arg)) {
+                        perr.println("Invalid namespace '" + arg + "'");
+                        return -1;
+                    }
+                    mTable = arg.toLowerCase();
+                    if (mVerb == CommandVerb.LIST) {
+                        valid = true;
+                        break;
+                    }
+                } else if (mVerb == CommandVerb.GET || mVerb == CommandVerb.DELETE) {
+                    mKey = arg;
+                    if (peekNextArg() == null) {
+                        valid = true;
+                    } else {
+                        perr.println("Too many arguments");
+                        return -1;
+                    }
+                    break;
+                } else if (mKey == null) {
+                    mKey = arg;
+                    // keep going; there's another PUT arg
+                } else {    // PUT, final arg
+                    mValue = arg;
+                    if (peekNextArg() == null) {
+                        valid = true;
+                    } else {
+                        perr.println("Too many arguments");
+                        return -1;
+                    }
+                    break;
+                }
+            } while ((arg = getNextArg()) != null);
+
+            if (!valid) {
+                perr.println("Bad arguments");
+                return -1;
+            }
+
+            if (mUser == UserHandle.USER_CURRENT) {
+                try {
+                    mUser = ActivityManagerNative.getDefault().getCurrentUser().id;
+                } catch (RemoteException e) {
+                    throw new RuntimeException("Failed in IPC", e);
+                }
+            }
+            if (mUser < 0) {
+                mUser = UserHandle.USER_SYSTEM;
+            } else if (mVerb == CommandVerb.DELETE || mVerb == CommandVerb.LIST) {
+                perr.println("--user not supported for delete and list.");
+                return -1;
+            }
+            UserManager userManager = UserManager.get(mProvider.getContext());
+            if (userManager.getUserInfo(mUser) == null) {
+                perr.println("Invalid user: " + mUser);
+                return -1;
+            }
+
+            final IContentProvider iprovider = mProvider.getIContentProvider();
+            final PrintWriter pout = getOutPrintWriter();
+            switch (mVerb) {
+                case GET:
+                    pout.println(getForUser(iprovider, mUser, mTable, mKey));
+                    break;
+                case PUT:
+                    putForUser(iprovider, mUser, mTable, mKey, mValue);
+                    break;
+                case DELETE:
+                    pout.println("Deleted "
+                            + deleteForUser(iprovider, mUser, mTable, mKey) + " rows");
+                    break;
+                case LIST:
+                    for (String line : listForUser(iprovider, mUser, mTable)) {
+                        pout.println(line);
+                    }
+                    break;
+                default:
+                    perr.println("Unspecified command");
+                    return -1;
+            }
+
+            return 0;
+        }
+
+        private List<String> listForUser(IContentProvider provider, int userHandle, String table) {
+            final Uri uri = "system".equals(table) ? Settings.System.CONTENT_URI
+                    : "secure".equals(table) ? Settings.Secure.CONTENT_URI
+                    : "global".equals(table) ? Settings.Global.CONTENT_URI
+                    : null;
+            final ArrayList<String> lines = new ArrayList<String>();
+            if (uri == null) {
+                return lines;
+            }
+            try {
+                final Cursor cursor = provider.query(resolveCallingPackage(), uri, null, null, null,
+                        null, null);
+                try {
+                    while (cursor != null && cursor.moveToNext()) {
+                        lines.add(cursor.getString(1) + "=" + cursor.getString(2));
+                    }
+                } finally {
+                    if (cursor != null) {
+                        cursor.close();
+                    }
+                }
+                Collections.sort(lines);
+            } catch (RemoteException e) {
+                throw new RuntimeException("Failed in IPC", e);
+            }
+            return lines;
+        }
+
+        String getForUser(IContentProvider provider, int userHandle,
+                final String table, final String key) {
+            final String callGetCommand;
+            if ("system".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_SYSTEM;
+            else if ("secure".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_SECURE;
+            else if ("global".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_GLOBAL;
+            else {
+                getErrPrintWriter().println("Invalid table; no put performed");
+                throw new IllegalArgumentException("Invalid table " + table);
+            }
+
+            String result = null;
+            try {
+                Bundle arg = new Bundle();
+                arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
+                Bundle b = provider.call(resolveCallingPackage(), callGetCommand, key, arg);
+                if (b != null) {
+                    result = b.getPairValue();
+                }
+            } catch (RemoteException e) {
+                throw new RuntimeException("Failed in IPC", e);
+            }
+            return result;
+        }
+
+        void putForUser(IContentProvider provider, int userHandle,
+                final String table, final String key, final String value) {
+            final String callPutCommand;
+            if ("system".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_SYSTEM;
+            else if ("secure".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_SECURE;
+            else if ("global".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_GLOBAL;
+            else {
+                getErrPrintWriter().println("Invalid table; no put performed");
+                return;
+            }
+
+            try {
+                Bundle arg = new Bundle();
+                arg.putString(Settings.NameValueTable.VALUE, value);
+                arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
+                provider.call(resolveCallingPackage(), callPutCommand, key, arg);
+            } catch (RemoteException e) {
+                throw new RuntimeException("Failed in IPC", e);
+            }
+        }
+
+        int deleteForUser(IContentProvider provider, int userHandle,
+                final String table, final String key) {
+            Uri targetUri;
+            if ("system".equals(table)) targetUri = Settings.System.getUriFor(key);
+            else if ("secure".equals(table)) targetUri = Settings.Secure.getUriFor(key);
+            else if ("global".equals(table)) targetUri = Settings.Global.getUriFor(key);
+            else {
+                getErrPrintWriter().println("Invalid table; no delete performed");
+                throw new IllegalArgumentException("Invalid table " + table);
+            }
+
+            int num = 0;
+            try {
+                num = provider.delete(resolveCallingPackage(), targetUri, null, null);
+            } catch (RemoteException e) {
+                throw new RuntimeException("Failed in IPC", e);
+            }
+            return num;
+        }
+
+        public static String resolveCallingPackage() {
+            switch (Binder.getCallingUid()) {
+                case Process.ROOT_UID: {
+                    return "root";
+                }
+
+                case Process.SHELL_UID: {
+                    return "com.android.shell";
+                }
+
+                default: {
+                    return null;
+                }
+            }
+        }
+
+        @Override
+        public void onHelp() {
+            PrintWriter pw = getOutPrintWriter();
+            dumpHelp(pw, mDumping);
+        }
+
+        static void dumpHelp(PrintWriter pw, boolean dumping) {
+            if (dumping) {
+                pw.println("Settings provider dump options:");
+                pw.println("  [-h]");
+                pw.println("  -h: print this help.");
+            } else {
+                pw.println("Settings provider (settings) commands:");
+                pw.println("  help");
+                pw.println("      Print this help text.");
+                pw.println("  get [--user <USER_ID> | current] NAMESPACE KEY");
+                pw.println("      Retrieve the current value of KEY.");
+                pw.println("  put [--user <USER_ID> | current] NAMESPACE KEY VALUE");
+                pw.println("      Change the contents of KEY to VALUE.");
+                pw.println("  delete NAMESPACE KEY");
+                pw.println("      Delete the entry for KEY.");
+                pw.println("  list NAMESPACE");
+                pw.println("      Print all defined keys.");
+                pw.println();
+                pw.println("  NAMESPACE is one of {system, secure, global}, case-insensitive");
+            }
+        }
+    }
+}
+
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 832c9d9..d682fe9 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -350,8 +350,11 @@
                 pw.print(" ");
                 pw.print(operation.mOperation);
                 if (operation.mSetting != null) {
-                    pw.print("  ");
-                    pw.print(operation.mSetting);
+                    pw.print(" ");
+                    // Only print the name of the setting, since we don't know the
+                    // historical package and values for it so they would be misleading
+                    // to print here (all we could print is what the current data is).
+                    pw.print(operation.mSetting.getName());
                 }
                 pw.println();
             }
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 4d59d57..2adb261 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -415,6 +415,18 @@
             android:launchMode="singleTop"
             android:excludeFromRecents="true" />
 
+        <activity
+            android:name=".pip.phone.PipMenuActivity"
+            android:theme="@style/PipPhoneOverlayControlTheme"
+            android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+            android:excludeFromRecents="true"
+            android:exported="false"
+            android:resizeableActivity="true"
+            android:supportsPictureInPicture="true"
+            android:stateNotNeeded="true"
+            android:taskAffinity=""
+            androidprv:alwaysFocusable="true" />
+
         <!-- platform logo easter egg activity -->
         <activity
             android:name=".DessertCase"
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/qs/QSContainer.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSContainer.java
index a616369..4947863 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSContainer.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSContainer.java
@@ -31,7 +31,7 @@
 
     // This should be incremented any time this class or ActivityStarter or BaseStatusBarHeader
     // change in incompatible ways.
-    public static final int VERSION = 2;
+    public static final int VERSION = 3;
 
     public QSContainer(@NonNull Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
@@ -116,7 +116,6 @@
         void startPendingIntentDismissingKeyguard(PendingIntent intent);
         void startActivity(Intent intent, boolean dismissShade);
         void startActivity(Intent intent, boolean dismissShade, Callback callback);
-        void preventNextAnimation();
 
         interface Callback {
             void onActivityStarted(int resultCode);
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_menu_activity.xml b/packages/SystemUI/res/layout/pip_menu_activity.xml
new file mode 100644
index 0000000..88e6e72
--- /dev/null
+++ b/packages/SystemUI/res/layout/pip_menu_activity.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#33000000">
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center">
+        <Button
+            android:id="@+id/expand_pip"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:textSize="14sp"
+            android:textColor="#ffffffff"
+            android:text="@string/pip_phone_expand"
+            android:fontFamily="sans-serif" />
+    </LinearLayout>
+</FrameLayout>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 20113da..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>
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/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..37a7e38 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1667,4 +1667,51 @@
          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>
+
+    <!-- Making the PIP fullscreen -->
+    <string name="pip_phone_expand">Expand</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>
+
+    <!-- PIP tap once to break through to the activity. Non-translatable since it should
+        not appear on production builds ever. -->
+    <string name="pip_tap_through_title" translatable="false">Tap to interact</string>
+
+    <!-- PIP tap once to break through to the activity. Non-translatable since it should
+        not appear on production builds ever. -->
+    <string name="pip_tap_through_summary" translatable="false">Tap once to interact with the activity</string>
+
+    <!-- PIP snap to closest edge. Non-translatable since it should
+        not appear on production builds ever. -->
+    <string name="pip_snap_mode_edge_title" translatable="false">Snap to closest edge</string>
+
+    <!-- PIP snap to closest edge. Non-translatable since it should
+        not appear on production builds ever. -->
+    <string name="pip_snap_mode_edge_summary" translatable="false">Snap to the closest edge</string>
+
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index e5bc8b9..6661f07 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -56,6 +56,24 @@
         <item name="android:activityCloseExitAnimation">@anim/forced_resizable_exit</item>
     </style>
 
+    <style name="PipPhoneOverlayControlTheme" parent="@android:style/Theme.Material">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowBackground">@drawable/forced_resizable_background</item>
+        <item name="android:colorBackgroundCacheHint">@null</item>
+        <item name="android:statusBarColor">@color/transparent</item>
+        <item name="android:windowAnimationStyle">@style/Animation.PipPhoneOverlayControl</item>
+    </style>
+
+    <style name="Animation.PipPhoneOverlayControl" parent="@android:style/Animation">
+        <item name="android:activityOpenEnterAnimation">@anim/forced_resizable_enter</item>
+
+        <!-- If the target stack doesn't have focus, we do a task to front animation. -->
+        <item name="android:taskToFrontEnterAnimation">@anim/forced_resizable_enter</item>
+        <item name="android:activityCloseExitAnimation">@anim/forced_resizable_exit</item>
+    </style>
+
     <style name="TextAppearance.StatusBar.HeadsUp"
         parent="@*android:style/TextAppearance.StatusBar">
     </style>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 211f8e8..f09d6e9 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -121,6 +121,47 @@
 
     </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" />
+
+        <com.android.systemui.tuner.TunerSwitch
+            android:key="pip_tap_through"
+            android:title="@string/pip_tap_through_title"
+            android:summary="@string/pip_tap_through_summary"
+            sysui:defValue="false" />
+
+        <com.android.systemui.tuner.TunerSwitch
+            android:key="pip_snap_mode_edge"
+            android:title="@string/pip_snap_mode_edge_title"
+            android:summary="@string/pip_snap_mode_edge_summary"
+            sysui:defValue="false" />
+
+    </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/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..81dfafc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -0,0 +1,257 @@
+/*
+ * 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.net.Uri;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.UserHandle;
+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 setListening(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 {
+
+        /**
+         * Called when a sensor requests a pulse
+         * @param pulseReason Requesting sensor, e.g. {@link DozeLog#PULSE_REASON_SENSOR_PICKUP}
+         * @param sensorPerformedProxCheck true if the sensor already checked for FAR proximity.
+         */
+        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..2bb1d6a 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -16,47 +16,39 @@
 
 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.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 +64,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 +78,7 @@
     private long mNotificationPulseTime;
 
     private AmbientDisplayConfiguration mConfig;
+    private AlarmManager mAlarmManager;
 
     public DozeService() {
         if (DEBUG) Log.d(mTag, "new DozeService()");
@@ -101,10 +93,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 +116,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 +171,10 @@
                 // stopDozing because can we just keep dozing until the bitter end.
             }
         }));
+
+        if (mDozeParameters.getAlwaysOn()) {
+            mTimeTick.onAlarm();
+        }
     }
 
     @Override
@@ -214,6 +191,7 @@
 
         // Tell the host that it's over.
         mHost.stopDozing();
+        mAlarmManager.cancel(mTimeTick);
     }
 
     private void requestPulse(final int reason) {
@@ -221,6 +199,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 +261,7 @@
                 if (mPulsing && mDreaming) {
                     mPulsing = false;
                     if (REREGISTER_ALL_SENSORS_ON_SCREEN_OFF) {
-                        reregisterAllSensors();
+                        mDozeSensors.reregisterAllSensors();
                     }
                     turnDisplayOff();
                 }
@@ -293,7 +272,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 +296,11 @@
 
     private void listenForPulseSignals(boolean listen) {
         if (DEBUG) Log.d(mTag, "listenForPulseSignals: " + listen);
-        for (TriggerSensor s : mSensors) {
-            s.setListening(listen);
-        }
+        mDozeSensors.setListening(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 +308,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 +332,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 +360,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 +413,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 +436,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 +468,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/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index e05e507..816d70d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -81,15 +81,6 @@
         }
 
         @Override // Binder interface
-        public void keyguardDone(boolean authenticated, boolean wakeup) {
-            Trace.beginSection("KeyguardService.mBinder#keyguardDone");
-            checkPermission();
-            // TODO: Remove wakeup
-            mKeyguardViewMediator.keyguardDone(authenticated);
-            Trace.endSection();
-        }
-
-        @Override // Binder interface
         public void setOccluded(boolean isOccluded, boolean animate) {
             Trace.beginSection("KeyguardService.mBinder#setOccluded");
             checkPermission();
@@ -202,12 +193,6 @@
             mKeyguardViewMediator.startKeyguardExitAnimation(startTime, fadeoutDuration);
             Trace.endSection();
         }
-
-        @Override
-        public void onActivityDrawn() {
-            checkPermission();
-            mKeyguardViewMediator.onActivityDrawn();
-        }
     };
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 24247e4..9ae341a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -135,7 +135,6 @@
 
     private static final boolean DEBUG = KeyguardConstants.DEBUG;
     private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
-    private final static boolean DBG_WAKE = false;
 
     private final static String TAG = "KeyguardViewMediator";
 
@@ -145,25 +144,23 @@
             "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_LOCK";
 
     // used for handler messages
-    private static final int SHOW = 2;
-    private static final int HIDE = 3;
-    private static final int RESET = 4;
-    private static final int VERIFY_UNLOCK = 5;
-    private static final int NOTIFY_FINISHED_GOING_TO_SLEEP = 6;
-    private static final int NOTIFY_SCREEN_TURNING_ON = 7;
-    private static final int KEYGUARD_DONE = 9;
-    private static final int KEYGUARD_DONE_DRAWING = 10;
-    private static final int KEYGUARD_DONE_AUTHENTICATING = 11;
-    private static final int SET_OCCLUDED = 12;
-    private static final int KEYGUARD_TIMEOUT = 13;
-    private static final int DISMISS = 17;
-    private static final int START_KEYGUARD_EXIT_ANIM = 18;
-    private static final int ON_ACTIVITY_DRAWN = 19;
-    private static final int KEYGUARD_DONE_PENDING_TIMEOUT = 20;
-    private static final int NOTIFY_STARTED_WAKING_UP = 21;
-    private static final int NOTIFY_SCREEN_TURNED_ON = 22;
-    private static final int NOTIFY_SCREEN_TURNED_OFF = 23;
-    private static final int NOTIFY_STARTED_GOING_TO_SLEEP = 24;
+    private static final int SHOW = 1;
+    private static final int HIDE = 2;
+    private static final int RESET = 3;
+    private static final int VERIFY_UNLOCK = 4;
+    private static final int NOTIFY_FINISHED_GOING_TO_SLEEP = 5;
+    private static final int NOTIFY_SCREEN_TURNING_ON = 6;
+    private static final int KEYGUARD_DONE = 7;
+    private static final int KEYGUARD_DONE_DRAWING = 8;
+    private static final int SET_OCCLUDED = 9;
+    private static final int KEYGUARD_TIMEOUT = 10;
+    private static final int DISMISS = 11;
+    private static final int START_KEYGUARD_EXIT_ANIM = 12;
+    private static final int KEYGUARD_DONE_PENDING_TIMEOUT = 13;
+    private static final int NOTIFY_STARTED_WAKING_UP = 14;
+    private static final int NOTIFY_SCREEN_TURNED_ON = 15;
+    private static final int NOTIFY_SCREEN_TURNED_OFF = 16;
+    private static final int NOTIFY_STARTED_GOING_TO_SLEEP = 17;
 
     /**
      * The default amount of time we stay awake (used for all key input)
@@ -185,11 +182,6 @@
     private static final int KEYGUARD_DONE_DRAWING_TIMEOUT_MS = 2000;
 
     /**
-     * Secure setting whether analytics are collected on the keyguard.
-     */
-    private static final String KEYGUARD_ANALYTICS_SETTING = "keyguard_analytics";
-
-    /**
      * Boolean option for doKeyguardLocked/doKeyguardTimeout which, when set to true, forces the
      * keyguard to show even if it is disabled for the current user.
      */
@@ -209,16 +201,9 @@
     /** High level access to the power manager for WakeLocks */
     private PowerManager mPM;
 
-    /** High level access to the window manager for dismissing keyguard animation */
-    private IWindowManager mWM;
-
-
     /** TrustManager for letting it know when we change visibility */
     private TrustManager mTrustManager;
 
-    /** SearchManager for determining whether or not search assistant is available */
-    private SearchManager mSearchManager;
-
     /**
      * Used to keep the device awake while to ensure the keyguard finishes opening before
      * we sleep.
@@ -342,8 +327,6 @@
     private boolean mWakeAndUnlocking;
     private IKeyguardDrawnCallback mDrawnCallback;
 
-    private boolean mIsPerUserLock;
-
     KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
 
         @Override
@@ -533,7 +516,7 @@
             }
 
             if (!mKeyguardDonePending) {
-                KeyguardViewMediator.this.keyguardDone(true /* authenticated */);
+                KeyguardViewMediator.this.handleKeyguardDone(true /* authenticated */);
             }
             if (strongAuth) {
                 mUpdateMonitor.reportSuccessfulStrongAuthUnlockAttempt();
@@ -584,7 +567,7 @@
             if (mKeyguardDonePending) {
                 // Somebody has called keyguardDonePending before, which means that we are
                 // authenticated
-                KeyguardViewMediator.this.keyguardDone(true /* authenticated */);
+                KeyguardViewMediator.this.handleKeyguardDone(true /* authenticated */);
             }
             Trace.endSection();
         }
@@ -600,11 +583,6 @@
         }
 
         @Override
-        public boolean isInputRestricted() {
-            return KeyguardViewMediator.this.isInputRestricted();
-        }
-
-        @Override
         public boolean isScreenOn() {
             return mDeviceInteractive;
         }
@@ -645,7 +623,6 @@
 
     private void setupLocked() {
         mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-        mWM = WindowManagerGlobal.getWindowManagerService();
         mTrustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
 
         mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
@@ -720,14 +697,12 @@
      * Let us know that the system is ready after startup.
      */
     public void onSystemReady() {
-        mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
         synchronized (this) {
             if (DEBUG) Log.d(TAG, "onSystemReady");
             mSystemReady = true;
             doKeyguardLocked(null);
             mUpdateMonitor.registerCallback(mUpdateCallback);
         }
-        mIsPerUserLock = StorageManager.isFileEncryptedNativeOrEmulated();
         // Most services aren't available until the system reaches the ready state, so we
         // send it here when the device first boots.
         maybeSendUserPresentBroadcast();
@@ -1153,7 +1128,6 @@
             if (mOccluded != isOccluded) {
                 mOccluded = isOccluded;
                 mStatusBarKeyguardViewManager.setOccluded(isOccluded, animate);
-                updateActivityLockScreenState();
                 adjustStatusBarLocked();
             }
         }
@@ -1514,9 +1488,6 @@
                     Trace.beginSection("KeyguardViewMediator#handleMessage KEYGUARD_DONE_PENDING_TIMEOUT");
                     Log.w(TAG, "Timeout while waiting for activity drawn!");
                     Trace.endSection();
-                    // Fall through.
-                case ON_ACTIVITY_DRAWN:
-                    handleOnActivityDrawn();
                     break;
             }
         }
@@ -1638,7 +1609,7 @@
     private void updateActivityLockScreenState() {
         Trace.beginSection("KeyguardViewMediator#updateActivityLockScreenState");
         try {
-            ActivityManagerNative.getDefault().setLockScreenShown(mShowing, mOccluded);
+            ActivityManagerNative.getDefault().setLockScreenShown(mShowing);
         } catch (RemoteException e) {
         }
         Trace.endSection();
@@ -1668,7 +1639,6 @@
             mWakeAndUnlocking = false;
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
-            updateActivityLockScreenState();
             adjustStatusBarLocked();
             userActivity();
 
@@ -1745,13 +1715,6 @@
         Trace.endSection();
     }
 
-    private void handleOnActivityDrawn() {
-        if (DEBUG) Log.d(TAG, "handleOnActivityDrawn: mKeyguardDonePending=" + mKeyguardDonePending);
-        if (mKeyguardDonePending) {
-            mStatusBarKeyguardViewManager.onActivityDrawn();
-        }
-    }
-
     private void handleStartKeyguardExitAnimation(long startTime, long fadeoutDuration) {
         Trace.beginSection("KeyguardViewMediator#handleStartKeyguardExitAnimation");
         if (DEBUG) Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime
@@ -1784,7 +1747,6 @@
             mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
-            updateActivityLockScreenState();
             adjustStatusBarLocked();
             sendUserPresentBroadcast();
         }
@@ -1831,7 +1793,7 @@
     private void handleReset() {
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleReset");
-            mStatusBarKeyguardViewManager.reset();
+            mStatusBarKeyguardViewManager.reset(true /* hideBouncerWhenShowing */);
         }
     }
 
@@ -1845,7 +1807,6 @@
             if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
             setShowingLocked(true);
             mStatusBarKeyguardViewManager.verifyUnlock();
-            updateActivityLockScreenState();
         }
         Trace.endSection();
     }
@@ -1964,10 +1925,6 @@
         Trace.endSection();
     }
 
-    public void onActivityDrawn() {
-        mHandler.sendEmptyMessage(ON_ACTIVITY_DRAWN);
-    }
-
     public ViewMediatorCallback getViewMediatorCallback() {
         return mViewMediatorCallback;
     }
@@ -2027,6 +1984,7 @@
             }
             updateInputRestrictedLocked();
             mTrustManager.reportKeyguardShowingChanged();
+            updateActivityLockScreenState();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 53a4868..7b8d27e 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -34,6 +34,7 @@
     private IActivityManager mActivityManager;
     private IWindowManager mWindowManager;
 
+    private PipMenuActivityController mMenuController;
     private PipTouchHandler mTouchHandler;
 
     private PipManager() {}
@@ -46,13 +47,17 @@
         mActivityManager = ActivityManagerNative.getDefault();
         mWindowManager = WindowManagerGlobal.getWindowManagerService();
 
-        mTouchHandler = new PipTouchHandler(context, mActivityManager, mWindowManager);
+        mMenuController = new PipMenuActivityController(context, mActivityManager, mWindowManager);
+        mTouchHandler = new PipTouchHandler(context, mMenuController, mActivityManager,
+                mWindowManager);
     }
 
     /**
      * Updates the PIP per configuration changed.
      */
-    public void onConfigurationChanged() {}
+    public void onConfigurationChanged() {
+        mTouchHandler.onConfigurationChanged();
+    }
 
     /**
      * Gets an instance of {@link PipManager}.
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
new file mode 100644
index 0000000..bfe5cff
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -0,0 +1,137 @@
+/*
+ * 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.annotation.Nullable;
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.View;
+import com.android.systemui.R;
+
+/**
+ * Translucent activity that gets started on top of a task in PIP to allow the user to control it.
+ */
+public class PipMenuActivity extends Activity {
+
+    private static final String TAG = "PipMenuActivity";
+
+    public static final int MESSAGE_FINISH_SELF = 2;
+
+    private static final long INITIAL_DISMISS_DELAY = 2000;
+    private static final long POST_INTERACTION_DISMISS_DELAY = 1500;
+
+    private Messenger mToControllerMessenger;
+    private Messenger mMessenger = new Messenger(new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_FINISH_SELF:
+                    finish();
+                    break;
+            }
+        }
+    });
+
+    private final Runnable mFinishRunnable = new Runnable() {
+        @Override
+        public void run() {
+            finish();
+        }
+    };
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        Intent startingIntet = getIntent();
+        mToControllerMessenger = startingIntet.getParcelableExtra(
+                PipMenuActivityController.EXTRA_CONTROLLER_MESSENGER);
+
+        setContentView(R.layout.pip_menu_activity);
+        findViewById(R.id.expand_pip).setOnClickListener((view) -> {
+            finish();
+            notifyExpandPip();
+        });
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        notifyActivityVisibility(true);
+        repostDelayedFinish(INITIAL_DISMISS_DELAY);
+    }
+
+    @Override
+    public void onUserInteraction() {
+        repostDelayedFinish(POST_INTERACTION_DISMISS_DELAY);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        finish();
+    }
+
+    @Override
+    public void finish() {
+        View v = getWindow().getDecorView();
+        v.removeCallbacks(mFinishRunnable);
+        notifyActivityVisibility(false);
+        super.finish();
+        overridePendingTransition(0, R.anim.forced_resizable_exit);
+    }
+
+    @Override
+    public void setTaskDescription(ActivityManager.TaskDescription taskDescription) {
+        // Do nothing
+    }
+
+    private void notifyActivityVisibility(boolean visible) {
+        Message m = Message.obtain();
+        m.what = PipMenuActivityController.MESSAGE_ACTIVITY_VISIBILITY_CHANGED;
+        m.arg1 = visible ? 1 : 0;
+        m.replyTo = visible ? mMessenger : null;
+        try {
+            mToControllerMessenger.send(m);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Could not notify controller of PIP menu visibility", e);
+        }
+    }
+
+    private void notifyExpandPip() {
+        Message m = Message.obtain();
+        m.what = PipMenuActivityController.MESSAGE_EXPAND_PIP;
+        try {
+            mToControllerMessenger.send(m);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Could not notify controller to expand PIP", e);
+        }
+    }
+
+    private void repostDelayedFinish(long delay) {
+        View v = getWindow().getDecorView();
+        v.removeCallbacks(mFinishRunnable);
+        v.postDelayed(mFinishRunnable, delay);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
new file mode 100644
index 0000000..d1bce0c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -0,0 +1,126 @@
+package com.android.systemui.pip.phone;
+
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.view.WindowManager.INPUT_CONSUMER_PIP;
+
+import android.app.ActivityManager.StackInfo;
+import android.app.ActivityOptions;
+import android.app.IActivityManager;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.view.IWindowManager;
+
+import java.util.ArrayList;
+
+public class PipMenuActivityController {
+
+    private static final String TAG = "PipMenuActivityController";
+
+    public static final String EXTRA_CONTROLLER_MESSENGER = "messenger";
+    public static final int MESSAGE_ACTIVITY_VISIBILITY_CHANGED = 1;
+    public static final int MESSAGE_EXPAND_PIP = 3;
+
+    /**
+     * A listener interface to receive notification on changes in PIP.
+     */
+    public interface Listener {
+        /**
+         * Called when the PIP menu visibility changes.
+         */
+        void onPipMenuVisibilityChanged(boolean visible);
+    }
+
+    private Context mContext;
+    private IActivityManager mActivityManager;
+    private IWindowManager mWindowManager;
+    private ArrayList<Listener> mListeners = new ArrayList<>();
+
+    private Messenger mToActivityMessenger;
+    private Messenger mMessenger = new Messenger(new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_ACTIVITY_VISIBILITY_CHANGED: {
+                    boolean visible = msg.arg1 > 0;
+                    int listenerCount = mListeners.size();
+                    for (int i = 0; i < listenerCount; i++) {
+                        mListeners.get(i).onPipMenuVisibilityChanged(visible);
+                    }
+                    mToActivityMessenger = msg.replyTo;
+                    break;
+                }
+                case MESSAGE_EXPAND_PIP: {
+                    try {
+                        mActivityManager.resizeStack(PINNED_STACK_ID, null, true, true, true, 225);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Error showing PIP menu activity", e);
+                    }
+                    break;
+                }
+            }
+        }
+    });
+
+    public PipMenuActivityController(Context context, IActivityManager activityManager,
+            IWindowManager windowManager) {
+        mContext = context;
+        mActivityManager = activityManager;
+        mWindowManager = windowManager;
+    }
+
+    /**
+     * Adds a new menu activity listener.
+     */
+    public void addListener(Listener listener) {
+        if (!mListeners.contains(listener)) {
+            mListeners.add(listener);
+        }
+    }
+
+    /**
+     * Shows the menu activity.
+     */
+    public void showMenu() {
+        // Start the menu activity on the top task of the pinned stack
+        try {
+            StackInfo pinnedStackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
+            if (pinnedStackInfo != null && pinnedStackInfo.taskIds != null &&
+                    pinnedStackInfo.taskIds.length > 0) {
+                Intent intent = new Intent(mContext, PipMenuActivity.class);
+                intent.putExtra(EXTRA_CONTROLLER_MESSENGER, mMessenger);
+                ActivityOptions options = ActivityOptions.makeBasic();
+                options.setLaunchTaskId(
+                        pinnedStackInfo.taskIds[pinnedStackInfo.taskIds.length - 1]);
+                options.setTaskOverlay(true);
+                mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT);
+            } else {
+                Log.e(TAG, "No PIP tasks found");
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error showing PIP menu activity", e);
+        }
+    }
+
+    /**
+     * Hides the menu activity.
+     */
+    public void hideMenu() {
+        if (mToActivityMessenger != null) {
+            Message m = Message.obtain();
+            m.what = PipMenuActivity.MESSAGE_FINISH_SELF;
+            try {
+                mToActivityMessenger.send(m);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Could not notify menu activity to finish", e);
+            }
+            mToActivityMessenger = null;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 7aa9aa5..a359380 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -17,25 +17,27 @@
 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 static com.android.systemui.recents.misc.Utilities.RECT_EVALUATOR;
 
 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.content.res.Configuration;
-import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.os.Handler;
 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;
@@ -43,51 +45,77 @@
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.ViewConfiguration;
-import android.view.animation.Interpolator;
-import android.widget.Scroller;
 
 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 {
+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 String TUNER_KEY_TAP_THROUGH = "pip_tap_through";
+    private static final String TUNER_KEY_SNAP_MODE_EDGE = "pip_snap_mode_edge";
+
     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 static final float SCROLL_FRICTION_MULTIPLIER = 8f;
-
     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 final PipMenuListener mMenuListener = new PipMenuListener();
+    private IPinnedStackController mPinnedStackController;
 
-    private final PipInputEventReceiver mInputEventReceiver;
-    private final PipDismissViewController mDismissViewController;
+    private PipInputEventReceiver mInputEventReceiver;
+    private PipMenuActivityController mMenuController;
+    private PipDismissViewController mDismissViewController;
+    private final PipSnapAlgorithm mSnapAlgorithm;
+    private PipMotionHelper mMotionHelper;
+
+    private boolean mEnableSwipeToDismiss = true;
+    private boolean mEnableDragToDismiss = true;
+    private boolean mEnableTapThrough = false;
+    private boolean mEnableSnapToEdge = false;
 
     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 boolean mIsTappingThrough;
     private int mActivePointerId;
 
     private final FlingAnimationUtils mFlingAnimationUtils;
-    private final Scroller mScroller;
     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);
         }
@@ -99,7 +127,7 @@
                 // To be implemented for input handling over Pip windows
                 if (event instanceof MotionEvent) {
                     MotionEvent ev = (MotionEvent) event;
-                    handleTouchEvent(ev);
+                    handled = handleTouchEvent(ev);
                 }
             } finally {
                 finishInputEvent(event, handled);
@@ -107,27 +135,104 @@
         }
     }
 
-    public PipTouchHandler(Context context, IActivityManager activityManager,
-            IWindowManager windowManager) {
+    /**
+     * 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
+        }
+    }
+
+    /**
+     * A listener for the PIP menu activity.
+     */
+    private class PipMenuListener implements PipMenuActivityController.Listener {
+        @Override
+        public void onPipMenuVisibilityChanged(boolean visible) {
+            if (!visible) {
+                mIsTappingThrough = false;
+                registerInputConsumer();
+            } else {
+                unregisterInputConsumer();
+            }
+        }
+    }
+
+    public PipTouchHandler(Context context, PipMenuActivityController menuController,
+            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());
+        mMenuController = menuController;
+        mMenuController.addListener(mMenuListener);
         mDismissViewController = new PipDismissViewController(context);
-        mScroller = new Scroller(context);
-        mScroller.setFriction(mViewConfig.getScrollFriction() * SCROLL_FRICTION_MULTIPLIER);
+        mSnapAlgorithm = new PipSnapAlgorithm(mContext);
         mFlingAnimationUtils = new FlingAnimationUtils(context, 2f);
+        mMotionHelper = new PipMotionHelper(BackgroundThread.getHandler());
+        registerInputConsumer();
+
+        // Register any tuner settings changes
+        TunerService.get(context).addTunable(this, TUNER_KEY_SWIPE_TO_DISMISS,
+            TUNER_KEY_DRAG_TO_DISMISS, TUNER_KEY_TAP_THROUGH, TUNER_KEY_SNAP_MODE_EDGE);
     }
 
-    private void handleTouchEvent(MotionEvent ev) {
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        if (newValue == null) {
+            // Reset back to default
+            mEnableSwipeToDismiss = true;
+            mEnableDragToDismiss = true;
+            mEnableTapThrough = false;
+            mIsTappingThrough = false;
+            mEnableSnapToEdge = false;
+            setSnapToEdge(false);
+            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;
+            case TUNER_KEY_TAP_THROUGH:
+                mEnableTapThrough = Integer.parseInt(newValue) != 0;
+                mIsTappingThrough = false;
+                break;
+            case TUNER_KEY_SNAP_MODE_EDGE:
+                mEnableSnapToEdge = Integer.parseInt(newValue) != 0;
+                setSnapToEdge(mEnableSnapToEdge);
+                break;
+        }
+    }
+
+    public void onConfigurationChanged() {
+        mSnapAlgorithm.onConfigurationChanged();
+        updateBoundedPinnedStackBounds(false /* updatePinnedStackBounds */);
+    }
+
+    private boolean handleTouchEvent(MotionEvent ev) {
+        // Skip touch handling until we are bound to the controller
+        if (mPinnedStackController == null) {
+            return true;
+        }
+
         switch (ev.getAction()) {
             case MotionEvent.ACTION_DOWN: {
                 // Cancel any existing animations on the pinned stack
@@ -135,16 +240,23 @@
                     mPinnedStackBoundsAnimator.cancel();
                 }
 
-                updateBoundedPinnedStackBounds();
+                updateBoundedPinnedStackBounds(true /* updatePinnedStackBounds */);
                 initOrResetVelocityTracker();
                 mVelocityTracker.addMovement(ev);
                 mActivePointerId = ev.getPointerId(0);
                 mLastTouch.set(ev.getX(), ev.getY());
                 mDownTouch.set(mLastTouch);
                 mIsDragging = false;
-                // 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();
+                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: {
@@ -152,29 +264,53 @@
                 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 - ev.getX(activePointerIndex),
-                            mDownTouch.y - ev.getY(activePointerIndex));
+                    float movement = PointF.length(mDownTouch.x - x, mDownTouch.y - y);
                     if (movement > mViewConfig.getScaledTouchSlop()) {
                         mIsDragging = true;
-                        mDismissViewController.showDismissTarget();
+                        mIsTappingThrough = false;
+                        mMenuController.hideMenu();
+                        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 (mIsDragging) {
-                    // Move the pinned stack
-                    float dx = ev.getX(activePointerIndex) - mLastTouch.x;
-                    float dy = ev.getY(activePointerIndex) - mLastTouch.y;
-                    float left = Math.max(mBoundedPinnedStackBounds.left, Math.min(
-                            mBoundedPinnedStackBounds.right, mPinnedStackBounds.left + dx));
-                    float top = Math.max(mBoundedPinnedStackBounds.top, Math.min(
-                            mBoundedPinnedStackBounds.bottom, mPinnedStackBounds.top + dy));
-                    if (DEBUG_ALLOW_OUT_OF_BOUNDS_STACK) {
-                        left = mPinnedStackBounds.left + dx;
-                        top = mPinnedStackBounds.top + dy;
+                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);
                     }
-                    movePinnedStack(left, top);
+                } 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;
@@ -196,39 +332,67 @@
             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 (mIsDragging) {
-                    mVelocityTracker.computeCurrentVelocity(1000,
-                            ViewConfiguration.get(mContext).getScaledMaximumFlingVelocity());
-                    float velocityX = mVelocityTracker.getXVelocity();
-                    float velocityY = mVelocityTracker.getYVelocity();
-                    float velocity = PointF.length(velocityX, velocityY);
+                // Update the movement bounds again if the state has changed since the user started
+                // dragging (ie. when the IME shows)
+                updateBoundedPinnedStackBounds(false /* updatePinnedStackBounds */);
+
+                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 = mDismissViewController.getDismissBounds();
-                        if (dismissBounds.contains(x, y)) {
+                        Rect dismissBounds = mEnableDragToDismiss
+                                ? mDismissViewController.getDismissBounds()
+                                : null;
+                        if (dismissBounds != null && dismissBounds.contains(x, y)) {
                             animateDismissPinnedStack(dismissBounds);
                         } else {
-                            animateToSnapTarget();
+                            animateToClosestSnapTarget();
                         }
                     }
                 } else {
-                    expandPinnedStackToFullscreen();
+                    if (mEnableTapThrough) {
+                        if (!mIsTappingThrough) {
+                            mMenuController.showMenu();
+                            mIsTappingThrough = true;
+                        }
+                    } else {
+                        expandPinnedStackToFullscreen();
+                    }
                 }
-                mDismissViewController.destroyDismissTarget();
+                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;
             }
         }
+        return !mIsTappingThrough;
     }
 
     private void initOrResetVelocityTracker() {
@@ -247,19 +411,52 @@
     }
 
     /**
-     * Creates an animation that continues the fling to a snap target.
+     * Registers the input consumer.
+     */
+    private void registerInputConsumer() {
+        final InputChannel inputChannel = new InputChannel();
+        try {
+            mWindowManager.destroyInputConsumer(INPUT_CONSUMER_PIP);
+            mWindowManager.createInputConsumer(INPUT_CONSUMER_PIP, inputChannel);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to create PIP input consumer", e);
+        }
+        mInputEventReceiver = new PipInputEventReceiver(inputChannel, Looper.myLooper());
+    }
+
+    /**
+     * Unregisters the input consumer.
+     */
+    private void unregisterInputConsumer() {
+        try {
+            mWindowManager.destroyInputConsumer(INPUT_CONSUMER_PIP);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to destroy PIP input consumer", e);
+        }
+        mInputEventReceiver.dispose();
+    }
+
+    /**
+     * Sets the snap-to-edge state.
+     */
+    private void setSnapToEdge(boolean snapToEdge) {
+        mSnapAlgorithm.setSnapToEdge(snapToEdge);
+        try {
+            mPinnedStackController.setSnapToEdge(snapToEdge);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Could not set snap mode to edge", e);
+        }
+    }
+
+    /**
+     * Flings the PIP to the closest snap target.
      */
     private void flingToSnapTarget(float velocity, float velocityX, float velocityY) {
-        mScroller.fling(mPinnedStackBounds.left, mPinnedStackBounds.top,
-            (int) velocityX, (int) velocityY,
-            mBoundedPinnedStackBounds.left, mBoundedPinnedStackBounds.right,
-            mBoundedPinnedStackBounds.top, mBoundedPinnedStackBounds.bottom);
-        Rect toBounds = findClosestBoundedPinnedStackSnapTarget(
-            mScroller.getFinalX(), mScroller.getFinalY());
-        mScroller.abortAnimation();
+        Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(mBoundedPinnedStackBounds,
+                mPinnedStackBounds, velocityX, velocityY);
         if (!mPinnedStackBounds.equals(toBounds)) {
-            mPinnedStackBoundsAnimator = createResizePinnedStackAnimation(
-                toBounds, 0, FAST_OUT_SLOW_IN);
+            mPinnedStackBoundsAnimator = mMotionHelper.createAnimationToBounds(mPinnedStackBounds,
+                toBounds, 0, FAST_OUT_SLOW_IN, mUpdatePinnedStackBoundsListener);
             mFlingAnimationUtils.apply(mPinnedStackBoundsAnimator, 0,
                 distanceBetweenRectOffsets(mPinnedStackBounds, toBounds),
                 velocity);
@@ -268,28 +465,59 @@
     }
 
     /**
-     * Animates the pinned stack to the closest snap target.
+     * Animates the PIP to the closest snap target.
      */
-    private void animateToSnapTarget() {
-        Rect toBounds = findClosestBoundedPinnedStackSnapTarget(
-            mPinnedStackBounds.left, mPinnedStackBounds.top);
+    private void animateToClosestSnapTarget() {
+        Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(mBoundedPinnedStackBounds,
+                mPinnedStackBounds);
         if (!mPinnedStackBounds.equals(toBounds)) {
-            mPinnedStackBoundsAnimator = createResizePinnedStackAnimation(
-                toBounds, SNAP_STACK_DURATION, FAST_OUT_SLOW_IN);
+            mPinnedStackBoundsAnimator = mMotionHelper.createAnimationToBounds(mPinnedStackBounds,
+                toBounds, SNAP_STACK_DURATION, FAST_OUT_SLOW_IN, mUpdatePinnedStackBoundsListener);
             mPinnedStackBoundsAnimator.start();
         }
     }
 
     /**
-     * Animates the dismissal of the pinned stack into the given bounds.
+     * 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 = createResizePinnedStackAnimation(
-            toBounds, DISMISS_STACK_DURATION, FAST_OUT_LINEAR_IN);
+        mPinnedStackBoundsAnimator = mMotionHelper.createAnimationToBounds(mPinnedStackBounds,
+            toBounds, DISMISS_STACK_DURATION, FAST_OUT_LINEAR_IN, mUpdatePinnedStackBoundsListener);
         mPinnedStackBoundsAnimator.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
@@ -323,115 +551,22 @@
     /**
      * Updates the movement bounds of the pinned stack.
      */
-    private void updateBoundedPinnedStackBounds() {
+    private void updateBoundedPinnedStackBounds(boolean updatePinnedStackBounds) {
         try {
             StackInfo info = mActivityManager.getStackInfo(PINNED_STACK_ID);
-            mPinnedStackBounds.set(info.bounds);
-            mBoundedPinnedStackBounds.set(mActivityManager.getPictureInPictureMovementBounds());
+            if (info != null) {
+                if (updatePinnedStackBounds) {
+                    mPinnedStackBounds.set(info.bounds);
+                }
+                mBoundedPinnedStackBounds.set(mWindowManager.getPictureInPictureMovementBounds(
+                        info.displayId));
+            }
         } catch (RemoteException e) {
             Log.e(TAG, "Could not fetch PIP movement bounds.", e);
         }
     }
 
     /**
-     * Moves the pinned stack to the given {@param left} and {@param top} offsets.
-     */
-    private void movePinnedStack(float left, float top) {
-        if ((int) left != mPinnedStackBounds.left || (int) top != mPinnedStackBounds.top) {
-            mPinnedStackBounds.offsetTo((int) left, (int) top);
-            BackgroundThread.getHandler().post(() -> {
-                try {
-                    mActivityManager.resizePinnedStack(mPinnedStackBounds,
-                            null /* tempPinnedBounds */);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Could not move pinned stack to offset: (" + left + ", " + top + ")",
-                            e);
-                }
-            });
-        }
-    }
-
-    /**
-     * Resizes the pinned stack to the given {@param bounds}.
-     */
-    private void resizePinnedStack(Rect bounds) {
-        if (!mPinnedStackBounds.equals(bounds)) {
-            mPinnedStackBounds.set(bounds);
-            BackgroundThread.getHandler().post(() -> {
-                try {
-                    mActivityManager.resizePinnedStack(bounds, null);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Could not resize pinned stack to bounds: (" + bounds + ")");
-                }
-            });
-        }
-    }
-
-    /**
-     * Creates a resize-stack animation.
-     */
-    private ValueAnimator createResizePinnedStackAnimation(Rect toBounds, int duration,
-            Interpolator interpolator) {
-        ValueAnimator anim = ValueAnimator.ofObject(RECT_EVALUATOR,
-                mPinnedStackBounds, toBounds);
-        anim.setDuration(duration);
-        anim.setInterpolator(interpolator);
-        anim.addUpdateListener(
-                new ValueAnimator.AnimatorUpdateListener() {
-                    @Override
-                    public void onAnimationUpdate(ValueAnimator animation) {
-                        resizePinnedStack((Rect) animation.getAnimatedValue());
-                    }
-                });
-        return anim;
-    }
-
-    /**
-     * @return the closest absolute bounded stack left/top to the given {@param x} and {@param y}.
-     */
-    private Rect findClosestBoundedPinnedStackSnapTarget(int x, int y) {
-        Point[] snapTargets;
-        int orientation = mContext.getResources().getConfiguration().orientation;
-        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
-            snapTargets = new Point[] {
-                new Point(mBoundedPinnedStackBounds.left, mBoundedPinnedStackBounds.top),
-                new Point(mBoundedPinnedStackBounds.right, mBoundedPinnedStackBounds.top),
-                new Point(mBoundedPinnedStackBounds.left, mBoundedPinnedStackBounds.bottom),
-                new Point(mBoundedPinnedStackBounds.right, mBoundedPinnedStackBounds.bottom)
-            };
-        } else {
-            snapTargets = new Point[] {
-                new Point(mBoundedPinnedStackBounds.left, mBoundedPinnedStackBounds.top),
-                new Point(mBoundedPinnedStackBounds.right, mBoundedPinnedStackBounds.top),
-                new Point(mBoundedPinnedStackBounds.left, mBoundedPinnedStackBounds.bottom),
-                new Point(mBoundedPinnedStackBounds.right, mBoundedPinnedStackBounds.bottom)
-            };
-        }
-
-        Point closestSnapTarget = null;
-        float minDistance = Float.MAX_VALUE;
-        for (Point p : snapTargets) {
-            float distance = distanceToPoint(p, x, y);
-            if (distance < minDistance) {
-                closestSnapTarget = p;
-                minDistance = distance;
-            }
-        }
-
-        Rect toBounds = new Rect(mPinnedStackBounds);
-        toBounds.offsetTo(closestSnapTarget.x, closestSnapTarget.y);
-        return toBounds;
-    }
-
-    /**
-     * @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);
-    }
-
-
-    /**
      * @return the distance between points {@param p1} and {@param p2}.
      */
     private float distanceBetweenRectOffsets(Rect r1, Rect r2) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 5ee825c..5b93aa2 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -34,10 +34,14 @@
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.SystemProperties;
+import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
+import android.view.Display;
 import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
+
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -54,7 +58,7 @@
  */
 public class PipManager {
     private static final String TAG = "PipManager";
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     private static final boolean DEBUG_FORCE_ONBOARDING =
             SystemProperties.getBoolean("debug.tv.pip_force_onboarding", false);
 
@@ -134,6 +138,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();
@@ -204,6 +209,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);
@@ -220,7 +226,8 @@
     private void loadConfigurationsAndApply() {
         Resources res = mContext.getResources();
         try {
-            mDefaultPipBounds = mActivityManager.getDefaultPictureInPictureBounds();
+            mDefaultPipBounds = mWindowManager.getPictureInPictureDefaultBounds(
+                    Display.DEFAULT_DISPLAY);
         } catch (RemoteException e) {
             Log.e(TAG, "Failed to get default PIP bounds", e);
         }
@@ -582,6 +589,10 @@
     private TaskStackListener mTaskStackListener = new TaskStackListener() {
         @Override
         public void onTaskStackChanged() {
+            if (DEBUG) Log.d(TAG, "onTaskStackChanged()");
+            if (!checkCurrentUserId()) {
+                return;
+            }
             if (mState != STATE_NO_PIP) {
                 boolean hasPip = false;
 
@@ -616,6 +627,9 @@
         @Override
         public void onActivityPinned() {
             if (DEBUG) Log.d(TAG, "onActivityPinned()");
+            if (!checkCurrentUserId()) {
+                return;
+            }
             StackInfo stackInfo = getPinnedStackInfo();
             if (stackInfo == null) {
                 Log.w(TAG, "Cannot find pinned stack");
@@ -646,6 +660,9 @@
         @Override
         public void onPinnedActivityRestartAttempt() {
             if (DEBUG) Log.d(TAG, "onPinnedActivityRestartAttempt()");
+            if (!checkCurrentUserId()) {
+                return;
+            }
             // If PIPed activity is launched again by Launcher or intent, make it fullscreen.
             movePipToFullscreen();
         }
@@ -653,6 +670,9 @@
         @Override
         public void onPinnedStackAnimationEnded() {
             if (DEBUG) Log.d(TAG, "onPinnedStackAnimationEnded()");
+            if (!checkCurrentUserId()) {
+                return;
+            }
             switch (mState) {
                 case STATE_PIP_OVERLAY:
                     if (!mPipRecentsOverlayManager.isRecentsShown()) {
@@ -673,6 +693,26 @@
                     break;
             }
         }
+
+        // {@link android.app.ITaskStackListener} isn't multi-user aware.
+        // Check the current uid and current SystemUI's running uid
+        // so we can handle the PIP status change only once.
+        private boolean checkCurrentUserId() {
+            try {
+                int processUserId = UserHandle.myUserId();
+                int currentUserId = mActivityManager.getCurrentUser().id;
+                if (processUserId != currentUserId) {
+                    if (DEBUG) {
+                        Log.d(TAG, "UID mismatch. SystemUI is running uid=" + processUserId
+                            + " and the current user is uid=" + currentUserId);
+                    }
+                    return false;
+                }
+            } catch (RemoteException e) {
+                Log.w(TAG, "Unable to get current user.");
+            }
+            return true;
+        }
     };
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 484e008..dc68112 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -44,6 +44,9 @@
 import com.android.systemui.statusbar.phone.QSTileHost;
 import libcore.util.Objects;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
+
 public class CustomTile extends QSTile<QSTile.State> implements TileChangeListener {
     public static final String PREFIX = "custom(";
 
@@ -171,7 +174,7 @@
         mIsShowingDialog = false;
         try {
             if (DEBUG) Log.d(TAG, "Removing token");
-            mWindowManager.removeWindowToken(mToken);
+            mWindowManager.removeWindowToken(mToken, DEFAULT_DISPLAY);
         } catch (RemoteException e) {
         }
     }
@@ -193,7 +196,7 @@
                 if (mIsTokenGranted && !mIsShowingDialog) {
                     try {
                         if (DEBUG) Log.d(TAG, "Removing token");
-                        mWindowManager.removeWindowToken(mToken);
+                        mWindowManager.removeWindowToken(mToken, DEFAULT_DISPLAY);
                     } catch (RemoteException e) {
                     }
                     mIsTokenGranted = false;
@@ -212,7 +215,7 @@
         if (mIsTokenGranted) {
             try {
                 if (DEBUG) Log.d(TAG, "Removing token");
-                mWindowManager.removeWindowToken(mToken);
+                mWindowManager.removeWindowToken(mToken, DEFAULT_DISPLAY);
             } catch (RemoteException e) {
             }
         }
@@ -252,7 +255,7 @@
         }
         try {
             if (DEBUG) Log.d(TAG, "Adding token");
-            mWindowManager.addWindowToken(mToken, WindowManager.LayoutParams.TYPE_QS_DIALOG);
+            mWindowManager.addWindowToken(mToken, TYPE_QS_DIALOG, DEFAULT_DISPLAY);
             mIsTokenGranted = true;
         } catch (RemoteException e) {
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 3c245b4..27fcf2a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -61,6 +61,8 @@
 import com.android.systemui.stackdivider.Divider;
 
 import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
 
 
 /**
@@ -77,6 +79,12 @@
     public final static int BIND_TO_SYSTEM_USER_RETRY_DELAY = 5000;
     public final static int RECENTS_GROW_TARGET_INVALID = -1;
 
+    public final static Set<String> RECENTS_ACTIVITIES = new HashSet<>();
+    static {
+        RECENTS_ACTIVITIES.add(RecentsImpl.RECENTS_ACTIVITY);
+        RECENTS_ACTIVITIES.add(RecentsTvImpl.RECENTS_TV_ACTIVITY);
+    }
+
     // Purely for experimentation
     private final static String RECENTS_OVERRIDE_SYSPROP_KEY = "persist.recents_override_pkg";
     private final static String ACTION_SHOW_RECENTS = "com.android.systemui.recents.ACTION_SHOW";
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 64ef997..abde44e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -181,10 +181,7 @@
         ssp.registerTaskStackListener(mTaskStackListener);
 
         // Initialize the static configuration resources
-        LayoutInflater inflater = LayoutInflater.from(mContext);
         mDummyStackView = new TaskStackView(mContext);
-        mHeaderBar = (TaskViewHeader) inflater.inflate(R.layout.recents_task_view_header,
-                null, false);
         reloadResources();
     }
 
@@ -205,14 +202,6 @@
         Resources res = mContext.getResources();
         reloadResources();
         mDummyStackView.reloadOnConfigurationChange();
-        // Update the header bar direction directly as it is not attached to anything and does not
-        // layout except in updateHeaderBarLayout()
-        mHeaderBar.setLayoutDirection(res.getConfiguration().getLayoutDirection());
-        mHeaderBar.onConfigurationChanged();
-        mHeaderBar.forceLayout();
-        mHeaderBar.measure(
-                MeasureSpec.makeMeasureSpec(mHeaderBar.getMeasuredWidth(), MeasureSpec.EXACTLY),
-                MeasureSpec.makeMeasureSpec(mHeaderBar.getMeasuredHeight(), MeasureSpec.EXACTLY));
     }
 
     /**
@@ -586,6 +575,11 @@
                 R.dimen.recents_task_view_header_height_tablet_land,
                 R.dimen.recents_task_view_header_height,
                 R.dimen.recents_task_view_header_height_tablet_land);
+
+        LayoutInflater inflater = LayoutInflater.from(mContext);
+        mHeaderBar = (TaskViewHeader) inflater.inflate(R.layout.recents_task_view_header,
+                null, false);
+        mHeaderBar.setLayoutDirection(res.getConfiguration().getLayoutDirection());
     }
 
     /**
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 d5218ed..11a4f64 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -81,6 +81,7 @@
 import com.android.systemui.R;
 import com.android.systemui.pip.tv.PipMenuActivity;
 import com.android.systemui.pip.tv.PipOnboardingActivity;
+import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.RecentsImpl;
 import com.android.systemui.recents.model.Task;
@@ -160,7 +161,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);
@@ -416,8 +417,7 @@
             }
             return (homeStackVisibleNotOccluded && topActivity != null
                     && topActivity.getPackageName().equals(RecentsImpl.RECENTS_PACKAGE)
-                    && (topActivity.getClassName().equals(RecentsImpl.RECENTS_ACTIVITY)
-                        || topActivity.getClassName().equals(RecentsTvImpl.RECENTS_TV_ACTIVITY)));
+                    && Recents.RECENTS_ACTIVITIES.contains(topActivity.getClassName()));
         } catch (RemoteException e) {
             e.printStackTrace();
         }
@@ -659,11 +659,9 @@
      * Sends a message to close other system windows.
      */
     public void sendCloseSystemWindows(String reason) {
-        if (ActivityManagerNative.isSystemReady()) {
-            try {
-                mIam.closeSystemDialogs(reason);
-            } catch (RemoteException e) {
-            }
+        try {
+            mIam.closeSystemDialogs(reason);
+        } catch (RemoteException e) {
         }
     }
 
@@ -1018,7 +1016,8 @@
         if (mIam == null) return;
 
         try {
-            mIam.startInPlaceAnimationOnFrontMostApplication(opts);
+            mIam.startInPlaceAnimationOnFrontMostApplication(
+                    opts == null ? null : opts.toBundle());
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -1084,7 +1083,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/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/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index fce7f9d..571c0f6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -344,19 +344,6 @@
         mContext = context;
         mCb = cb;
         mFreeformLayoutAlgorithm = new FreeformWorkspaceLayoutAlgorithm(context);
-        mMinMargin = res.getDimensionPixelSize(R.dimen.recents_layout_min_margin);
-        mBaseTopMargin = getDimensionForDevice(context,
-                R.dimen.recents_layout_top_margin_phone,
-                R.dimen.recents_layout_top_margin_tablet,
-                R.dimen.recents_layout_top_margin_tablet_xlarge);
-        mBaseSideMargin = getDimensionForDevice(context,
-                R.dimen.recents_layout_side_margin_phone,
-                R.dimen.recents_layout_side_margin_tablet,
-                R.dimen.recents_layout_side_margin_tablet_xlarge);
-        mBaseBottomMargin = res.getDimensionPixelSize(R.dimen.recents_layout_bottom_margin);
-        mFreeformStackGap =
-                res.getDimensionPixelSize(R.dimen.recents_freeform_layout_bottom_margin);
-
         reloadOnConfigurationChange(context);
     }
 
@@ -390,6 +377,18 @@
                 R.dimen.recents_layout_initial_bottom_offset_tablet,
                 R.dimen.recents_layout_initial_bottom_offset_tablet);
         mFreeformLayoutAlgorithm.reloadOnConfigurationChange(context);
+        mMinMargin = res.getDimensionPixelSize(R.dimen.recents_layout_min_margin);
+        mBaseTopMargin = getDimensionForDevice(context,
+                R.dimen.recents_layout_top_margin_phone,
+                R.dimen.recents_layout_top_margin_tablet,
+                R.dimen.recents_layout_top_margin_tablet_xlarge);
+        mBaseSideMargin = getDimensionForDevice(context,
+                R.dimen.recents_layout_side_margin_phone,
+                R.dimen.recents_layout_side_margin_tablet,
+                R.dimen.recents_layout_side_margin_tablet_xlarge);
+        mBaseBottomMargin = res.getDimensionPixelSize(R.dimen.recents_layout_bottom_margin);
+        mFreeformStackGap =
+                res.getDimensionPixelSize(R.dimen.recents_freeform_layout_bottom_margin);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 4cc7a16..23acb1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -119,8 +119,6 @@
 import java.util.Locale;
 import java.util.Set;
 
-import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_HIGH;
-
 public abstract class BaseStatusBar extends SystemUI implements
         CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener,
         ExpandableNotificationRow.ExpansionLogger, NotificationData.Environment,
@@ -347,17 +345,12 @@
                 dismissKeyguardThenExecute(new OnDismissAction() {
                     @Override
                     public boolean onDismiss() {
-                        if (keyguardShowing && !afterKeyguardGone) {
-                            try {
-                                ActivityManagerNative.getDefault()
-                                        .keyguardWaitingForActivityDrawn();
-                                ActivityManagerNative.getDefault().resumeAppSwitches();
-                            } catch (RemoteException e) {
-                            }
+                        try {
+                            ActivityManagerNative.getDefault().resumeAppSwitches();
+                        } catch (RemoteException e) {
                         }
 
                         boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent);
-                        overrideActivityPendingAppTransition(keyguardShowing && !afterKeyguardGone);
 
                         // close the shade if it was open
                         if (handled) {
@@ -1054,24 +1047,15 @@
     }
 
     private void startNotificationGutsIntent(final Intent intent, final int appUid) {
-        final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
         dismissKeyguardThenExecute(new OnDismissAction() {
             @Override
             public boolean onDismiss() {
                 AsyncTask.execute(new Runnable() {
                     public void run() {
-                        try {
-                            if (keyguardShowing) {
-                                ActivityManagerNative.getDefault()
-                                        .keyguardWaitingForActivityDrawn();
-                            }
-                            TaskStackBuilder.create(mContext)
-                                    .addNextIntentWithParentStack(intent)
-                                    .startActivities(getActivityOptions(),
-                                            new UserHandle(UserHandle.getUserId(appUid)));
-                            overrideActivityPendingAppTransition(keyguardShowing);
-                        } catch (RemoteException e) {
-                        }
+                        TaskStackBuilder.create(mContext)
+                                .addNextIntentWithParentStack(intent)
+                                .startActivities(getActivityOptions(),
+                                        new UserHandle(UserHandle.getUserId(appUid)));
                     }
                 });
                 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
@@ -1336,11 +1320,9 @@
     }
 
     protected void sendCloseSystemWindows(String reason) {
-        if (ActivityManagerNative.isSystemReady()) {
-            try {
-                ActivityManagerNative.getDefault().closeSystemDialogs(reason);
-            } catch (RemoteException e) {
-            }
+        try {
+            ActivityManagerNative.getDefault().closeSystemDialogs(reason);
+        } catch (RemoteException e) {
         }
     }
 
@@ -1834,11 +1816,6 @@
                     @Override
                     public void run() {
                         try {
-                            if (keyguardShowing && !afterKeyguardGone) {
-                                ActivityManagerNative.getDefault()
-                                        .keyguardWaitingForActivityDrawn();
-                            }
-
                             // The intent we are sending is for the application, which
                             // won't have permission to immediately start an activity after
                             // the user switches to home.  We know it is safe to do at this
@@ -1857,8 +1834,6 @@
                         }
                         if (intent.isActivity()) {
                             mAssistManager.hideAssist();
-                            overrideActivityPendingAppTransition(keyguardShowing
-                                    && !afterKeyguardGone);
                         }
                     }
                 }.start();
@@ -1945,11 +1920,6 @@
                         @Override
                         public void run() {
                             try {
-                                if (keyguardShowing && !afterKeyguardGone) {
-                                    ActivityManagerNative.getDefault()
-                                            .keyguardWaitingForActivityDrawn();
-                                }
-
                                 // The intent we are sending is for the application, which
                                 // won't have permission to immediately start an activity after
                                 // the user switches to home.  We know it is safe to do at this
@@ -1995,8 +1965,6 @@
                                 }
                                 if (intent.isActivity()) {
                                     mAssistManager.hideAssist();
-                                    overrideActivityPendingAppTransition(keyguardShowing
-                                            && !afterKeyguardGone);
                                 }
                             }
 
@@ -2067,16 +2035,6 @@
     public void animateCollapsePanels(int flags, boolean force, boolean delayed) {
     }
 
-    public void overrideActivityPendingAppTransition(boolean keyguardShowing) {
-        if (keyguardShowing) {
-            try {
-                mWindowManagerService.overridePendingAppTransition(null, 0, 0, null);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Error overriding app transition: " + e);
-            }
-        }
-    }
-
     protected boolean startWorkChallengeIfNecessary(int userId, IntentSender intendSender,
             String notificationKey) {
         final Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null,
@@ -2578,7 +2536,7 @@
             return false;
         }
 
-        if (mNotificationData.getImportance(sbn.getKey()) < IMPORTANCE_HIGH) {
+        if (mNotificationData.getImportance(sbn.getKey()) < NotificationManager.IMPORTANCE_HIGH) {
             if (DEBUG) Log.d(TAG, "No peeking: unimportant notification: " + sbn.getKey());
             return false;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index bae16f3..7019880 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar;
 
 import android.app.Notification;
+import android.app.NotificationManager;
 import android.content.Context;
 import android.os.SystemClock;
 import android.service.notification.NotificationListenerService;
@@ -186,8 +187,8 @@
         public int compare(Entry a, Entry b) {
             final StatusBarNotification na = a.notification;
             final StatusBarNotification nb = b.notification;
-            int aImportance = Ranking.IMPORTANCE_DEFAULT;
-            int bImportance = Ranking.IMPORTANCE_DEFAULT;
+            int aImportance = NotificationManager.IMPORTANCE_DEFAULT;
+            int bImportance = NotificationManager.IMPORTANCE_DEFAULT;
             int aRank = 0;
             int bRank = 0;
 
@@ -205,13 +206,13 @@
 
             // IMPORTANCE_MIN media streams are allowed to drift to the bottom
             final boolean aMedia = a.key.equals(mediaNotification)
-                    && aImportance > Ranking.IMPORTANCE_MIN;
+                    && aImportance > NotificationManager.IMPORTANCE_MIN;
             final boolean bMedia = b.key.equals(mediaNotification)
-                    && bImportance > Ranking.IMPORTANCE_MIN;
+                    && bImportance > NotificationManager.IMPORTANCE_MIN;
 
-            boolean aSystemMax = aImportance >= Ranking.IMPORTANCE_MAX &&
+            boolean aSystemMax = aImportance >= NotificationManager.IMPORTANCE_HIGH &&
                     isSystemNotification(na);
-            boolean bSystemMax = bImportance >= Ranking.IMPORTANCE_MAX &&
+            boolean bSystemMax = bImportance >= NotificationManager.IMPORTANCE_HIGH &&
                     isSystemNotification(nb);
 
             boolean isHeadsUp = a.row.isHeadsUp();
@@ -318,7 +319,7 @@
             mRankingMap.getRanking(key, mTmpRanking);
             return mTmpRanking.getImportance();
         }
-        return Ranking.IMPORTANCE_UNSPECIFIED;
+        return NotificationManager.IMPORTANCE_UNSPECIFIED;
     }
 
     public String getOverrideGroupKey(String key) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 62d730a..b10fb31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.app.INotificationManager;
+import android.app.NotificationManager;
 import android.content.Context;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -30,7 +31,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationListenerService.Ranking;
 import android.service.notification.StatusBarNotification;
 import android.util.AttributeSet;
 import android.view.View;
@@ -178,7 +178,7 @@
             final Set<String> nonBlockablePkgs, final int importance) {
         mINotificationManager = INotificationManager.Stub.asInterface(
                 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
-        mStartingUserImportance = NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
+        mStartingUserImportance = NotificationManager.IMPORTANCE_UNSPECIFIED;
         try {
             mStartingUserImportance =
                     mINotificationManager.getImportance(sbn.getPackageName(), sbn.getUid());
@@ -229,15 +229,15 @@
             if (mSeekBar.isEnabled()) {
                 return mSeekBar.getProgress();
             } else {
-                return Ranking.IMPORTANCE_UNSPECIFIED;
+                return NotificationManager.IMPORTANCE_UNSPECIFIED;
             }
         } else {
             if (mBlock.isChecked()) {
-                return Ranking.IMPORTANCE_NONE;
+                return NotificationManager.IMPORTANCE_NONE;
             } else if (mSilent.isChecked()) {
-                return Ranking.IMPORTANCE_LOW;
+                return NotificationManager.IMPORTANCE_LOW;
             } else {
-                return Ranking.IMPORTANCE_UNSPECIFIED;
+                return NotificationManager.IMPORTANCE_UNSPECIFIED;
             }
         }
     }
@@ -262,7 +262,7 @@
         }
         mBlock.setText(mContext.getString(R.string.block));
         mSilent.setText(mContext.getString(R.string.show_silently));
-        if (importance == NotificationListenerService.Ranking.IMPORTANCE_LOW) {
+        if (importance == NotificationManager.IMPORTANCE_LOW) {
             mSilent.setChecked(true);
         } else {
             mReset.setChecked(true);
@@ -278,9 +278,9 @@
         mSeekBar = (SeekBar) importanceSlider.findViewById(R.id.seekbar);
 
         final int minProgress = nonBlockable ?
-                NotificationListenerService.Ranking.IMPORTANCE_MIN
-                : NotificationListenerService.Ranking.IMPORTANCE_NONE;
-        mSeekBar.setMax(NotificationListenerService.Ranking.IMPORTANCE_MAX);
+                NotificationManager.IMPORTANCE_MIN
+                : NotificationManager.IMPORTANCE_NONE;
+        mSeekBar.setMax(NotificationManager.IMPORTANCE_HIGH);
         mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
             @Override
             public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
@@ -317,7 +317,7 @@
                 applyAuto();
             }
         });
-        mAuto = mStartingUserImportance == Ranking.IMPORTANCE_UNSPECIFIED;
+        mAuto = mStartingUserImportance == NotificationManager.IMPORTANCE_UNSPECIFIED;
         applyAuto();
     }
 
@@ -344,36 +344,32 @@
 
     private void updateTitleAndSummary(int progress) {
         switch (progress) {
-            case Ranking.IMPORTANCE_NONE:
+            case NotificationManager.IMPORTANCE_NONE:
                 mImportanceSummary.setText(mContext.getString(
                         R.string.notification_importance_blocked));
                 mImportanceTitle.setText(mContext.getString(R.string.blocked_importance));
                 break;
-            case Ranking.IMPORTANCE_MIN:
+            case NotificationManager.IMPORTANCE_MIN:
                 mImportanceSummary.setText(mContext.getString(
                         R.string.notification_importance_min));
                 mImportanceTitle.setText(mContext.getString(R.string.min_importance));
                 break;
-            case Ranking.IMPORTANCE_LOW:
+            case NotificationManager.IMPORTANCE_LOW:
                 mImportanceSummary.setText(mContext.getString(
                         R.string.notification_importance_low));
                 mImportanceTitle.setText(mContext.getString(R.string.low_importance));
                 break;
-            case Ranking.IMPORTANCE_DEFAULT:
+            case NotificationManager.IMPORTANCE_DEFAULT:
                 mImportanceSummary.setText(mContext.getString(
                         R.string.notification_importance_default));
                 mImportanceTitle.setText(mContext.getString(R.string.default_importance));
                 break;
-            case Ranking.IMPORTANCE_HIGH:
+            case NotificationManager.IMPORTANCE_HIGH:
+            case NotificationManager.IMPORTANCE_MAX:
                 mImportanceSummary.setText(mContext.getString(
                         R.string.notification_importance_high));
                 mImportanceTitle.setText(mContext.getString(R.string.high_importance));
                 break;
-            case Ranking.IMPORTANCE_MAX:
-                mImportanceSummary.setText(mContext.getString(
-                        R.string.notification_importance_max));
-                mImportanceTitle.setText(mContext.getString(R.string.max_importance));
-                break;
         }
     }
 
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..01ffe01 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);
+            }
         }
     }
 
@@ -111,6 +123,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 +260,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 +281,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 +291,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/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index f9b7bb5..dfb06d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -496,7 +496,6 @@
                     } catch (RemoteException e) {
                         Log.w(TAG, "Unable to start camera activity", e);
                     }
-                    mActivityStarter.preventNextAnimation();
                     final boolean launched = isSuccessfulLaunch(result);
                     post(new Runnable() {
                         @Override
@@ -539,7 +538,6 @@
             @Override
             public void run() {
                 mAssistManager.launchVoiceAssistFromKeyguard();
-                mActivityStarter.preventNextAnimation();
             }
         };
         if (mPhoneStatusBar.isKeyguardCurrentlySecure()) {
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 798d9df..df167e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -105,7 +105,7 @@
     private boolean mInCarMode = false;
     private boolean mDockedStackExists;
 
-    private final SparseArray<ButtonDispatcher> mButtonDisatchers = new SparseArray<>();
+    private final SparseArray<ButtonDispatcher> mButtonDispatchers = new SparseArray<>();
     private Configuration mConfiguration;
 
     private NavigationBarInflaterView mNavigationInflaterView;
@@ -206,11 +206,11 @@
 
         mBarTransitions = new NavigationBarTransitions(this);
 
-        mButtonDisatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
-        mButtonDisatchers.put(R.id.home, new ButtonDispatcher(R.id.home));
-        mButtonDisatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps));
-        mButtonDisatchers.put(R.id.menu, new ButtonDispatcher(R.id.menu));
-        mButtonDisatchers.put(R.id.ime_switcher, new ButtonDispatcher(R.id.ime_switcher));
+        mButtonDispatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
+        mButtonDispatchers.put(R.id.home, new ButtonDispatcher(R.id.home));
+        mButtonDispatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps));
+        mButtonDispatchers.put(R.id.menu, new ButtonDispatcher(R.id.menu));
+        mButtonDispatchers.put(R.id.ime_switcher, new ButtonDispatcher(R.id.ime_switcher));
     }
 
     public BarTransitions getBarTransitions() {
@@ -262,23 +262,23 @@
     }
 
     public ButtonDispatcher getRecentsButton() {
-        return mButtonDisatchers.get(R.id.recent_apps);
+        return mButtonDispatchers.get(R.id.recent_apps);
     }
 
     public ButtonDispatcher getMenuButton() {
-        return mButtonDisatchers.get(R.id.menu);
+        return mButtonDispatchers.get(R.id.menu);
     }
 
     public ButtonDispatcher getBackButton() {
-        return mButtonDisatchers.get(R.id.back);
+        return mButtonDispatchers.get(R.id.back);
     }
 
     public ButtonDispatcher getHomeButton() {
-        return mButtonDisatchers.get(R.id.home);
+        return mButtonDispatchers.get(R.id.home);
     }
 
     public ButtonDispatcher getImeSwitchButton() {
-        return mButtonDisatchers.get(R.id.ime_switcher);
+        return mButtonDispatchers.get(R.id.ime_switcher);
     }
 
     private void updateCarModeIcons(Context ctx) {
@@ -495,7 +495,7 @@
         mNavigationInflaterView = (NavigationBarInflaterView) findViewById(
                 R.id.navigation_inflater);
         updateRotatedViews();
-        mNavigationInflaterView.setButtonDispatchers(mButtonDisatchers);
+        mNavigationInflaterView.setButtonDispatchers(mButtonDispatchers);
 
         getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
 
@@ -556,8 +556,8 @@
         mCurrentView = mRotatedViews[rot];
         mCurrentView.setVisibility(View.VISIBLE);
         mNavigationInflaterView.setAlternativeOrder(rot == Surface.ROTATION_90);
-        for (int i = 0; i < mButtonDisatchers.size(); i++) {
-            mButtonDisatchers.valueAt(i).setCurrentView(mCurrentView);
+        for (int i = 0; i < mButtonDispatchers.size(); i++) {
+            mButtonDispatchers.valueAt(i).setCurrentView(mCurrentView);
         }
         updateLayoutTransitionsEnabled();
         mCurrentRotation = rot;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 7b35cbd..cda0bfe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1858,6 +1858,7 @@
             mLaunchAnimationEndRunnable.run();
             mLaunchAnimationEndRunnable = null;
         }
+        mStatusBar.readyForKeyguardDone();
     }
 
     @Override
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..669a512 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -37,8 +37,8 @@
 import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.app.IActivityManager;
-import android.app.KeyguardManager;
 import android.app.Notification;
+import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
@@ -50,7 +50,6 @@
 import android.content.IntentSender;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
@@ -123,6 +122,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 +367,7 @@
     // top bar
     BaseStatusBarHeader mHeader;
     protected KeyguardStatusBarView mKeyguardStatusBar;
-    View mKeyguardStatusView;
+    KeyguardStatusView mKeyguardStatusView;
     KeyguardBottomAreaView mKeyguardBottomArea;
     boolean mLeaveOpenOnKeyguardHide;
     KeyguardIndicationController mKeyguardIndicationController;
@@ -846,10 +846,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);
@@ -1560,7 +1561,7 @@
                     Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + notification.getKey());
                 }
             } else if (mNotificationData.getImportance(notification.getKey())
-                    < NotificationListenerService.Ranking.IMPORTANCE_MAX) {
+                    < NotificationManager.IMPORTANCE_HIGH) {
                 if (DEBUG) {
                     Log.d(TAG, "No Fullscreen intent: not important enough: "
                             + notification.getKey());
@@ -2512,11 +2513,6 @@
         startActivityDismissingKeyguard(intent, false, dismissShade, callback);
     }
 
-    @Override
-    public void preventNextAnimation() {
-        overrideActivityPendingAppTransition(true /* keyguardShowing */);
-    }
-
     public void setQsExpanded(boolean expanded) {
         mStatusBarWindowManager.setQsExpanded(expanded);
         mKeyguardStatusView.setImportantForAccessibility(expanded
@@ -2695,6 +2691,10 @@
         mFalsingManager.onScreenOff();
     }
 
+    public boolean isPulsing() {
+        return mDozeScrimController.isPulsing();
+    }
+
     /**
      * All changes to the status bar and notifications funnel through here and are batched.
      */
@@ -2864,7 +2864,7 @@
         for (int i = 0; i < size; i++) {
             clonedList.get(i).run();
         }
-
+        mStatusBarKeyguardViewManager.readyForKeyguardDone();
     }
 
     @Override
@@ -3491,7 +3491,6 @@
 
         final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
                 mContext, intent, mCurrentUserId);
-        final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
         Runnable runnable = new Runnable() {
             @Override
             public void run() {
@@ -3522,8 +3521,6 @@
                 } catch (RemoteException e) {
                     Log.w(TAG, "Unable to start activity", e);
                 }
-                overrideActivityPendingAppTransition(
-                        keyguardShowing && !afterKeyguardGone);
                 if (callback != null) {
                     callback.onActivityStarted(result);
                 }
@@ -3541,36 +3538,24 @@
                 afterKeyguardGone, true /* deferred */);
     }
 
+    public void readyForKeyguardDone() {
+        mStatusBarKeyguardViewManager.readyForKeyguardDone();
+    }
+
     public void executeRunnableDismissingKeyguard(final Runnable runnable,
             final Runnable cancelAction,
             final boolean dismissShade,
             final boolean afterKeyguardGone,
             final boolean deferred) {
-        final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
-        dismissKeyguardThenExecute(new OnDismissAction() {
-            @Override
-            public boolean onDismiss() {
-                AsyncTask.execute(new Runnable() {
-                    @Override
-                    public void run() {
-                        try {
-                            if (keyguardShowing && !afterKeyguardGone) {
-                                ActivityManagerNative.getDefault()
-                                        .keyguardWaitingForActivityDrawn();
-                            }
-                            if (runnable != null) {
-                                runnable.run();
-                            }
-                        } catch (RemoteException e) {
-                        }
-                    }
-                });
-                if (dismissShade) {
-                    animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
-                            true /* delayed*/);
-                }
-                return deferred;
+        dismissKeyguardThenExecute(() -> {
+            if (runnable != null) {
+                AsyncTask.execute(runnable);
             }
+            if (dismissShade) {
+                animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
+                        true /* delayed*/);
+            }
+            return deferred;
         }, cancelAction, afterKeyguardGone);
     }
 
@@ -5135,6 +5120,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/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 77c60fb..f5c5e56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -48,7 +48,7 @@
 public class StatusBarKeyguardViewManager implements RemoteInputController.Callback {
 
     // When hiding the Keyguard with timing supplied from WindowManager, better be early than late.
-    private static final long HIDE_TIMING_CORRECTION_MS = -3 * 16;
+    private static final long HIDE_TIMING_CORRECTION_MS = - 16 * 3;
 
     // Delay for showing the navigation bar when the bouncer appears. This should be kept in sync
     // with the appear animations of the PIN/pattern/password views.
@@ -120,14 +120,14 @@
         mShowing = true;
         mStatusBarWindowManager.setKeyguardShowing(true);
         mScrimController.abortKeyguardFadingOut();
-        reset();
+        reset(true /* hideBouncerWhenShowing */);
     }
 
     /**
      * Shows the notification keyguard or the bouncer depending on
      * {@link KeyguardBouncer#needsFullscreenBouncer()}.
      */
-    protected void showBouncerOrKeyguard() {
+    protected void showBouncerOrKeyguard(boolean hideBouncerWhenShowing) {
         if (mBouncer.needsFullscreenBouncer()) {
 
             // The keyguard might be showing (already). So we need to hide it.
@@ -135,8 +135,10 @@
             mBouncer.show(true /* resetSecuritySelection */);
         } else {
             mPhoneStatusBar.showKeyguard();
-            mBouncer.hide(false /* destroyView */);
-            mBouncer.prepare();
+            if (hideBouncerWhenShowing) {
+                mBouncer.hide(false /* destroyView */);
+                mBouncer.prepare();
+            }
         }
     }
 
@@ -163,14 +165,14 @@
     /**
      * Reset the state of the view.
      */
-    public void reset() {
+    public void reset(boolean hideBouncerWhenShowing) {
         if (mShowing) {
             if (mOccluded) {
                 mPhoneStatusBar.hideKeyguard();
                 mPhoneStatusBar.stopWaitingForKeyguardExit();
                 mBouncer.hide(false /* destroyView */);
             } else {
-                showBouncerOrKeyguard();
+                showBouncerOrKeyguard(hideBouncerWhenShowing);
             }
             KeyguardUpdateMonitor.getInstance(mContext).sendKeyguardReset();
             updateStates();
@@ -257,7 +259,7 @@
                             @Override
                             public void run() {
                                 mStatusBarWindowManager.setKeyguardOccluded(mOccluded);
-                                reset();
+                                reset(true /* hideBouncerWhenShowing */);
                             }
                         });
                 return;
@@ -268,7 +270,10 @@
             mPhoneStatusBar.updateMediaMetaData(false, animate && !occluded);
         }
         mStatusBarWindowManager.setKeyguardOccluded(occluded);
-        reset();
+
+        // If Keyguard is reshown, don't hide the bouncer as it might just have been requested by
+        // a FLAG_DISMISS_KEYGUARD_ACTIVITY.
+        reset(false /* hideBouncerWhenShowing*/);
         if (animate && !occluded && mShowing) {
             mPhoneStatusBar.animateKeyguardUnoccluding();
         }
@@ -391,7 +396,8 @@
                 if (endRunnable != null) {
                     endRunnable.run();
                 }
-                mStatusBarWindowManager.setKeyguardFadingAway(false);
+                mContainer.postDelayed(() -> mStatusBarWindowManager.setKeyguardFadingAway(false),
+                        100);
                 mPhoneStatusBar.finishKeyguardFadingAway();
                 mFingerprintUnlockController.finishKeyguardFadingAway();
                 WindowManagerGlobal.getInstance().trimMemory(
@@ -418,9 +424,7 @@
      * Dismisses the keyguard by going to the next screen or making it gone.
      */
     public void dismiss() {
-        if (mDeviceInteractive || mDeviceWillWakeUp) {
-            showBouncer();
-        }
+        showBouncer();
     }
 
     /**
@@ -445,7 +449,7 @@
     public boolean onBackPressed() {
         if (mBouncer.isShowing()) {
             mPhoneStatusBar.endAffordanceLaunch();
-            reset();
+            reset(true /* hideBouncerWhenShowing */);
             return true;
         }
         return false;
@@ -556,17 +560,8 @@
         return mBouncer.interceptMediaKey(event);
     }
 
-    public void onActivityDrawn() {
-        if (mPhoneStatusBar.isCollapsing()) {
-            mPhoneStatusBar.addPostCollapseAction(new Runnable() {
-                @Override
-                public void run() {
-                    mViewMediatorCallback.readyForKeyguardDone();
-                }
-            });
-        } else {
-            mViewMediatorCallback.readyForKeyguardDone();
-        }
+    public void readyForKeyguardDone() {
+        mViewMediatorCallback.readyForKeyguardDone();
     }
 
     public boolean shouldDisableWindowAnimationsForUnlock() {
@@ -581,10 +576,6 @@
         return mBouncer.isSecure() || mLockPatternUtils.isSecure(userId);
     }
 
-    public boolean isInputRestricted() {
-        return mViewMediatorCallback.isInputRestricted();
-    }
-
     public void keyguardGoingAway() {
         mPhoneStatusBar.keyguardGoingAway();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index a7a792b..4a2d5dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -137,8 +137,7 @@
 
     private void applyFocusableFlag(State state) {
         boolean panelFocusable = state.statusBarFocusable && state.panelExpanded;
-        if (state.keyguardShowing && state.keyguardNeedsInput && state.bouncerShowing
-                || BaseStatusBar.ENABLE_REMOTE_INPUT && state.remoteInputActive) {
+        if (state.bouncerShowing || BaseStatusBar.ENABLE_REMOTE_INPUT && state.remoteInputActive) {
             mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
             mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
         } else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) {
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/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/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/packages/SystemUI/src/com/android/systemui/util/Assert.java
similarity index 60%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to packages/SystemUI/src/com/android/systemui/util/Assert.java
index 5f66d16..af447f3 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/packages/SystemUI/src/com/android/systemui/util/Assert.java
@@ -11,9 +11,21 @@
  * 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.
+ * limitations under the License
  */
 
-package android.net.wifi.nan;
+package com.android.systemui.util;
 
-parcelable PublishConfig;
+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/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 100%
rename from services/core/proto/ipconnectivity.proto
rename to proto/src/ipconnectivity.proto
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index cebde98..48bc27e 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -689,6 +689,7 @@
     ACTION_WIFI_ADD_NETWORK = 134;
 
     // ACTION: Settings > Wi-Fi > [Long press network] > Connect to network
+    //   SUBTYPE: true if connecting to a saved network, false if not
     // CATEGORY: SETTINGS
     // OS: 6.0
     ACTION_WIFI_CONNECT = 135;
@@ -704,6 +705,7 @@
     ACTION_WIFI_FORGET = 137;
 
     // ACTION: Settings > Wi-Fi > Toggle off
+    //   SUBTYPE: true if connected to network before toggle, false if not
     // CATEGORY: SETTINGS
     // OS: 6.0
     ACTION_WIFI_OFF = 138;
@@ -2593,6 +2595,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/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 4819c0a..ab111a0 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -17,6 +17,8 @@
 package com.android.server.accessibility;
 
 import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
 
 import android.Manifest;
 import android.accessibilityservice.AccessibilityService;
@@ -827,9 +829,10 @@
      * @param centerX the new screen-relative center X coordinate
      * @param centerY the new screen-relative center Y coordinate
      */
-    void notifyMagnificationChanged(@NonNull Region region,
+    public void notifyMagnificationChanged(@NonNull Region region,
             float scale, float centerX, float centerY) {
         synchronized (mLock) {
+            notifyClearAccessibilityCacheLocked();
             notifyMagnificationChangedLocked(region, scale, centerX, centerY);
         }
     }
@@ -899,10 +902,6 @@
         mSecurityPolicy.onTouchInteractionEnd();
     }
 
-    void onMagnificationStateChanged() {
-        notifyClearAccessibilityCacheLocked();
-    }
-
     private void switchUser(int userId) {
         synchronized (mLock) {
             if (mCurrentUserId == userId && mInitialized) {
@@ -2928,8 +2927,8 @@
                         sendDownAndUpKeyEvents(KeyEvent.KEYCODE_HOME);
                     } return true;
                     case AccessibilityService.GLOBAL_ACTION_RECENTS: {
-                        openRecents();
-                    } return true;
+                        return openRecents();
+                    }
                     case AccessibilityService.GLOBAL_ACTION_NOTIFICATIONS: {
                         expandNotifications();
                     } return true;
@@ -3129,7 +3128,7 @@
             final long identity = Binder.clearCallingIdentity();
             try {
                 mWindowManagerService.addWindowToken(mOverlayWindowToken,
-                        WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY);
+                        TYPE_ACCESSIBILITY_OVERLAY, DEFAULT_DISPLAY);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -3138,7 +3137,7 @@
         public void onRemoved() {
             final long identity = Binder.clearCallingIdentity();
             try {
-                mWindowManagerService.removeWindowToken(mOverlayWindowToken, true);
+                mWindowManagerService.removeWindowToken(mOverlayWindowToken, true, DEFAULT_DISPLAY);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -3422,14 +3421,19 @@
             Binder.restoreCallingIdentity(token);
         }
 
-        private void openRecents() {
+        private boolean openRecents() {
             final long token = Binder.clearCallingIdentity();
-
-            StatusBarManagerInternal statusBarService = LocalServices.getService(
-                    StatusBarManagerInternal.class);
-            statusBarService.toggleRecentApps();
-
-            Binder.restoreCallingIdentity(token);
+            try {
+                StatusBarManagerInternal statusBarService = LocalServices.getService(
+                        StatusBarManagerInternal.class);
+                if (statusBarService == null) {
+                    return false;
+                }
+                statusBarService.toggleRecentApps();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+            return true;
         }
 
         private void showGlobalActions() {
@@ -3668,7 +3672,7 @@
                     return AccessibilityWindowInfo.TYPE_SPLIT_SCREEN_DIVIDER;
                 }
 
-                case WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY: {
+                case TYPE_ACCESSIBILITY_OVERLAY: {
                     return AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY;
                 }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
index 7886b9e..f65046c 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
@@ -21,8 +21,6 @@
 import com.android.internal.os.SomeArgs;
 import com.android.server.LocalServices;
 
-import android.animation.ObjectAnimator;
-import android.animation.TypeEvaluator;
 import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.content.BroadcastReceiver;
@@ -34,12 +32,10 @@
 import android.graphics.Region;
 import android.os.AsyncTask;
 import android.os.Handler;
-import android.os.Looper;
 import android.os.Message;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.MathUtils;
-import android.util.Property;
 import android.util.Slog;
 import android.view.MagnificationSpec;
 import android.view.View;
@@ -53,27 +49,29 @@
  * from the accessibility manager and related classes. It is responsible for
  * holding the current state of magnification and animation, and it handles
  * communication between the accessibility manager and window manager.
+ *
+ * Magnification is limited to the range [MIN_SCALE, MAX_SCALE], and can only occur inside the
+ * magnification region. If a value is out of bounds, it will be adjusted to guarantee these
+ * constraints.
  */
-class MagnificationController {
+class MagnificationController implements Handler.Callback {
     private static final String LOG_TAG = "MagnificationController";
 
-    private static final boolean DEBUG_SET_MAGNIFICATION_SPEC = false;
+    public static final float MIN_SCALE = 1.0f;
+    public static final float MAX_SCALE = 5.0f;
 
-    private static final int DEFAULT_SCREEN_MAGNIFICATION_AUTO_UPDATE = 1;
+    private static final boolean DEBUG_SET_MAGNIFICATION_SPEC = false;
 
     private static final int INVALID_ID = -1;
 
     private static final float DEFAULT_MAGNIFICATION_SCALE = 2.0f;
 
-    private static final float MIN_SCALE = 1.0f;
-    private static final float MAX_SCALE = 5.0f;
-
-    /**
-     * The minimum scaling factor that can be persisted to secure settings.
-     * This must be > 1.0 to ensure that magnification is actually set to an
-     * enabled state when the scaling factor is restored from settings.
-     */
-    private static final float MIN_PERSISTED_SCALE = 2.0f;
+    // Messages
+    private static final int MSG_SEND_SPEC_TO_ANIMATION = 1;
+    private static final int MSG_SCREEN_TURNED_OFF = 2;
+    private static final int MSG_ON_MAGNIFIED_BOUNDS_CHANGED = 3;
+    private static final int MSG_ON_RECTANGLE_ON_SCREEN_REQUESTED = 4;
+    private static final int MSG_ON_USER_CONTEXT_CHANGED = 5;
 
     private final Object mLock;
 
@@ -90,46 +88,95 @@
     private final Rect mTempRect1 = new Rect();
 
     private final AccessibilityManagerService mAms;
-    private final ContentResolver mContentResolver;
+
+    private final SettingsBridge mSettingsBridge;
 
     private final ScreenStateObserver mScreenStateObserver;
-    private final WindowStateObserver mWindowStateObserver;
 
     private final SpecAnimationBridge mSpecAnimationBridge;
 
+    private final WindowManagerInternal.MagnificationCallbacks mWMCallbacks =
+            new WindowManagerInternal.MagnificationCallbacks () {
+                @Override
+                public void onMagnificationRegionChanged(Region region) {
+                    final SomeArgs args = SomeArgs.obtain();
+                    args.arg1 = Region.obtain(region);
+                    mHandler.obtainMessage(MSG_ON_MAGNIFIED_BOUNDS_CHANGED, args).sendToTarget();
+                }
+
+                @Override
+                public void onRectangleOnScreenRequested(int left, int top, int right, int bottom) {
+                    final SomeArgs args = SomeArgs.obtain();
+                    args.argi1 = left;
+                    args.argi2 = top;
+                    args.argi3 = right;
+                    args.argi4 = bottom;
+                    mHandler.obtainMessage(MSG_ON_RECTANGLE_ON_SCREEN_REQUESTED, args)
+                            .sendToTarget();
+                }
+
+                @Override
+                public void onRotationChanged(int rotation) {
+                    // Treat as context change and reset
+                    mHandler.sendEmptyMessage(MSG_ON_USER_CONTEXT_CHANGED);
+                }
+
+                @Override
+                public void onUserContextChanged() {
+                    mHandler.sendEmptyMessage(MSG_ON_USER_CONTEXT_CHANGED);
+                }
+            };
+
     private int mUserId;
 
+    private final long mMainThreadId;
+
+    private Handler mHandler;
+
     private int mIdOfLastServiceToMagnify = INVALID_ID;
 
+    private final WindowManagerInternal mWindowManager;
+
     // Flag indicating that we are registered with window manager.
     private boolean mRegistered;
 
     private boolean mUnregisterPending;
 
     public MagnificationController(Context context, AccessibilityManagerService ams, Object lock) {
+        this(context, ams, lock, null, LocalServices.getService(WindowManagerInternal.class),
+                new ValueAnimator(), new SettingsBridge(context.getContentResolver()));
+        mHandler = new Handler(context.getMainLooper(), this);
+    }
+
+    public MagnificationController(Context context, AccessibilityManagerService ams, Object lock,
+            Handler handler, WindowManagerInternal windowManagerInternal,
+            ValueAnimator valueAnimator, SettingsBridge settingsBridge) {
+        mHandler = handler;
+        mWindowManager = windowManagerInternal;
+        mMainThreadId = context.getMainLooper().getThread().getId();
         mAms = ams;
-        mContentResolver = context.getContentResolver();
         mScreenStateObserver = new ScreenStateObserver(context, this);
-        mWindowStateObserver = new WindowStateObserver(context, this);
         mLock = lock;
-        mSpecAnimationBridge = new SpecAnimationBridge(context, mLock);
+        mSpecAnimationBridge = new SpecAnimationBridge(
+                context, mLock, mWindowManager, valueAnimator);
+        mSettingsBridge = settingsBridge;
     }
 
     /**
      * Start tracking the magnification region for services that control magnification and the
      * magnification gesture handler.
      *
-     * This tracking imposes a cost on the system, so we avoid tracking this data
-     * unless it's required.
+     * This tracking imposes a cost on the system, so we avoid tracking this data unless it's
+     * required.
      */
     public void register() {
         synchronized (mLock) {
             if (!mRegistered) {
                 mScreenStateObserver.register();
-                mWindowStateObserver.register();
+                mWindowManager.setMagnificationCallbacks(mWMCallbacks);
                 mSpecAnimationBridge.setEnabled(true);
                 // Obtain initial state.
-                mWindowStateObserver.getMagnificationRegion(mMagnificationRegion);
+                mWindowManager.getMagnificationRegion(mMagnificationRegion);
                 mMagnificationRegion.getBounds(mMagnificationBounds);
                 mRegistered = true;
             }
@@ -164,7 +211,7 @@
         if (mRegistered) {
             mSpecAnimationBridge.setEnabled(false);
             mScreenStateObserver.unregister();
-            mWindowStateObserver.unregister();
+            mWindowManager.setMagnificationCallbacks(null);
             mMagnificationRegion.setEmpty();
             mRegistered = false;
         }
@@ -183,40 +230,22 @@
      * Update our copy of the current magnification region
      *
      * @param magnified the magnified region
-     * @param updateSpec {@code true} to update the scale and center based on
-     *                   the region bounds, {@code false} to leave them as-is
      */
-    private void onMagnificationRegionChanged(Region magnified, boolean updateSpec) {
+    private void onMagnificationRegionChanged(Region magnified) {
         synchronized (mLock) {
             if (!mRegistered) {
                 // Don't update if we've unregistered
                 return;
             }
-            boolean magnificationChanged = false;
-            boolean boundsChanged = false;
-
             if (!mMagnificationRegion.equals(magnified)) {
                 mMagnificationRegion.set(magnified);
                 mMagnificationRegion.getBounds(mMagnificationBounds);
-                boundsChanged = true;
-            }
-            if (updateSpec) {
-                final MagnificationSpec sentSpec = mSpecAnimationBridge.mSentMagnificationSpec;
-                final float scale = sentSpec.scale;
-                final float offsetX = sentSpec.offsetX;
-                final float offsetY = sentSpec.offsetY;
-
-                // Compute the new center and update spec as needed.
-                final float centerX = (mMagnificationBounds.width() / 2.0f
-                        + mMagnificationBounds.left - offsetX) / scale;
-                final float centerY = (mMagnificationBounds.height() / 2.0f
-                        + mMagnificationBounds.top - offsetY) / scale;
-                magnificationChanged = setScaleAndCenterLocked(
-                        scale, centerX, centerY, false, INVALID_ID);
-            }
-
-            // If magnification changed we already notified for the change.
-            if (boundsChanged && updateSpec && !magnificationChanged) {
+                // It's possible that our magnification spec is invalid with the new bounds.
+                // Adjust the current spec's offsets if necessary.
+                if (updateCurrentSpecWithOffsetsLocked(
+                        mCurrentMagnificationSpec.offsetX, mCurrentMagnificationSpec.offsetY)) {
+                    sendSpecToAnimation(mCurrentMagnificationSpec, false);
+                }
                 onMagnificationChangedLocked();
             }
         }
@@ -328,7 +357,7 @@
      *
      * @return the scale currently used by the window manager
      */
-    public float getSentScale() {
+    private float getSentScale() {
         return mSpecAnimationBridge.mSentMagnificationSpec.scale;
     }
 
@@ -339,7 +368,7 @@
      *
      * @return the X offset currently used by the window manager
      */
-    public float getSentOffsetX() {
+    private float getSentOffsetX() {
         return mSpecAnimationBridge.mSentMagnificationSpec.offsetX;
     }
 
@@ -350,7 +379,7 @@
      *
      * @return the Y offset currently used by the window manager
      */
-    public float getSentOffsetY() {
+    private float getSentOffsetY() {
         return mSpecAnimationBridge.mSentMagnificationSpec.offsetY;
     }
 
@@ -380,7 +409,7 @@
             onMagnificationChangedLocked();
         }
         mIdOfLastServiceToMagnify = INVALID_ID;
-        mSpecAnimationBridge.updateSentSpec(spec, animate);
+        sendSpecToAnimation(spec, animate);
         return changed;
     }
 
@@ -475,7 +504,7 @@
     private boolean setScaleAndCenterLocked(float scale, float centerX, float centerY,
             boolean animate, int id) {
         final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY);
-        mSpecAnimationBridge.updateSentSpec(mCurrentMagnificationSpec, animate);
+        sendSpecToAnimation(mCurrentMagnificationSpec, animate);
         if (isMagnifying() && (id != INVALID_ID)) {
             mIdOfLastServiceToMagnify = id;
         }
@@ -483,27 +512,28 @@
     }
 
     /**
-     * Offsets the center of the magnified region.
+     * Offsets the magnified region. Note that the offsetX and offsetY values actually move in the
+     * opposite direction as the offsets passed in here.
      *
-     * @param offsetX the amount in pixels to offset the X center
-     * @param offsetY the amount in pixels to offset the Y center
+     * @param offsetX the amount in pixels to offset the region in the X direction, in current
+     * screen pixels.
+     * @param offsetY the amount in pixels to offset the region in the Y direction, in current
+     * screen pixels.
      * @param id the ID of the service requesting the change
      */
-    public void offsetMagnifiedRegionCenter(float offsetX, float offsetY, int id) {
+    public void offsetMagnifiedRegion(float offsetX, float offsetY, int id) {
         synchronized (mLock) {
             if (!mRegistered) {
                 return;
             }
 
-            final MagnificationSpec currSpec = mCurrentMagnificationSpec;
-            final float nonNormOffsetX = currSpec.offsetX - offsetX;
-            currSpec.offsetX = MathUtils.constrain(nonNormOffsetX, getMinOffsetXLocked(), 0);
-            final float nonNormOffsetY = currSpec.offsetY - offsetY;
-            currSpec.offsetY = MathUtils.constrain(nonNormOffsetY, getMinOffsetYLocked(), 0);
+            final float nonNormOffsetX = mCurrentMagnificationSpec.offsetX - offsetX;
+            final float nonNormOffsetY = mCurrentMagnificationSpec.offsetY - offsetY;
+            updateCurrentSpecWithOffsetsLocked(nonNormOffsetX, nonNormOffsetY);
             if (id != INVALID_ID) {
                 mIdOfLastServiceToMagnify = id;
             }
-            mSpecAnimationBridge.updateSentSpec(currSpec, false);
+            sendSpecToAnimation(mCurrentMagnificationSpec, false);
         }
     }
 
@@ -517,7 +547,6 @@
     }
 
     private void onMagnificationChangedLocked() {
-        mAms.onMagnificationStateChanged();
         mAms.notifyMagnificationChanged(mMagnificationRegion,
                 getScale(), getCenterX(), getCenterY());
         if (mUnregisterPending && !isMagnifying()) {
@@ -535,8 +564,7 @@
         new AsyncTask<Void, Void, Void>() {
             @Override
             protected Void doInBackground(Void... params) {
-                Settings.Secure.putFloatForUser(mContentResolver,
-                        Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, scale, userId);
+                mSettingsBridge.putMagnificationScale(scale, userId);
                 return null;
             }
         }.execute();
@@ -550,9 +578,7 @@
      *         scale if none is available
      */
     public float getPersistedScale() {
-        return Settings.Secure.getFloatForUser(mContentResolver,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
-                DEFAULT_MAGNIFICATION_SCALE, mUserId);
+        return mSettingsBridge.getMagnificationScale(mUserId);
     }
 
     /**
@@ -578,36 +604,20 @@
             scale = getScale();
         }
 
-        // Ensure requested center is within the magnification region.
-        if (!magnificationRegionContains(centerX, centerY)) {
-            return false;
-        }
-
         // Compute changes.
-        final MagnificationSpec currSpec = mCurrentMagnificationSpec;
         boolean changed = false;
 
         final float normScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
-        if (Float.compare(currSpec.scale, normScale) != 0) {
-            currSpec.scale = normScale;
+        if (Float.compare(mCurrentMagnificationSpec.scale, normScale) != 0) {
+            mCurrentMagnificationSpec.scale = normScale;
             changed = true;
         }
 
         final float nonNormOffsetX = mMagnificationBounds.width() / 2.0f
-                + mMagnificationBounds.left - centerX * scale;
-        final float offsetX = MathUtils.constrain(nonNormOffsetX, getMinOffsetXLocked(), 0);
-        if (Float.compare(currSpec.offsetX, offsetX) != 0) {
-            currSpec.offsetX = offsetX;
-            changed = true;
-        }
-
+                + mMagnificationBounds.left - centerX * normScale;
         final float nonNormOffsetY = mMagnificationBounds.height() / 2.0f
-                + mMagnificationBounds.top - centerY * scale;
-        final float offsetY = MathUtils.constrain(nonNormOffsetY, getMinOffsetYLocked(), 0);
-        if (Float.compare(currSpec.offsetY, offsetY) != 0) {
-            currSpec.offsetY = offsetY;
-            changed = true;
-        }
+                + mMagnificationBounds.top - centerY * normScale;
+        changed |= updateCurrentSpecWithOffsetsLocked(nonNormOffsetX, nonNormOffsetY);
 
         if (changed) {
             onMagnificationChangedLocked();
@@ -616,6 +626,21 @@
         return changed;
     }
 
+    private boolean updateCurrentSpecWithOffsetsLocked(float nonNormOffsetX, float nonNormOffsetY) {
+        boolean changed = false;
+        final float offsetX = MathUtils.constrain(nonNormOffsetX, getMinOffsetXLocked(), 0);
+        if (Float.compare(mCurrentMagnificationSpec.offsetX, offsetX) != 0) {
+            mCurrentMagnificationSpec.offsetX = offsetX;
+            changed = true;
+        }
+        final float offsetY = MathUtils.constrain(nonNormOffsetY, getMinOffsetYLocked(), 0);
+        if (Float.compare(mCurrentMagnificationSpec.offsetY, offsetY) != 0) {
+            mCurrentMagnificationSpec.offsetY = offsetY;
+            changed = true;
+        }
+        return changed;
+    }
+
     private float getMinOffsetXLocked() {
         final float viewportWidth = mMagnificationBounds.width();
         return viewportWidth - viewportWidth * mCurrentMagnificationSpec.scale;
@@ -643,12 +668,6 @@
         }
     }
 
-    private boolean isScreenMagnificationAutoUpdateEnabled() {
-        return (Settings.Secure.getInt(mContentResolver,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE,
-                DEFAULT_SCREEN_MAGNIFICATION_AUTO_UPDATE) == 1);
-    }
-
     /**
      * Resets magnification if magnification and auto-update are both enabled.
      *
@@ -658,7 +677,7 @@
      */
     boolean resetIfNeeded(boolean animate) {
         synchronized (mLock) {
-            if (isMagnifying() && isScreenMagnificationAutoUpdateEnabled()) {
+            if (isMagnifying()) {
                 reset(animate);
                 return true;
             }
@@ -715,18 +734,61 @@
             }
 
             final float scale = getScale();
-            offsetMagnifiedRegionCenter(scrollX * scale, scrollY * scale, INVALID_ID);
+            offsetMagnifiedRegion(scrollX * scale, scrollY * scale, INVALID_ID);
         }
     }
 
+    private void sendSpecToAnimation(MagnificationSpec spec, boolean animate) {
+        if (Thread.currentThread().getId() == mMainThreadId) {
+            mSpecAnimationBridge.updateSentSpecMainThread(spec, animate);
+        } else {
+            mHandler.obtainMessage(MSG_SEND_SPEC_TO_ANIMATION,
+                    animate ? 1 : 0, 0, spec).sendToTarget();
+        }
+    }
+
+    private void onScreenTurnedOff() {
+        mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
+    }
+
+    public boolean handleMessage(Message msg) {
+        switch (msg.what) {
+            case MSG_SEND_SPEC_TO_ANIMATION:
+                final boolean animate = msg.arg1 == 1;
+                final MagnificationSpec spec = (MagnificationSpec) msg.obj;
+                mSpecAnimationBridge.updateSentSpecMainThread(spec, animate);
+                break;
+            case MSG_SCREEN_TURNED_OFF:
+                resetIfNeeded(false);
+                break;
+            case MSG_ON_MAGNIFIED_BOUNDS_CHANGED: {
+                final SomeArgs args = (SomeArgs) msg.obj;
+                final Region magnifiedBounds = (Region) args.arg1;
+                onMagnificationRegionChanged(magnifiedBounds);
+                magnifiedBounds.recycle();
+                args.recycle();
+            } break;
+            case MSG_ON_RECTANGLE_ON_SCREEN_REQUESTED: {
+                final SomeArgs args = (SomeArgs) msg.obj;
+                final int left = args.argi1;
+                final int top = args.argi2;
+                final int right = args.argi3;
+                final int bottom = args.argi4;
+                requestRectangleOnScreen(left, top, right, bottom);
+                args.recycle();
+            } break;
+            case MSG_ON_USER_CONTEXT_CHANGED:
+                resetIfNeeded(true);
+                break;
+        }
+        return true;
+    }
+
     /**
      * Class responsible for animating spec on the main thread and sending spec
      * updates to the window manager.
      */
-    private static class SpecAnimationBridge {
-        private static final int ACTION_UPDATE_SPEC = 1;
-
-        private final Handler mHandler;
+    private static class SpecAnimationBridge implements ValueAnimator.AnimatorUpdateListener {
         private final WindowManagerInternal mWindowManager;
 
         /**
@@ -735,34 +797,33 @@
          */
         private final MagnificationSpec mSentMagnificationSpec = MagnificationSpec.obtain();
 
-        /**
-         * The animator that updates the sent spec. This should only be accessed
-         * and modified on the main (e.g. animation) thread.
-         */
-        private final ValueAnimator mTransformationAnimator;
+        private final MagnificationSpec mStartMagnificationSpec = MagnificationSpec.obtain();
 
-        private final long mMainThreadId;
+        private final MagnificationSpec mEndMagnificationSpec = MagnificationSpec.obtain();
+
+        private final MagnificationSpec mTmpMagnificationSpec = MagnificationSpec.obtain();
+
+        /**
+         * The animator should only be accessed and modified on the main (e.g. animation) thread.
+         */
+        private final ValueAnimator mValueAnimator;
+
         private final Object mLock;
 
         @GuardedBy("mLock")
         private boolean mEnabled = false;
 
-        private SpecAnimationBridge(Context context, Object lock) {
+        private SpecAnimationBridge(Context context, Object lock, WindowManagerInternal wm,
+                ValueAnimator animator) {
             mLock = lock;
-            final Looper mainLooper = context.getMainLooper();
-            mMainThreadId = mainLooper.getThread().getId();
-
-            mHandler = new UpdateHandler(context);
-            mWindowManager = LocalServices.getService(WindowManagerInternal.class);
-
-            final MagnificationSpecProperty property = new MagnificationSpecProperty();
-            final MagnificationSpecEvaluator evaluator = new MagnificationSpecEvaluator();
+            mWindowManager = wm;
             final long animationDuration = context.getResources().getInteger(
                     R.integer.config_longAnimTime);
-            mTransformationAnimator = ObjectAnimator.ofObject(this, property, evaluator,
-                    mSentMagnificationSpec);
-            mTransformationAnimator.setDuration(animationDuration);
-            mTransformationAnimator.setInterpolator(new DecelerateInterpolator(2.5f));
+            mValueAnimator = animator;
+            mValueAnimator.setDuration(animationDuration);
+            mValueAnimator.setInterpolator(new DecelerateInterpolator(2.5f));
+            mValueAnimator.setFloatValues(0.0f, 1.0f);
+            mValueAnimator.addUpdateListener(this);
         }
 
         /**
@@ -781,22 +842,9 @@
             }
         }
 
-        public void updateSentSpec(MagnificationSpec spec, boolean animate) {
-            if (Thread.currentThread().getId() == mMainThreadId) {
-                // Already on the main thread, don't bother proxying.
-                updateSentSpecInternal(spec, animate);
-            } else {
-                mHandler.obtainMessage(ACTION_UPDATE_SPEC,
-                        animate ? 1 : 0, 0, spec).sendToTarget();
-            }
-        }
-
-        /**
-         * Updates the sent spec.
-         */
-        private void updateSentSpecInternal(MagnificationSpec spec, boolean animate) {
-            if (mTransformationAnimator.isRunning()) {
-                mTransformationAnimator.cancel();
+        public void updateSentSpecMainThread(MagnificationSpec spec, boolean animate) {
+            if (mValueAnimator.isRunning()) {
+                mValueAnimator.cancel();
             }
 
             // If the current and sent specs don't match, update the sent spec.
@@ -812,11 +860,6 @@
             }
         }
 
-        private void animateMagnificationSpecLocked(MagnificationSpec toSpec) {
-            mTransformationAnimator.setObjectValues(mSentMagnificationSpec, toSpec);
-            mTransformationAnimator.start();
-        }
-
         private void setMagnificationSpecLocked(MagnificationSpec spec) {
             if (mEnabled) {
                 if (DEBUG_SET_MAGNIFICATION_SPEC) {
@@ -828,71 +871,40 @@
             }
         }
 
-        private class UpdateHandler extends Handler {
-            public UpdateHandler(Context context) {
-                super(context.getMainLooper());
-            }
-
-            @Override
-            public void handleMessage(Message msg) {
-                switch (msg.what) {
-                    case ACTION_UPDATE_SPEC:
-                        final boolean animate = msg.arg1 == 1;
-                        final MagnificationSpec spec = (MagnificationSpec) msg.obj;
-                        updateSentSpecInternal(spec, animate);
-                        break;
-                }
-            }
+        private void animateMagnificationSpecLocked(MagnificationSpec toSpec) {
+            mEndMagnificationSpec.setTo(toSpec);
+            mStartMagnificationSpec.setTo(mSentMagnificationSpec);
+            mValueAnimator.start();
         }
 
-        private static class MagnificationSpecProperty
-                extends Property<SpecAnimationBridge, MagnificationSpec> {
-            public MagnificationSpecProperty() {
-                super(MagnificationSpec.class, "spec");
-            }
-
-            @Override
-            public MagnificationSpec get(SpecAnimationBridge object) {
-                synchronized (object.mLock) {
-                    return object.mSentMagnificationSpec;
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            synchronized (mLock) {
+                if (mEnabled) {
+                    float fract = animation.getAnimatedFraction();
+                    mTmpMagnificationSpec.scale = mStartMagnificationSpec.scale +
+                            (mEndMagnificationSpec.scale - mStartMagnificationSpec.scale) * fract;
+                    mTmpMagnificationSpec.offsetX = mStartMagnificationSpec.offsetX +
+                            (mEndMagnificationSpec.offsetX - mStartMagnificationSpec.offsetX)
+                                    * fract;
+                    mTmpMagnificationSpec.offsetY = mStartMagnificationSpec.offsetY +
+                            (mEndMagnificationSpec.offsetY - mStartMagnificationSpec.offsetY)
+                                    * fract;
+                    synchronized (mLock) {
+                        setMagnificationSpecLocked(mTmpMagnificationSpec);
+                    }
                 }
             }
-
-            @Override
-            public void set(SpecAnimationBridge object, MagnificationSpec value) {
-                synchronized (object.mLock) {
-                    object.setMagnificationSpecLocked(value);
-                }
-            }
-        }
-
-        private static class MagnificationSpecEvaluator
-                implements TypeEvaluator<MagnificationSpec> {
-            private final MagnificationSpec mTempSpec = MagnificationSpec.obtain();
-
-            @Override
-            public MagnificationSpec evaluate(float fraction, MagnificationSpec fromSpec,
-                    MagnificationSpec toSpec) {
-                final MagnificationSpec result = mTempSpec;
-                result.scale = fromSpec.scale + (toSpec.scale - fromSpec.scale) * fraction;
-                result.offsetX = fromSpec.offsetX + (toSpec.offsetX - fromSpec.offsetX) * fraction;
-                result.offsetY = fromSpec.offsetY + (toSpec.offsetY - fromSpec.offsetY) * fraction;
-                return result;
-            }
         }
     }
 
     private static class ScreenStateObserver extends BroadcastReceiver {
-        private static final int MESSAGE_ON_SCREEN_STATE_CHANGE = 1;
-
         private final Context mContext;
         private final MagnificationController mController;
-        private final Handler mHandler;
 
         public ScreenStateObserver(Context context, MagnificationController controller) {
             mContext = context;
             mController = controller;
-            mHandler = new StateChangeHandler(context);
         }
 
         public void register() {
@@ -905,151 +917,27 @@
 
         @Override
         public void onReceive(Context context, Intent intent) {
-            mHandler.obtainMessage(MESSAGE_ON_SCREEN_STATE_CHANGE,
-                    intent.getAction()).sendToTarget();
-        }
-
-        private void handleOnScreenStateChange() {
-            mController.resetIfNeeded(false);
-        }
-
-        private class StateChangeHandler extends Handler {
-            public StateChangeHandler(Context context) {
-                super(context.getMainLooper());
-            }
-
-            @Override
-            public void handleMessage(Message message) {
-                switch (message.what) {
-                    case MESSAGE_ON_SCREEN_STATE_CHANGE:
-                        handleOnScreenStateChange();
-                        break;
-                }
-            }
+            mController.onScreenTurnedOff();
         }
     }
 
-    /**
-     * This class handles the screen magnification when accessibility is enabled.
-     */
-    private static class WindowStateObserver
-            implements WindowManagerInternal.MagnificationCallbacks {
-        private static final int MESSAGE_ON_MAGNIFIED_BOUNDS_CHANGED = 1;
-        private static final int MESSAGE_ON_RECTANGLE_ON_SCREEN_REQUESTED = 2;
-        private static final int MESSAGE_ON_USER_CONTEXT_CHANGED = 3;
-        private static final int MESSAGE_ON_ROTATION_CHANGED = 4;
+    // Extra class to get settings so tests can mock it
+    public static class SettingsBridge {
+        private final ContentResolver mContentResolver;
 
-        private final MagnificationController mController;
-        private final WindowManagerInternal mWindowManager;
-        private final Handler mHandler;
-
-        private boolean mSpecIsDirty;
-
-        public WindowStateObserver(Context context, MagnificationController controller) {
-            mController = controller;
-            mWindowManager = LocalServices.getService(WindowManagerInternal.class);
-            mHandler = new CallbackHandler(context);
+        public SettingsBridge(ContentResolver contentResolver) {
+            mContentResolver = contentResolver;
         }
 
-        public void register() {
-            mWindowManager.setMagnificationCallbacks(this);
+        public void putMagnificationScale(float value, int userId) {
+            Settings.Secure.putFloatForUser(mContentResolver,
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, value, userId);
         }
 
-        public void unregister() {
-            mWindowManager.setMagnificationCallbacks(null);
-        }
-
-        @Override
-        public void onMagnificationRegionChanged(Region magnificationRegion) {
-            final SomeArgs args = SomeArgs.obtain();
-            args.arg1 = Region.obtain(magnificationRegion);
-            mHandler.obtainMessage(MESSAGE_ON_MAGNIFIED_BOUNDS_CHANGED, args).sendToTarget();
-        }
-
-        private void handleOnMagnifiedBoundsChanged(Region magnificationRegion) {
-            mController.onMagnificationRegionChanged(magnificationRegion, mSpecIsDirty);
-            mSpecIsDirty = false;
-        }
-
-        @Override
-        public void onRectangleOnScreenRequested(int left, int top, int right, int bottom) {
-            final SomeArgs args = SomeArgs.obtain();
-            args.argi1 = left;
-            args.argi2 = top;
-            args.argi3 = right;
-            args.argi4 = bottom;
-            mHandler.obtainMessage(MESSAGE_ON_RECTANGLE_ON_SCREEN_REQUESTED, args).sendToTarget();
-        }
-
-        private void handleOnRectangleOnScreenRequested(int left, int top, int right, int bottom) {
-            mController.requestRectangleOnScreen(left, top, right, bottom);
-        }
-
-        @Override
-        public void onRotationChanged(int rotation) {
-            mHandler.obtainMessage(MESSAGE_ON_ROTATION_CHANGED, rotation, 0).sendToTarget();
-        }
-
-        private void handleOnRotationChanged() {
-            // If there was a rotation and magnification is still enabled,
-            // we'll need to rewrite the spec to reflect the new screen
-            // configuration. Conveniently, we'll receive a callback from
-            // the window manager with updated bounds for the magnified
-            // region.
-            mSpecIsDirty = !mController.resetIfNeeded(true);
-        }
-
-        @Override
-        public void onUserContextChanged() {
-            mHandler.sendEmptyMessage(MESSAGE_ON_USER_CONTEXT_CHANGED);
-        }
-
-        private void handleOnUserContextChanged() {
-            mController.resetIfNeeded(true);
-        }
-
-        /**
-         * This method is used to get the magnification region in the tiny time slice between
-         * registering the callbacks and handling the message.
-         * TODO: Elimiante this extra path, perhaps by processing the message immediately
-         *
-         * @param outMagnificationRegion
-         */
-        public void getMagnificationRegion(@NonNull Region outMagnificationRegion) {
-            mWindowManager.getMagnificationRegion(outMagnificationRegion);
-        }
-
-        private class CallbackHandler extends Handler {
-            public CallbackHandler(Context context) {
-                super(context.getMainLooper());
-            }
-
-            @Override
-            public void handleMessage(Message message) {
-                switch (message.what) {
-                    case MESSAGE_ON_MAGNIFIED_BOUNDS_CHANGED: {
-                        final SomeArgs args = (SomeArgs) message.obj;
-                        final Region magnifiedBounds = (Region) args.arg1;
-                        handleOnMagnifiedBoundsChanged(magnifiedBounds);
-                        magnifiedBounds.recycle();
-                    } break;
-                    case MESSAGE_ON_RECTANGLE_ON_SCREEN_REQUESTED: {
-                        final SomeArgs args = (SomeArgs) message.obj;
-                        final int left = args.argi1;
-                        final int top = args.argi2;
-                        final int right = args.argi3;
-                        final int bottom = args.argi4;
-                        handleOnRectangleOnScreenRequested(left, top, right, bottom);
-                        args.recycle();
-                    } break;
-                    case MESSAGE_ON_USER_CONTEXT_CHANGED: {
-                        handleOnUserContextChanged();
-                    } break;
-                    case MESSAGE_ON_ROTATION_CHANGED: {
-                        handleOnRotationChanged();
-                    } break;
-                }
-            }
+        public float getMagnificationScale(int userId) {
+            return Settings.Secure.getFloatForUser(mContentResolver,
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
+                    DEFAULT_MAGNIFICATION_SCALE, userId);
         }
     }
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
index 39bc809..f6e5340 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
@@ -381,7 +381,7 @@
                 Slog.i(LOG_TAG, "Panned content by scrollX: " + distanceX
                         + " scrollY: " + distanceY);
             }
-            mMagnificationController.offsetMagnifiedRegionCenter(distanceX, distanceY,
+            mMagnificationController.offsetMagnifiedRegion(distanceX, distanceY,
                     AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
             return true;
         }
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/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 20cca16..8e01e9e 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -938,7 +938,7 @@
 
         try {
             ActivityManagerNative.getDefault().registerUidObserver(new UidObserver(),
-                    ActivityManager.UID_OBSERVER_IDLE);
+                    ActivityManager.UID_OBSERVER_IDLE, null);
         } catch (RemoteException e) {
             // ignored; both services live in system_server
         }
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index d2cfb6d..b88a45e 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.app.ActivityManagerInternal;
 import android.database.ContentObserver;
 import android.os.BatteryStats;
 
@@ -148,6 +149,8 @@
 
     private boolean mSentLowBatteryBroadcast = false;
 
+    private ActivityManagerInternal mActivityManagerInternal;
+
     public BatteryService(Context context) {
         super(context);
 
@@ -155,6 +158,7 @@
         mHandler = new Handler(true /*async*/);
         mLed = new Led(context, getLocalService(LightsManager.class));
         mBatteryStats = BatteryStatsService.getService();
+        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
 
         mCriticalBatteryLevel = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
@@ -279,7 +283,7 @@
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    if (ActivityManagerNative.isSystemReady()) {
+                    if (mActivityManagerInternal.isSystemReady()) {
                         Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
                         intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
                         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -298,7 +302,7 @@
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    if (ActivityManagerNative.isSystemReady()) {
+                    if (mActivityManagerInternal.isSystemReady()) {
                         Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
                         intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
                         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
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/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index df1b6f5..2698f95 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -15,6 +15,10 @@
 
 package com.android.server;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import com.android.internal.content.PackageMonitor;
@@ -44,6 +48,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
+import android.app.ActivityManagerInternal;
 import android.app.ActivityManagerNative;
 import android.app.AlertDialog;
 import android.app.AppGlobals;
@@ -111,6 +116,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerInternal;
 import android.view.inputmethod.EditorInfo;
@@ -466,6 +472,7 @@
 
     private AlertDialog.Builder mDialogBuilder;
     private AlertDialog mSwitchingDialog;
+    private IBinder mSwitchingDialogToken = new Binder();
     private View mSwitchingDialogTitleView;
     private Toast mSubtypeSwitchedByShortCutToast;
     private InputMethodInfo[] mIms;
@@ -1481,8 +1488,7 @@
             mCurToken = new Binder();
             try {
                 if (true || DEBUG) Slog.v(TAG, "Adding window token: " + mCurToken);
-                mIWindowManager.addWindowToken(mCurToken,
-                        WindowManager.LayoutParams.TYPE_INPUT_METHOD);
+                mIWindowManager.addWindowToken(mCurToken, TYPE_INPUT_METHOD, DEFAULT_DISPLAY);
             } catch (RemoteException e) {
             }
             return new InputBindResult(null, null, mCurId, mCurSeq,
@@ -1590,7 +1596,7 @@
                     // The current IME is shown. Hence an IME switch (transition) is happening.
                     mWindowManagerInternal.saveLastInputMethodWindowForTransition();
                 }
-                mIWindowManager.removeWindowToken(mCurToken);
+                mIWindowManager.removeWindowToken(mCurToken, DEFAULT_DISPLAY);
             } catch (RemoteException e) {
             }
             mCurToken = null;
@@ -2050,7 +2056,7 @@
             // setSelectedInputMethodAndSubtypeLocked().
             mCurMethodId = id;
 
-            if (ActivityManagerNative.isSystemReady()) {
+            if (LocalServices.getService(ActivityManagerInternal.class).isSystemReady()) {
                 Intent intent = new Intent(Intent.ACTION_INPUT_METHOD_CHANGED);
                 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
                 intent.putExtra("input_method_id", id);
@@ -3287,11 +3293,16 @@
 
             mSwitchingDialog = mDialogBuilder.create();
             mSwitchingDialog.setCanceledOnTouchOutside(true);
-            mSwitchingDialog.getWindow().setType(
-                    WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
-            mSwitchingDialog.getWindow().getAttributes().privateFlags |=
-                    WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-            mSwitchingDialog.getWindow().getAttributes().setTitle("Select input method");
+            final Window w = mSwitchingDialog.getWindow();
+            final WindowManager.LayoutParams attrs = w.getAttributes();
+            w.setType(TYPE_INPUT_METHOD_DIALOG);
+            // Use an alternate token for the dialog for that window manager can group the token
+            // with other IME windows based on type vs. grouping based on whichever token happens
+            // to get selected by the system later on.
+            attrs.token = mSwitchingDialogToken;
+            attrs.privateFlags |= PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+            attrs.setTitle("Select input method");
+            w.setAttributes(attrs);
             updateSystemUi(mCurToken, mImeWindowVis, mBackDisposition);
             mSwitchingDialog.show();
         }
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 0cad814..a2207b2 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -585,6 +585,20 @@
                     Slog.e(TAG, "Unable to remove tied profile key", e);
                 }
             }
+
+            boolean isWatch = mContext.getPackageManager().hasSystemFeature(
+                    PackageManager.FEATURE_WATCH);
+            // Wear used to set DISABLE_LOCKSCREEN to 'true', but because Wear now allows accounts
+            // and device management the lockscreen must be re-enabled now for users that upgrade.
+            if (isWatch && getString("migrated_wear_lockscreen_disabled", null, 0) == null) {
+                final int userCount = users.size();
+                for (int i = 0; i < userCount; i++) {
+                    int id = users.get(i).id;
+                    setBoolean(LockPatternUtils.DISABLE_LOCKSCREEN_KEY, false, id);
+                }
+                setString("migrated_wear_lockscreen_disabled", "true", 0);
+                Slog.i(TAG, "Migrated lockscreen_disabled for Wear devices");
+            }
         } catch (RemoteException re) {
             Slog.e(TAG, "Unable to migrate old data", re);
         }
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index b9a4831..8b7b6a0 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;
@@ -199,6 +201,15 @@
     // Disable this since it messes up long-running cryptfs operations.
     private static final boolean WATCHDOG_ENABLE = false;
 
+    /**
+     * Our goal is for all Android devices to be usable as development devices,
+     * which includes the new Direct Boot mode added in N. For devices that
+     * don't have native FBE support, we offer an emulation mode for developer
+     * testing purposes, but if it's prohibitively difficult to support this
+     * mode, it can be disabled for specific products using this flag.
+     */
+    private static final boolean EMULATE_FBE_SUPPORTED = true;
+
     private static final String TAG = "MountService";
 
     private static final String TAG_STORAGE_BENCHMARK = "storage_benchmark";
@@ -1976,9 +1987,13 @@
         waitForReady();
 
         if ((mask & StorageManager.DEBUG_EMULATE_FBE) != 0) {
+            if (!EMULATE_FBE_SUPPORTED) {
+                throw new IllegalStateException(
+                        "Emulation not supported on this device");
+            }
             if (StorageManager.isFileEncryptedNativeOnly()) {
                 throw new IllegalStateException(
-                        "Emulation not available on device with native FBE");
+                        "Emulation not supported on device with native FBE");
             }
             if (mLockPatternUtils.isCredentialRequiredToDecrypt(false)) {
                 throw new IllegalStateException(
@@ -2535,11 +2550,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 +3753,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 9a638a2..2d6832d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -16,7 +16,11 @@
 
 package com.android.server.am;
 
+import android.annotation.Nullable;
 import android.app.ApplicationThreadConstants;
+import android.app.ContentProviderHolder;
+import android.app.IActivityManager;
+import android.app.WaitResult;
 import android.os.IDeviceIdentifiersPolicyService;
 import android.util.Size;
 import android.util.TypedValue;
@@ -76,10 +80,10 @@
 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;
-import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
 import android.app.ActivityThread;
 import android.app.AlertDialog;
@@ -219,7 +223,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;
@@ -256,6 +259,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;
@@ -279,6 +283,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;
@@ -293,6 +298,7 @@
 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;
@@ -309,7 +315,6 @@
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
@@ -371,13 +376,14 @@
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
+import static com.android.server.wm.AppTransition.TRANSIT_NONE;
 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
 import static org.xmlpull.v1.XmlPullParser.START_TAG;
 
-public final class ActivityManagerService extends ActivityManagerNative
+public class ActivityManagerService extends IActivityManager.Stub
         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
@@ -522,9 +528,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;
@@ -549,12 +552,11 @@
 
     /** Run all ActivityStacks through this */
     final ActivityStackSupervisor mStackSupervisor;
+    private final KeyguardController mKeyguardController;
 
     final ActivityStarter mActivityStarter;
 
-    /** Task stack change listeners. */
-    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
-            new RemoteCallbackList<ITaskStackListener>();
+    final TaskChangeNotificationController mTaskChangeNotificationController;
 
     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
 
@@ -634,7 +636,7 @@
 
     public boolean canShowErrorDialogs() {
         return mShowDialogs && !mSleeping && !mShuttingDown
-                && mLockScreenShown != LOCK_SCREEN_SHOWN;
+                && !mKeyguardController.isKeyguardShowing();
     }
 
     private static final class PriorityState {
@@ -1130,10 +1132,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();
@@ -1252,14 +1255,6 @@
      */
     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
 
-    static final int LOCK_SCREEN_HIDDEN = 0;
-    static final int LOCK_SCREEN_LEAVING = 1;
-    static final int LOCK_SCREEN_SHOWN = 2;
-    /**
-     * State of external call telling us if the lock screen is shown.
-     */
-    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
-
     /**
      * Set if we are shutting down the system, similar to sleeping.
      */
@@ -1393,12 +1388,6 @@
 
     final long[] mTmpLong = new long[2];
 
-    // The size and position information that describes where the pinned stack will go by default.
-    // In particular, the size is defined in DPs.
-    Size mDefaultPinnedStackSizeDp;
-    Size mDefaultPinnedStackScreenEdgeInsetsDp;
-    int mDefaultPinnedStackGravity;
-
     static final class ProcessChangeItem {
         static final int CHANGE_ACTIVITIES = 1<<0;
         static final int CHANGE_PROCESS_STATE = 1<<1;
@@ -1523,29 +1512,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;
@@ -2102,92 +2085,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;
@@ -2319,11 +2216,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) {
@@ -2717,16 +2609,19 @@
 
         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);
+        mKeyguardController = mStackSupervisor.mKeyguardController;
         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);
 
@@ -3101,13 +2996,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);
@@ -3134,7 +3034,7 @@
                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
     }
 
-    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
+    void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
         mHandler.sendMessage(
                 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
     }
@@ -4069,7 +3969,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");
         }
 
@@ -4079,20 +3979,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;
                     }
                 }
             }
@@ -4209,18 +4101,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--;
@@ -4762,23 +4642,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);
         }
     }
 
@@ -5095,12 +4964,17 @@
             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
         }
 
-        if (!restarting && hasVisibleActivities
-                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
-            // If there was nothing to resume, and we are not already restarting this process, but
-            // there is a visible activity that is hosted by the process...  then make sure all
-            // visible activities are running, taking care of restarting this process.
-            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+        mWindowManager.deferSurfaceLayout();
+        try {
+            if (!restarting && hasVisibleActivities
+                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
+                // If there was nothing to resume, and we are not already restarting this process, but
+                // there is a visible activity that is hosted by the process...  then make sure all
+                // visible activities are running, taking care of restarting this process.
+                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+            }
+        } finally {
+            mWindowManager.continueSurfaceLayout();
         }
     }
 
@@ -6730,39 +6604,12 @@
     }
 
     @Override
-    public void keyguardWaitingForActivityDrawn() {
-        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
-        final long token = Binder.clearCallingIdentity();
-        try {
-            synchronized (this) {
-                if (DEBUG_LOCKSCREEN) logLockScreen("");
-                mWindowManager.keyguardWaitingForActivityDrawn();
-                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
-                    mLockScreenShown = LOCK_SCREEN_LEAVING;
-                    updateSleepIfNeededLocked();
-                }
-            }
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    @Override
     public void keyguardGoingAway(int flags) {
         enforceNotIsolatedCaller("keyguardGoingAway");
         final long token = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
-                if (DEBUG_LOCKSCREEN) logLockScreen("");
-                mWindowManager.keyguardGoingAway(flags);
-                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
-                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
-                    updateSleepIfNeededLocked();
-
-                    // Some stack visibility might change (e.g. docked stack)
-                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
-                    applyVrModeIfNeededLocked(mStackSupervisor.getResumedActivityLocked(), true);
-                }
+                mKeyguardController.keyguardGoingAway(flags);
             }
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -6913,6 +6760,7 @@
         final long origId = Binder.clearCallingIdentity();
         synchronized(this) {
             ActivityRecord.activityResumedLocked(token);
+            mWindowManager.notifyAppResumedFinished(token);
         }
         Binder.restoreCallingIdentity(origId);
     }
@@ -7605,7 +7453,8 @@
                 // current bounds.
                 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
                 final Rect bounds = (pinnedStack != null)
-                        ? pinnedStack.mBounds : getDefaultPictureInPictureBounds();
+                        ? pinnedStack.mBounds
+                        : mWindowManager.getPictureInPictureDefaultBounds(DEFAULT_DISPLAY);
 
                 mStackSupervisor.moveActivityToPinnedStackLocked(
                         r, "enterPictureInPictureMode", bounds);
@@ -7615,85 +7464,6 @@
         }
     }
 
-    @Override
-    public Rect getDefaultPictureInPictureBounds() {
-        final long origId = Binder.clearCallingIdentity();
-        final Rect defaultBounds = new Rect();
-        try {
-            synchronized(this) {
-                if (!mSupportsPictureInPicture) {
-                    return new Rect();
-                }
-
-                // Convert the sizes to for the current display state
-                final DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
-                final int stackWidth = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
-                        mDefaultPinnedStackSizeDp.getWidth(), dm);
-                final int stackHeight = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
-                        mDefaultPinnedStackSizeDp.getHeight(), dm);
-                final Rect maxBounds = new Rect();
-                getPictureInPictureBounds(maxBounds);
-                Gravity.apply(mDefaultPinnedStackGravity, stackWidth, stackHeight,
-                        maxBounds, 0, 0, defaultBounds);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(origId);
-        }
-        return defaultBounds;
-    }
-
-    @Override
-    public Rect getPictureInPictureMovementBounds() {
-        final long origId = Binder.clearCallingIdentity();
-        final Rect maxBounds = new Rect();
-        try {
-            synchronized(this) {
-                if (!mSupportsPictureInPicture) {
-                    return new Rect();
-                }
-
-                getPictureInPictureBounds(maxBounds);
-
-                // Adjust the max bounds by the current stack dimensions
-                final StackInfo pinnedStackInfo = mStackSupervisor.getStackInfoLocked(
-                        PINNED_STACK_ID);
-                if (pinnedStackInfo != null) {
-                    maxBounds.right = Math.max(maxBounds.left, maxBounds.right -
-                            pinnedStackInfo.bounds.width());
-                    maxBounds.bottom = Math.max(maxBounds.top, maxBounds.bottom -
-                            pinnedStackInfo.bounds.height());
-                }
-            }
-        } finally {
-            Binder.restoreCallingIdentity(origId);
-        }
-        return maxBounds;
-    }
-
-    /**
-     * Calculate the bounds where the pinned stack can move in the current display state.
-     */
-    private void getPictureInPictureBounds(Rect outRect) {
-        // Convert the insets to for the current display state
-        final DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
-        final int insetsLR = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
-                mDefaultPinnedStackScreenEdgeInsetsDp.getWidth(), dm);
-        final int insetsTB = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
-                mDefaultPinnedStackScreenEdgeInsetsDp.getHeight(), dm);
-        try {
-            final Rect insets = new Rect();
-            final DisplayInfo info = mStackSupervisor.getDisplayInfo(DEFAULT_DISPLAY);
-            mWindowManager.getStableInsets(insets);
-
-            // Calculate the insets from the system decorations and apply the gravity
-            outRect.set(insets.left + insetsLR, insets.top + insetsTB,
-                    info.logicalWidth - insets.right - insetsLR,
-                    info.logicalHeight - insets.bottom - insetsTB);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to calculate PIP movement bounds", e);
-        }
-    }
-
     // =========================================================
     // PROCESS INFO
     // =========================================================
@@ -7781,7 +7551,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);
             }
@@ -9098,12 +8869,12 @@
     // =========================================================
 
     @Override
-    public List<IAppTask> getAppTasks(String callingPackage) {
+    public List<IBinder> getAppTasks(String callingPackage) {
         int callingUid = Binder.getCallingUid();
         long ident = Binder.clearCallingIdentity();
 
         synchronized(this) {
-            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
+            ArrayList<IBinder> list = new ArrayList<IBinder>();
             try {
                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
 
@@ -9124,7 +8895,7 @@
                     ActivityManager.RecentTaskInfo taskInfo =
                             createRecentTaskInfoFromTaskRecord(tr);
                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
-                    list.add(taskImpl);
+                    list.add(taskImpl.asBinder());
                 }
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -9439,7 +9210,6 @@
 
                 task.setLastThumbnailLocked(thumbnail);
                 task.freeLastThumbnail();
-
                 return task.taskId;
             }
         } finally {
@@ -9461,6 +9231,7 @@
             if (r != null) {
                 r.setTaskDescription(td);
                 r.task.updateTaskDescription();
+                mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td);
             }
         }
     }
@@ -9576,16 +9347,17 @@
     }
 
     @Override
-    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
+    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
             throws RemoteException {
-        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
-                opts.getCustomInPlaceResId() == 0) {
+        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
+        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
+                activityOptions.getCustomInPlaceResId() == 0) {
             throw new IllegalArgumentException("Expected in-place ActivityOption " +
                     "with valid animation");
         }
         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
-        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
-                opts.getCustomInPlaceResId());
+        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
+                activityOptions.getCustomInPlaceResId());
         mWindowManager.executeAppTransition();
     }
 
@@ -9744,6 +9516,22 @@
     }
 
     @Override
+    public void moveStackToDisplay(int stackId, int displayId) {
+        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
+
+        synchronized (this) {
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
+                        + " to displayId=" + displayId);
+                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
+    @Override
     public boolean removeTask(int taskId) {
         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
         synchronized (this) {
@@ -9872,14 +9660,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) {
@@ -10281,7 +10061,7 @@
     }
 
     @Override
-    public void startLockTaskMode(int taskId) {
+    public void startLockTaskModeById(int taskId) {
         synchronized (this) {
             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
             if (task != null) {
@@ -10291,7 +10071,7 @@
     }
 
     @Override
-    public void startLockTaskMode(IBinder token) {
+    public void startLockTaskModeByToken(IBinder token) {
         synchronized (this) {
             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
             if (r == null) {
@@ -10311,7 +10091,7 @@
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
-                startLockTaskMode(taskId);
+                startLockTaskModeById(taskId);
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -11631,9 +11411,10 @@
         }
     }
 
-    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
+    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
         enforceNotIsolatedCaller("openContentUri");
         final int userId = UserHandle.getCallingUserId();
+        final Uri uri = Uri.parse(uriString);
         String name = uri.getAuthority();
         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
         ParcelFileDescriptor pfd = null;
@@ -11737,7 +11518,7 @@
             case PowerManagerInternal.WAKEFULNESS_DOZING:
                 // Pause applications whenever the lock screen is shown or any sleep
                 // tokens have been acquired.
-                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
+                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
             default:
                 // If we're asleep then pause applications unconditionally.
@@ -11750,38 +11531,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
@@ -11833,22 +11586,6 @@
         Binder.restoreCallingIdentity(origId);
     }
 
-    private String lockScreenShownToString() {
-        switch (mLockScreenShown) {
-            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
-            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
-            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
-            default: return "Unknown=" + mLockScreenShown;
-        }
-    }
-
-    void logLockScreen(String msg) {
-        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
-                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
-                + PowerManagerInternal.wakefulnessToString(mWakefulness)
-                + " mSleeping=" + mSleeping);
-    }
-
     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
@@ -11866,7 +11603,8 @@
         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
     }
 
-    public void setLockScreenShown(boolean showing, boolean occluded) {
+    @Override
+    public void setLockScreenShown(boolean showing) {
         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires permission "
@@ -11876,18 +11614,7 @@
         synchronized(this) {
             long ident = Binder.clearCallingIdentity();
             try {
-                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
-                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
-                if (showing && occluded) {
-                    // The lock screen is currently showing, but is occluded by a window that can
-                    // show on top of the lock screen. In this can we want to dismiss the docked
-                    // stack since it will be complicated/risky to try to put the activity on top
-                    // of the lock screen in the right fullscreen configuration.
-                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
-                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
-                }
-
-                updateSleepIfNeededLocked();
+                mKeyguardController.setKeyguardShown(showing);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -12518,9 +12245,11 @@
     }
 
     @Override
-    public void registerUidObserver(IUidObserver observer, int which) {
-        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
-                "registerUidObserver()");
+    public void registerUidObserver(IUidObserver observer, int which, String callingPackage) {
+        if (!hasUsageStatsPermission(callingPackage)) {
+            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
+                    "registerUidObserver");
+        }
         synchronized (this) {
             mUidObservers.register(observer, which);
         }
@@ -12556,7 +12285,7 @@
     }
 
     @Override
-    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
+    public boolean convertToTranslucent(IBinder token, Bundle options) {
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
@@ -12567,7 +12296,7 @@
                 int index = r.task.mActivities.lastIndexOf(r);
                 if (index > 0) {
                     ActivityRecord under = r.task.mActivities.get(index - 1);
-                    under.returningOptions = options;
+                    under.returningOptions = ActivityOptions.fromBundle(options);
                 }
                 final boolean translucentChanged = r.changeWindowTranslucency(false);
                 if (translucentChanged) {
@@ -12615,7 +12344,7 @@
     }
 
     @Override
-    public ActivityOptions getActivityOptions(IBinder token) {
+    public Bundle getActivityOptions(IBinder token) {
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
@@ -12623,7 +12352,7 @@
                 if (r != null) {
                     final ActivityOptions activityOptions = r.pendingOptions;
                     r.pendingOptions = null;
-                    return activityOptions;
+                    return activityOptions == null ? null : activityOptions.toBundle();
                 }
                 return null;
             }
@@ -13240,7 +12969,6 @@
             mLenientBackgroundCheck = lenientBackgroundCheck;
             mSupportsLeanbackOnly = supportsLeanbackOnly;
             mForceResizableActivities = forceResizable;
-            mWindowManager.setForceResizableTasks(mForceResizableActivities);
             if (supportsMultiWindow || forceResizable) {
                 mSupportsMultiWindow = true;
                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
@@ -13250,6 +12978,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);
@@ -13263,12 +12993,6 @@
                     com.android.internal.R.dimen.thumbnail_width);
             mThumbnailHeight = res.getDimensionPixelSize(
                     com.android.internal.R.dimen.thumbnail_height);
-            mDefaultPinnedStackSizeDp = Size.parseSize(res.getString(
-                    com.android.internal.R.string.config_defaultPictureInPictureSize));
-            mDefaultPinnedStackScreenEdgeInsetsDp = Size.parseSize(res.getString(
-                    com.android.internal.R.string.config_defaultPictureInPictureScreenEdgeInsets));
-            mDefaultPinnedStackGravity = res.getInteger(
-                    com.android.internal.R.integer.config_defaultPictureInPictureGravity);
             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
                     com.android.internal.R.string.config_appsNotReportingCrashes));
             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
@@ -13284,11 +13008,6 @@
         }
     }
 
-    public boolean testIsSystemReady() {
-        // no need to synchronize(this) just to read & return the value
-        return mSystemReady;
-    }
-
     public void systemReady(final Runnable goingCallback) {
         synchronized(this) {
             if (mSystemReady) {
@@ -13482,7 +13201,8 @@
      * @param app object of the crashing app, null for the system server
      * @param crashInfo describing the exception
      */
-    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
+    public void handleApplicationCrash(IBinder app,
+            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
         ProcessRecord r = findAppProcess(app, "Crash");
         final String processName = app == null ? "system_server"
                 : (r == null ? "unknown" : r.processName);
@@ -13694,7 +13414,7 @@
      * @return true if the process should exit immediately (WTF is fatal)
      */
     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
-            final ApplicationErrorReport.CrashInfo crashInfo) {
+            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
         final int callingUid = Binder.getCallingUid();
         final int callingPid = Binder.getCallingPid();
 
@@ -14350,11 +14070,6 @@
                 }
             } else if ("locks".equals(cmd)) {
                 LockGuard.dump(fd, pw, args);
-            } else if ("pip".equals(cmd)) {
-                pw.print("defaultBounds="); getDefaultPictureInPictureBounds().printShortString(pw);
-                pw.println();
-                pw.print("movementBounds="); getPictureInPictureMovementBounds().printShortString(pw);
-                pw.println();
             } else {
                 // Dumping a single activity?
                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacks)) {
@@ -14877,6 +14592,7 @@
         }
         if (dumpPackage == null) {
             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
+            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
         }
         if (dumpAll) {
             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
@@ -14902,8 +14618,7 @@
             pw.println("  mWakefulness="
                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
             pw.println("  mSleepTokens=" + mSleepTokens);
-            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
-                    + lockScreenShownToString());
+            pw.println("  mSleeping=" + mSleeping);
             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
             if (mRunningVoice != null) {
                 pw.println("  mRunningVoice=" + mRunningVoice);
@@ -18939,8 +18654,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");
@@ -18965,12 +18679,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);
         }
     }
 
@@ -18995,21 +18713,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);
@@ -19096,8 +18813,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;
         }
@@ -19124,33 +18841,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;
@@ -19158,16 +18875,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 {
@@ -19197,13 +18904,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);
@@ -20819,6 +20629,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,
@@ -21367,6 +21198,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;
@@ -21397,6 +21231,9 @@
                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
             }
         }
+        if (mLocalPowerManager != null) {
+            mLocalPowerManager.finishUidChanges();
+        }
 
         if (mProcessStats.shouldWriteNowLocked(now)) {
             mHandler.post(new Runnable() {
@@ -21421,10 +21258,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) {
@@ -21438,6 +21282,9 @@
                     }
                 }
             }
+            if (mLocalPowerManager != null) {
+                mLocalPowerManager.finishUidChanges();
+            }
             if (nextTime > 0) {
                 mHandler.removeMessages(IDLE_UIDS_MSG);
                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
@@ -22209,6 +22056,27 @@
         public int getUidProcessState(int uid) {
             return getUidState(uid);
         }
+
+        @Override
+        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
+            synchronized (ActivityManagerService.this) {
+
+                // We might change the visibilities here, so prepare an empty app transition which
+                // might be overridden later if we actually change visibilities.
+                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
+                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+                mWindowManager.executeAppTransition();
+            }
+            if (callback != null) {
+                callback.run();
+            }
+        }
+
+        @Override
+        public boolean isSystemReady() {
+            // no need to synchronize(this) just to read & return the value
+            return mSystemReady;
+        }
     }
 
     private final class SleepTokenImpl extends SleepToken {
@@ -22403,4 +22271,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 c7a04c1..abeea74 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -27,6 +27,7 @@
 import android.app.Instrumentation;
 import android.app.ProfilerInfo;
 import android.app.UiAutomationConnection;
+import android.app.WaitResult;
 import android.app.usage.ConfigurationStats;
 import android.app.usage.IUsageStatsManager;
 import android.app.usage.UsageStatsManager;
@@ -40,7 +41,9 @@
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
+import android.content.res.AssetManager;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.Rect;
 import android.os.Binder;
 import android.os.Build;
@@ -55,6 +58,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.DebugUtils;
+import android.util.DisplayMetrics;
 import android.view.IWindowManager;
 
 import com.android.internal.util.HexDump;
@@ -141,7 +145,8 @@
                 case "broadcast":
                     return runSendBroadcast(pw);
                 case "instrument":
-                    return runInstrument(pw);
+                    getOutPrintWriter().println("Error: must be invoked through 'am instrument'.");
+                    return -1;
                 case "trace-ipc":
                     return runTraceIpc(pw);
                 case "profile":
@@ -214,12 +219,18 @@
                     return runGetInactive(pw);
                 case "send-trim-memory":
                     return runSendTrimMemory(pw);
+                case "display":
+                    return runDisplay(pw);
                 case "stack":
                     return runStack(pw);
                 case "task":
                     return runTask(pw);
                 case "write":
                     return runWrite(pw);
+                case "attach-agent":
+                    return runAttachAgent(pw);
+                case "supports-multiwindow":
+                    return runSupportsMultiwindow(pw);
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -339,7 +350,7 @@
             pw.flush();
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
-            IActivityManager.WaitResult result = null;
+            WaitResult result = null;
             int res;
             final long startTime = SystemClock.uptimeMillis();
             ActivityOptions options = null;
@@ -428,7 +439,7 @@
             out.flush();
             if (mWaitOption && launched) {
                 if (result == null) {
-                    result = new IActivityManager.WaitResult();
+                    result = new WaitResult();
                     result.who = intent.getComponent();
                 }
                 pw.println("Status: " + (result.timeout ? "timeout" : "ok"));
@@ -559,224 +570,6 @@
         return 0;
     }
 
-    final static class InstrumentationWatcher extends IInstrumentationWatcher.Stub {
-        private final IActivityManager mInterface;
-        private final PrintWriter mPw;
-        private boolean mFinished = false;
-        private boolean mRawMode = false;
-
-        InstrumentationWatcher(IActivityManager iam, PrintWriter pw) {
-            mInterface = iam;
-            mPw = pw;
-        }
-
-        /**
-         * 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) {
-                    mPw.print(pretty);
-                } else {
-                    if (results != null) {
-                        for (String key : results.keySet()) {
-                            mPw.println(
-                                    "INSTRUMENTATION_STATUS: " + key + "=" + results.get(key));
-                        }
-                    }
-                    mPw.println("INSTRUMENTATION_STATUS_CODE: " + resultCode);
-                }
-                mPw.flush();
-                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) {
-                    mPw.println(pretty);
-                } else {
-                    if (results != null) {
-                        for (String key : results.keySet()) {
-                            mPw.println(
-                                    "INSTRUMENTATION_RESULT: " + key + "=" + results.get(key));
-                        }
-                    }
-                    mPw.println("INSTRUMENTATION_CODE: " + resultCode);
-                }
-                mPw.flush();
-                mFinished = true;
-                notifyAll();
-            }
-        }
-
-        public boolean waitForFinish() {
-            synchronized (this) {
-                while (!mFinished) {
-                    try {
-                        if (!mInterface.asBinder().pingBinder()) {
-                            return false;
-                        }
-                        wait(1000);
-                    } catch (InterruptedException e) {
-                        throw new IllegalStateException(e);
-                    }
-                }
-            }
-            return true;
-        }
-    }
-
-    int runInstrument(PrintWriter pw) throws RemoteException {
-        final PrintWriter err = getErrPrintWriter();
-        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;
-
-        String opt;
-        while ((opt=getNextOption()) != null) {
-            if (opt.equals("-p")) {
-                profileFile = getNextArgRequired();
-            } else if (opt.equals("-w")) {
-                wait = true;
-            } else if (opt.equals("-r")) {
-                rawMode = true;
-            } else if (opt.equals("-e")) {
-                argKey = getNextArgRequired();
-                argValue = getNextArgRequired();
-                args.putString(argKey, argValue);
-            } else if (opt.equals("--no_window_animation")
-                    || opt.equals("--no-window-animation")) {
-                no_window_animation = true;
-            } else if (opt.equals("--user")) {
-                userId = UserHandle.parseUserArg(getNextArgRequired());
-            } else if (opt.equals("--abi")) {
-                abi = getNextArgRequired();
-            } else {
-                err.println("Error: Unknown option: " + opt);
-                return -1;
-            }
-        }
-
-        if (userId == UserHandle.USER_ALL) {
-            err.println("Error: Can't start instrumentation with user 'all'");
-            return -1;
-        }
-
-        String cnArg = getNextArgRequired();
-
-        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(mInterface, pw);
-            watcher.setRawOutput(rawMode);
-            // Don't yet know how to support this.
-            connection = null; //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 RuntimeException(
-                        "INSTRUMENTATION_FAILED: Unsupported instruction set " + abi);
-            }
-        }
-
-        if (!mInterface.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId,
-                abi)) {
-            throw new RuntimeException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
-        }
-
-        if (watcher != null) {
-            if (!watcher.waitForFinish()) {
-                pw.println("INSTRUMENTATION_ABORTED: System has crashed.");
-            }
-        }
-
-        if (oldAnims != null) {
-            wm.setAnimationScales(oldAnims);
-        }
-        return 0;
-    }
-
     int runTraceIpc(PrintWriter pw) throws RemoteException {
         String op = getNextArgRequired();
         if (op.equals("start")) {
@@ -1846,12 +1639,23 @@
         return 0;
     }
 
+    int runDisplay(PrintWriter pw) throws RemoteException {
+        String op = getNextArgRequired();
+        switch (op) {
+            case "move-stack":
+                return runDisplayMoveStack(pw);
+            default:
+                getErrPrintWriter().println("Error: unknown command '" + op + "'");
+                return -1;
+        }
+    }
+
     int runStack(PrintWriter pw) throws RemoteException {
         String op = getNextArgRequired();
         switch (op) {
             case "start":
                 return runStackStart(pw);
-            case "movetask":
+            case "move-task":
                 return runStackMoveTask(pw);
             case "resize":
                 return runStackResize(pw);
@@ -1906,6 +1710,15 @@
         return new Rect(left, top, right, bottom);
     }
 
+    int runDisplayMoveStack(PrintWriter pw) throws RemoteException {
+        String stackIdStr = getNextArgRequired();
+        int stackId = Integer.parseInt(stackIdStr);
+        String displayIdStr = getNextArgRequired();
+        int displayId = Integer.parseInt(displayIdStr);
+        mInterface.moveStackToDisplay(stackId, displayId);
+        return 0;
+    }
+
     int runStackStart(PrintWriter pw) throws RemoteException {
         String displayIdStr = getNextArgRequired();
         int displayId = Integer.parseInt(displayIdStr);
@@ -2175,7 +1988,7 @@
             mInterface.stopLockTaskMode();
         } else {
             int taskId = Integer.parseInt(taskIdStr);
-            mInterface.startLockTaskMode(taskId);
+            mInterface.startLockTaskModeById(taskId);
         }
         pw.println("Activity manager is " + (mInterface.isInLockTaskMode() ? "" : "not ") +
                 "in lockTaskMode");
@@ -2462,6 +2275,38 @@
         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;
+    }
+
+    int runSupportsMultiwindow(PrintWriter pw) throws RemoteException {
+        // system resources does not contain all the device configuration, construct it manually.
+        Configuration config = mInterface.getConfiguration();
+        if (config == null) {
+            pw.println("Error: Activity manager has no configuration");
+            return -1;
+        }
+
+        final DisplayMetrics metrics = new DisplayMetrics();
+        metrics.setToDefaults();
+
+        Resources res = new Resources(AssetManager.getSystem(), metrics, config);
+
+        pw.println(res.getBoolean(com.android.internal.R.bool.config_supportsMultiWindow));
+        return 0;
+    }
+
     @Override
     public void onHelp() {
         PrintWriter pw = getOutPrintWriter();
@@ -2481,7 +2326,6 @@
             pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
             pw.println("    o[om]: out of memory management");
             pw.println("    perm[issions]: URI permission grant state");
-            pw.println("    pip: PIP state");
             pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
             pw.println("    provider [COMP_SPEC]: provider client-side state");
             pw.println("    s[ervices] [COMP_SPEC ...]: service state");
@@ -2534,6 +2378,25 @@
             pw.println("      --user <USER_ID> | all | current: Specify which user to send to; if not");
             pw.println("          specified then send to all users.");
             pw.println("      --receiver-permission <PERMISSION>: Require receiver to hold permission.");
+            pw.println("  instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]");
+            pw.println("          [--user <USER_ID> | current]");
+            pw.println("          [--no-window-animation] [--abi <ABI>] <COMPONENT>");
+            pw.println("      Start an Instrumentation.  Typically this target <COMPONENT> is in the");
+            pw.println("      form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there");
+            pw.println("      is only one instrumentation.  Options are:");
+            pw.println("      -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT).  Use with");
+            pw.println("          [-e perf true] to generate raw output for performance measurements.");
+            pw.println("      -e <NAME> <VALUE>: set argument <NAME> to <VALUE>.  For test runners a");
+            pw.println("          common form is [-e <testrunner_flag> <value>[,<value>...]].");
+            pw.println("      -p <FILE>: write profiling data to <FILE>");
+            pw.println("      -m: Write output as protobuf (machine readable)");
+            pw.println("      -w: wait for instrumentation to finish before returning.  Required for");
+            pw.println("          test runners.");
+            pw.println("      --user <USER_ID> | current: Specify user instrumentation runs in;");
+            pw.println("          current user if not specified.");
+            pw.println("      --no-window-animation: turn off window animations while running.");
+            pw.println("      --abi <ABI>: Launch the instrumented process with the selected ABI.");
+            pw.println("          This assumes that the process supports the selected ABI.");
             pw.println("  trace-ipc [start|stop] [--dump-file <FILE>]");
             pw.println("      Trace IPC transactions.");
             pw.println("      start: start tracing IPC transactions.");
@@ -2619,8 +2482,12 @@
             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("  supports-multiwindow");
+            pw.println("      Returns true if the device supports multiwindow.");
             pw.println("  suppress-resize-config-changes <true|false>");
             pw.println("      Suppresses configuration changes due to user resizing an activity/task.");
             pw.println("  set-inactive [--user <USER_ID>] <PACKAGE> true|false");
@@ -2630,10 +2497,13 @@
             pw.println("  send-trim-memory [--user <USER_ID>] <PROCESS>");
             pw.println("          [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]");
             pw.println("      Send a memory trim event to a <PROCESS>.");
+            pw.println("  display [COMMAND] [...]: sub-commands for operating on displays.");
+            pw.println("       move-stack <STACK_ID> <DISPLAY_ID>");
+            pw.println("           Move <STACK_ID> from its current display to <DISPLAY_ID>.");
             pw.println("  stack [COMMAND] [...]: sub-commands for operating on activity stacks.");
             pw.println("       start <DISPLAY_ID> <INTENT>");
             pw.println("           Start a new activity on <DISPLAY_ID> using <INTENT>");
-            pw.println("       movetask <TASK_ID> <STACK_ID> [true|false]");
+            pw.println("       move-task <TASK_ID> <STACK_ID> [true|false]");
             pw.println("           Move <TASK_ID> from its current stack to the top (true) or");
             pw.println("           bottom (false) of <STACK_ID>.");
             pw.println("       resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
@@ -2683,8 +2553,6 @@
             pw.println("           Test command for sizing <TASK_ID> by <STEP_SIZE>");
             pw.println("           increments within the screen applying the optional [DELAY_MS] between");
             pw.println("           each step.");
-            pw.println("  pip");
-            pw.println("      Gets the current PIP state.");
             pw.println("  write");
             pw.println("      Write all pending state to storage.");
             pw.println();
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index b7618a1..90b46ed 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -83,6 +83,7 @@
 import android.view.AppTransitionAnimationSpec;
 import android.view.IApplicationToken;
 import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
 
 import com.android.internal.app.ResolverActivity;
 import com.android.internal.content.ReferrerIntent;
@@ -664,10 +665,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);
@@ -713,7 +722,7 @@
                         : android.R.style.Theme_Holo;
             }
             if ((aInfo.flags&ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
-                windowFlags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+                windowFlags |= LayoutParams.FLAG_HARDWARE_ACCELERATED;
             }
             if ((aInfo.flags&ActivityInfo.FLAG_MULTIPROCESS) != 0
                     && _caller != null
@@ -921,6 +930,22 @@
         return (info.flags & FLAG_ALWAYS_FOCUSABLE) != 0;
     }
 
+    /**
+     * @return true if the activity contains windows that have
+     *         {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set
+     */
+    boolean hasShowWhenLockedWindows() {
+        return service.mWindowManager.containsShowWhenLockedWindow(appToken);
+    }
+
+    /**
+     * @return true if the activity contains windows that have
+     *         {@link LayoutParams#FLAG_DISMISS_KEYGUARD} set
+     */
+    boolean hasDismissKeyguardWindows() {
+        return service.mWindowManager.containsDismissKeyguardWindow(appToken);
+    }
+
     void makeFinishingLocked() {
         if (!finishing) {
             final ActivityStack stack = getStack();
@@ -932,6 +957,10 @@
             if (stopped) {
                 clearOptionsLocked();
             }
+
+            if (service != null) {
+                service.mTaskChangeNotificationController.notifyTaskStackChanged();
+            }
         }
     }
 
@@ -1322,7 +1351,6 @@
         if (nowVisible) {
             // We won't get a call to reportActivityVisibleLocked() so dismiss lockscreen now.
             mStackSupervisor.reportActivityVisibleLocked(this);
-            mStackSupervisor.notifyActivityDrawnForKeyguard();
         }
 
         // Schedule an idle timeout in case the app doesn't do it for us.
@@ -1646,6 +1674,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 +1743,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..0d79980 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -31,7 +31,6 @@
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_APP;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RESULTS;
@@ -60,7 +59,6 @@
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.am.ActivityManagerService.LOCK_SCREEN_SHOWN;
 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.STARTING_WINDOW_REMOVED;
@@ -332,6 +330,9 @@
 
     private final LaunchingTaskPositioner mTaskPositioner;
 
+    private boolean mTopActivityOccludesKeyguard;
+    private ActivityRecord mTopDismissingKeyguardActivity;
+
     static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
     static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
     static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
@@ -448,10 +449,23 @@
                 ? new LaunchingTaskPositioner() : null;
     }
 
-    void attachDisplay(ActivityStackSupervisor.ActivityDisplay activityDisplay, boolean onTop) {
+    /** Adds the stack to specified display and calls WindowManager to do the same. */
+    void addToDisplay(ActivityStackSupervisor.ActivityDisplay activityDisplay, boolean onTop) {
+        final Rect bounds = mWindowManager.addStackToDisplay(mStackId, activityDisplay.mDisplayId,
+                onTop);
+        postAddToDisplay(activityDisplay, bounds);
+    }
+
+    /**
+     * Updates internal state after adding to new display.
+     * @param activityDisplay New display to which this stack was attached.
+     * @param bounds Updated bounds.
+     */
+    private void postAddToDisplay(ActivityStackSupervisor.ActivityDisplay activityDisplay,
+            Rect bounds) {
         mDisplayId = activityDisplay.mDisplayId;
         mStacks = activityDisplay.mStacks;
-        mBounds = mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId, onTop);
+        mBounds = bounds;
         mFullscreen = mBounds == null;
         if (mTaskPositioner != null) {
             mTaskPositioner.setDisplay(activityDisplay.mDisplay);
@@ -467,14 +481,26 @@
         }
     }
 
-    void detachDisplay() {
+    /**
+     * Moves the stack to specified display.
+     * @param activityDisplay Target display to move the stack to.
+     */
+    void moveToDisplay(ActivityStackSupervisor.ActivityDisplay activityDisplay) {
+        removeFromDisplay();
+        final Rect bounds = mWindowManager.moveStackToDisplay(mStackId, activityDisplay.mDisplayId);
+        postAddToDisplay(activityDisplay, bounds);
+    }
+
+    /**
+     * Updates the inner state of the stack to remove it from its current parent, so it can be
+     * either destroyed completely or re-parented.
+     */
+    private void removeFromDisplay() {
         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.
@@ -483,6 +509,14 @@
         }
     }
 
+    /** Removes the stack completely. Also calls WindowManager to do the same on its side. */
+    void remove() {
+        removeFromDisplay();
+        mStackSupervisor.deleteActivityContainerRecord(mStackId);
+        mWindowManager.removeStack(mStackId);
+        onParentChanged();
+    }
+
     void getDisplaySize(Point out) {
         mActivityContainer.mActivityDisplay.mDisplay.getSize(out);
     }
@@ -694,11 +728,7 @@
         }
 
         mStacks.add(addIndex, this);
-
-        // TODO(multi-display): Needs to also work if focus is moving to the non-home display.
-        if (isOnHomeDisplay()) {
-            mStackSupervisor.setFocusStackUnchecked(reason, this);
-        }
+        mStackSupervisor.setFocusStackUnchecked(reason, this);
         if (task != null) {
             insertTaskAtTop(task, null);
             return;
@@ -1168,7 +1198,12 @@
             if (mPausingActivity == r) {
                 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
                         + (timeout ? " (due to timeout)" : " (pause complete)"));
-                completePauseLocked(true, null);
+                mService.mWindowManager.deferSurfaceLayout();
+                try {
+                    completePauseLocked(true, null);
+                } finally {
+                    mService.mWindowManager.continueSurfaceLayout();
+                }
                 return;
             } else {
                 EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
@@ -1278,7 +1313,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;
         }
 
@@ -1580,153 +1615,218 @@
      */
     final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
             boolean preserveWindows) {
-        ActivityRecord top = topRunningActivityLocked();
-        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top
-                + " configChanges=0x" + Integer.toHexString(configChanges));
-        if (top != null) {
-            checkTranslucentActivityWaiting(top);
-        }
+        mTopActivityOccludesKeyguard = false;
+        mTopDismissingKeyguardActivity = null;
+        mStackSupervisor.mKeyguardController.beginActivityVisibilityUpdate();
+        try {
+            ActivityRecord top = topRunningActivityLocked();
+            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top
+                    + " configChanges=0x" + Integer.toHexString(configChanges));
+            if (top != null) {
+                checkTranslucentActivityWaiting(top);
+            }
 
-        // If the top activity is not fullscreen, then we need to
-        // make sure any activities under it are now visible.
-        boolean aboveTop = top != null;
-        final int stackVisibility = getStackVisibilityLocked(starting);
-        final boolean stackInvisible = stackVisibility != STACK_VISIBLE;
-        final boolean stackVisibleBehind = stackVisibility == STACK_VISIBLE_ACTIVITY_BEHIND;
-        boolean behindFullscreenActivity = stackInvisible;
-        boolean resumeNextActivity = mStackSupervisor.isFocusedStack(this)
-                && (isInStackLocked(starting) == null);
-        boolean behindTranslucentActivity = false;
-        final ActivityRecord visibleBehind = getVisibleBehindActivity();
-        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
-            final TaskRecord task = mTaskHistory.get(taskNdx);
-            final ArrayList<ActivityRecord> activities = task.mActivities;
-            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
-                final ActivityRecord r = activities.get(activityNdx);
-                if (r.finishing) {
-                    // Normally the screenshot will be taken in makeInvisible(). When an activity
-                    // is finishing, we no longer change its visibility, but we still need to take
-                    // the screenshots if startPausingLocked decided it should be taken.
-                    if (r.mUpdateTaskThumbnailWhenHidden) {
-                        r.updateThumbnailLocked(r.screenshotActivityLocked(),
-                                null /* description */);
-                        r.mUpdateTaskThumbnailWhenHidden = false;
+            // If the top activity is not fullscreen, then we need to
+            // make sure any activities under it are now visible.
+            boolean aboveTop = top != null;
+            final int stackVisibility = getStackVisibilityLocked(starting);
+            final boolean stackInvisible = stackVisibility != STACK_VISIBLE;
+            final boolean stackVisibleBehind = stackVisibility == STACK_VISIBLE_ACTIVITY_BEHIND;
+            boolean behindFullscreenActivity = stackInvisible;
+            boolean resumeNextActivity = mStackSupervisor.isFocusedStack(this)
+                    && (isInStackLocked(starting) == null);
+            boolean behindTranslucentActivity = false;
+            final ActivityRecord visibleBehind = getVisibleBehindActivity();
+            for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+                final TaskRecord task = mTaskHistory.get(taskNdx);
+                final ArrayList<ActivityRecord> activities = task.mActivities;
+                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                    final ActivityRecord r = activities.get(activityNdx);
+                    if (r.finishing) {
+                        // Normally the screenshot will be taken in makeInvisible(). When an activity
+                        // is finishing, we no longer change its visibility, but we still need to take
+                        // the screenshots if startPausingLocked decided it should be taken.
+                        if (r.mUpdateTaskThumbnailWhenHidden) {
+                            r.updateThumbnailLocked(r.screenshotActivityLocked(),
+                                    null /* description */);
+                            r.mUpdateTaskThumbnailWhenHidden = false;
+                        }
+                        continue;
                     }
-                    continue;
-                }
-                final boolean isTop = r == top;
-                if (aboveTop && !isTop) {
-                    continue;
-                }
-                aboveTop = false;
-
-                if (r.shouldBeVisible(behindTranslucentActivity, stackVisibleBehind,
-                        visibleBehind, behindFullscreenActivity)) {
-                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
-                            + " finishing=" + r.finishing + " state=" + r.state);
-                    // First: if this is not the current activity being started, make
-                    // sure it matches the current configuration.
-                    if (r != starting) {
-                        r.ensureActivityConfigurationLocked(0 /* globalChanges */, preserveWindows);
+                    final boolean isTop = r == top;
+                    if (aboveTop && !isTop) {
+                        continue;
                     }
+                    aboveTop = false;
 
-                    if (r.app == null || r.app.thread == null) {
-                        if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
-                                resumeNextActivity, r)) {
-                            if (activityNdx >= activities.size()) {
-                                // Record may be removed if its process needs to restart.
-                                activityNdx = activities.size() - 1;
-                            } else {
+                    // Check whether activity should be visible without Keyguard influence
+                    final boolean shouldBeVisible = r.shouldBeVisible(behindTranslucentActivity,
+                            stackVisibleBehind, visibleBehind, behindFullscreenActivity);
+
+                    // Now check whether it's really visible depending on Keyguard state.
+                    final boolean reallyVisible = checkKeyguardVisibility(r, shouldBeVisible,
+                            isTop);
+                    if (shouldBeVisible) {
+                        behindFullscreenActivity = updateBehindFullscreen(stackInvisible,
+                                behindFullscreenActivity, task, r);
+                        if (behindFullscreenActivity && !r.fullscreen) {
+                            behindTranslucentActivity = true;
+                        }
+                    }
+                    if (reallyVisible) {
+                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r
+                                + " finishing=" + r.finishing + " state=" + r.state);
+                        // First: if this is not the current activity being started, make
+                        // sure it matches the current configuration.
+                        if (r != starting) {
+                            r.ensureActivityConfigurationLocked(0 /* globalChanges */, preserveWindows);
+                        }
+
+                        if (r.app == null || r.app.thread == null) {
+                            if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,
+                                    resumeNextActivity, r)) {
+                                if (activityNdx >= activities.size()) {
+                                    // Record may be removed if its process needs to restart.
+                                    activityNdx = activities.size() - 1;
+                                } else {
+                                    resumeNextActivity = false;
+                                }
+                            }
+                        } else if (r.visible) {
+                            // If this activity is already visible, then there is nothing to do here.
+                            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
+                                    "Skipping: already visible at " + r);
+
+                            if (r.handleAlreadyVisible()) {
                                 resumeNextActivity = false;
                             }
+                        } else {
+                            r.makeVisibleIfNeeded(starting);
                         }
-                    } else if (r.visible) {
-                        // If this activity is already visible, then there is nothing to do here.
-                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
-                                "Skipping: already visible at " + r);
-
-                        if (r.handleAlreadyVisible()) {
-                            resumeNextActivity = false;
-                        }
+                        // Aggregate current change flags.
+                        configChanges |= r.configChangeFlags;
                     } else {
-                        r.makeVisibleIfNeeded(starting);
+                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
+                                + " finishing=" + r.finishing + " state=" + r.state + " stackInvisible="
+                                + stackInvisible + " behindFullscreenActivity="
+                                + behindFullscreenActivity + " mLaunchTaskBehind="
+                                + r.mLaunchTaskBehind);
+                        makeInvisible(r, visibleBehind);
                     }
-                    // Aggregate current change flags.
-                    configChanges |= r.configChangeFlags;
-                    behindFullscreenActivity = updateBehindFullscreen(stackInvisible,
-                            behindFullscreenActivity, task, r);
-                    if (behindFullscreenActivity && !r.fullscreen) {
-                        behindTranslucentActivity = true;
+                }
+                if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
+                    // The visibility of tasks and the activities they contain in freeform stack are
+                    // determined individually unlike other stacks where the visibility or fullscreen
+                    // status of an activity in a previous task affects other.
+                    behindFullscreenActivity = stackVisibility == STACK_INVISIBLE;
+                } else if (mStackId == HOME_STACK_ID) {
+                    if (task.isOnTopLauncher()) {
+                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "On-top launcher: at " + task
+                                + " stackInvisible=" + stackInvisible
+                                + " behindFullscreenActivity=" + behindFullscreenActivity);
+                        // When an on-top launcher is visible, (e.g. it's on the top of the home stack),
+                        // other tasks in the home stack could be visible if and only if:
+                        // - some app is running in the docked stack;
+                        // - no app is running in either the fullscreen stack or the freefrom stack.
+                        final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
+                        final ActivityStack fullscreenStack = mStackSupervisor.getStack(
+                                FULLSCREEN_WORKSPACE_STACK_ID);
+                        final ActivityStack freeformStack = mStackSupervisor.getStack(
+                                FREEFORM_WORKSPACE_STACK_ID);
+                        final boolean dockedStackEmpty = dockedStack == null ||
+                                dockedStack.topRunningActivityLocked() == null;
+                        final boolean fullscreenStackEmpty = fullscreenStack == null ||
+                                fullscreenStack.topRunningActivityLocked() == null;
+                        final boolean freeformStackEmpty = freeformStack == null ||
+                                freeformStack.topRunningActivityLocked() == null;
+                        behindFullscreenActivity = dockedStackEmpty || !fullscreenStackEmpty ||
+                                !freeformStackEmpty;
+                    } else if (task.isHomeTask()) {
+                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
+                                + " stackInvisible=" + stackInvisible
+                                + " behindFullscreenActivity=" + behindFullscreenActivity);
+                        // No other task in the home stack should be visible behind the home activity.
+                        // Home activities is usually a translucent activity with the wallpaper behind
+                        // them. However, when they don't have the wallpaper behind them, we want to
+                        // show activities in the next application stack behind them vs. another
+                        // task in the home stack like recents.
+                        behindFullscreenActivity = true;
+                    } else if (task.isRecentsTask()
+                            && task.getTaskToReturnTo() == APPLICATION_ACTIVITY_TYPE) {
+                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
+                                "Recents task returning to app: at " + task
+                                        + " stackInvisible=" + stackInvisible
+                                        + " behindFullscreenActivity=" + behindFullscreenActivity);
+                        // We don't want any other tasks in the home stack visible if the recents
+                        // activity is going to be returning to an application activity type.
+                        // We do this to preserve the visible order the user used to get into the
+                        // recents activity. The recents activity is normally translucent and if it
+                        // doesn't have the wallpaper behind it the next activity in the home stack
+                        // shouldn't be visible when the home stack is brought to the front to display
+                        // the recents activity from an app.
+                        behindFullscreenActivity = true;
                     }
-                } else {
-                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r
-                            + " finishing=" + r.finishing + " state=" + r.state + " stackInvisible="
-                            + stackInvisible + " behindFullscreenActivity="
-                            + behindFullscreenActivity + " mLaunchTaskBehind="
-                            + r.mLaunchTaskBehind);
-                    makeInvisible(r, visibleBehind);
+
                 }
             }
-            if (mStackId == FREEFORM_WORKSPACE_STACK_ID) {
-                // The visibility of tasks and the activities they contain in freeform stack are
-                // determined individually unlike other stacks where the visibility or fullscreen
-                // status of an activity in a previous task affects other.
-                behindFullscreenActivity = stackVisibility == STACK_INVISIBLE;
-            } else if (mStackId == HOME_STACK_ID) {
-                if (task.isOnTopLauncher()) {
-                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "On-top launcher: at " + task
-                            + " stackInvisible=" + stackInvisible
-                            + " behindFullscreenActivity=" + behindFullscreenActivity);
-                    // When an on-top launcher is visible, (e.g. it's on the top of the home stack),
-                    // other tasks in the home stack could be visible if and only if:
-                    // - some app is running in the docked stack;
-                    // - no app is running in either the fullscreen stack or the freefrom stack.
-                    final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
-                    final ActivityStack fullscreenStack = mStackSupervisor.getStack(
-                            FULLSCREEN_WORKSPACE_STACK_ID);
-                    final ActivityStack freeformStack = mStackSupervisor.getStack(
-                            FREEFORM_WORKSPACE_STACK_ID);
-                    final boolean dockedStackEmpty = dockedStack == null ||
-                            dockedStack.topRunningActivityLocked() == null;
-                    final boolean fullscreenStackEmpty = fullscreenStack == null ||
-                            fullscreenStack.topRunningActivityLocked() == null;
-                    final boolean freeformStackEmpty = freeformStack == null ||
-                            freeformStack.topRunningActivityLocked() == null;
-                    behindFullscreenActivity = dockedStackEmpty || !fullscreenStackEmpty ||
-                            !freeformStackEmpty;
-                } else if (task.isHomeTask()) {
-                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
-                            + " stackInvisible=" + stackInvisible
-                            + " behindFullscreenActivity=" + behindFullscreenActivity);
-                    // No other task in the home stack should be visible behind the home activity.
-                    // Home activities is usually a translucent activity with the wallpaper behind
-                    // them. However, when they don't have the wallpaper behind them, we want to
-                    // show activities in the next application stack behind them vs. another
-                    // task in the home stack like recents.
-                    behindFullscreenActivity = true;
-                } else if (task.isRecentsTask()
-                        && task.getTaskToReturnTo() == APPLICATION_ACTIVITY_TYPE) {
-                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
-                            "Recents task returning to app: at " + task
-                                    + " stackInvisible=" + stackInvisible
-                                    + " behindFullscreenActivity=" + behindFullscreenActivity);
-                    // We don't want any other tasks in the home stack visible if the recents
-                    // activity is going to be returning to an application activity type.
-                    // We do this to preserve the visible order the user used to get into the
-                    // recents activity. The recents activity is normally translucent and if it
-                    // doesn't have the wallpaper behind it the next activity in the home stack
-                    // shouldn't be visible when the home stack is brought to the front to display
-                    // the recents activity from an app.
-                    behindFullscreenActivity = true;
-                }
 
+            if (mTranslucentActivityWaiting != null &&
+                    mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
+                // Nothing is getting drawn or everything was already visible, don't wait for timeout.
+                notifyActivityDrawnLocked(null);
+            }
+        } finally {
+            mStackSupervisor.mKeyguardController.endActivityVisibilityUpdate();
+        }
+    }
+
+    /**
+     * @return true if the top visible activity wants to occlude the Keyguard, false otherwise
+     */
+    boolean topActivityOccludesKeyguard() {
+        return mTopActivityOccludesKeyguard;
+    }
+
+    /**
+     * @return the top most visible activity that wants to dismiss Keyguard
+     */
+    ActivityRecord getTopDismissingKeyguardActivity() {
+        return mTopDismissingKeyguardActivity;
+    }
+
+    /**
+     * Checks whether {@param r} should be visible depending on Keyguard state and updates
+     * {@link #mTopActivityOccludesKeyguard} and {@link #mTopDismissingKeyguardActivity} if
+     * necessary.
+     *
+     * @return true if {@param r} is visible taken Keyguard state into account, false otherwise
+     */
+    private boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible,
+            boolean isTop) {
+        final boolean keyguardShowing = mStackSupervisor.mKeyguardController.isKeyguardShowing();
+        final boolean keyguardLocked = mStackSupervisor.mKeyguardController.isKeyguardLocked();
+        final boolean showWhenLocked = r.hasShowWhenLockedWindows();
+        if (shouldBeVisible) {
+            if (r.hasDismissKeyguardWindows() && mTopDismissingKeyguardActivity == null) {
+                mTopDismissingKeyguardActivity = r;
+            }
+
+            // Only the top activity may control occluded, as we can't occlude the Keyguard if the
+            // top app doesn't want to occlude it.
+            if (isTop) {
+                mTopActivityOccludesKeyguard |= showWhenLocked;
             }
         }
+        if (keyguardShowing) {
 
-        if (mTranslucentActivityWaiting != null &&
-                mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
-            // Nothing is getting drawn or everything was already visible, don't wait for timeout.
-            notifyActivityDrawnLocked(null);
+            // If keyguard is showing, nothing is visible.
+            return false;
+        } else if (keyguardLocked) {
+
+            // Show when locked windows above keyguard.
+            return shouldBeVisible && showWhenLocked;
+        } else {
+            return shouldBeVisible;
         }
     }
 
@@ -1946,10 +2046,6 @@
         try {
             // Protect against recursion.
             mStackSupervisor.inResumeTopActivity = true;
-            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
-                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
-                mService.updateSleepIfNeededLocked();
-            }
             result = resumeTopActivityInnerLocked(prev, options);
         } finally {
             mStackSupervisor.inResumeTopActivity = false;
@@ -1968,8 +2064,6 @@
     }
 
     private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
-        if (DEBUG_LOCKSCREEN) mService.logLockScreen("");
-
         if (!mService.mBooting && !mService.mBooted) {
             // Not ready yet!
             return false;
@@ -2285,13 +2379,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) {
@@ -3285,70 +3380,77 @@
             return false;
         }
 
-        r.makeFinishingLocked();
-        final TaskRecord task = r.task;
-        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
-                r.userId, System.identityHashCode(r),
-                task.taskId, r.shortComponentName, reason);
-        final ArrayList<ActivityRecord> activities = task.mActivities;
-        final int index = activities.indexOf(r);
-        if (index < (activities.size() - 1)) {
-            task.setFrontOfTask();
-            if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
-                // If the caller asked that this activity (and all above it)
-                // be cleared when the task is reset, don't lose that information,
-                // but propagate it up to the next activity.
-                ActivityRecord next = activities.get(index+1);
-                next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
-            }
-        }
-
-        r.pauseKeyDispatchingLocked();
-
-        adjustFocusedActivityStackLocked(r, "finishActivity");
-
-        finishActivityResultsLocked(r, resultCode, resultData);
-
-        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);
-            mWindowManager.prepareAppTransition(transit, false);
-
-            // Tell window manager to prepare for this one to be removed.
-            mWindowManager.setAppVisibility(r.appToken, false);
-
-            if (mPausingActivity == null) {
-                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
-                if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
-                        "finish() => pause with userLeaving=false");
-                startPausingLocked(false, false, null, false);
-            }
-
-            if (endTask) {
-                mStackSupervisor.removeLockedTaskLocked(task);
-            }
-        } else if (r.state != ActivityState.PAUSING) {
-            // If the activity is PAUSING, we will complete the finish once
-            // it is done pausing; else we can just directly finish it here.
-            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
-            if (r.visible) {
-                mWindowManager.prepareAppTransition(transit, false);
-                mWindowManager.setAppVisibility(r.appToken, false);
-                mWindowManager.executeAppTransition();
-                if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) {
-                    mStackSupervisor.mWaitingVisibleActivities.add(r);
+        mWindowManager.deferSurfaceLayout();
+        try {
+            r.makeFinishingLocked();
+            final TaskRecord task = r.task;
+            EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
+                    r.userId, System.identityHashCode(r),
+                    task.taskId, r.shortComponentName, reason);
+            final ArrayList<ActivityRecord> activities = task.mActivities;
+            final int index = activities.indexOf(r);
+            if (index < (activities.size() - 1)) {
+                task.setFrontOfTask();
+                if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
+                    // If the caller asked that this activity (and all above it)
+                    // be cleared when the task is reset, don't lose that information,
+                    // but propagate it up to the next activity.
+                    ActivityRecord next = activities.get(index+1);
+                    next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                 }
             }
-            return finishCurrentActivityLocked(r, (r.visible || r.nowVisible) ?
-                    FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null;
-        } else {
-            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
-        }
 
-        return false;
+            r.pauseKeyDispatchingLocked();
+
+            adjustFocusedActivityStackLocked(r, "finishActivity");
+
+            finishActivityResultsLocked(r, resultCode, resultData);
+
+            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.
+                mWindowManager.setAppVisibility(r.appToken, false);
+
+                if (mPausingActivity == null) {
+                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
+                    if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
+                            "finish() => pause with userLeaving=false");
+                    startPausingLocked(false, false, null, false);
+                }
+
+                if (endTask) {
+                    mStackSupervisor.removeLockedTaskLocked(task);
+                }
+            } else if (r.state != ActivityState.PAUSING) {
+                // If the activity is PAUSING, we will complete the finish once
+                // it is done pausing; else we can just directly finish it here.
+                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
+                if (r.visible) {
+                    mWindowManager.prepareAppTransition(transit, false);
+                    mWindowManager.setAppVisibility(r.appToken, false);
+                    mWindowManager.executeAppTransition();
+                    if (!mStackSupervisor.mWaitingVisibleActivities.contains(r)) {
+                        mStackSupervisor.mWaitingVisibleActivities.add(r);
+                    }
+                }
+                return finishCurrentActivityLocked(r, (r.visible || r.nowVisible) ?
+                        FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null;
+            } else {
+                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
+            }
+
+            return false;
+        } finally {
+            mWindowManager.continueSurfaceLayout();
+        }
     }
 
     static final int FINISH_IMMEDIATELY = 0;
@@ -3640,7 +3742,7 @@
         r.state = ActivityState.DESTROYED;
         if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + r);
         r.app = null;
-        mWindowManager.removeAppToken(r.appToken);
+        mWindowManager.removeAppToken(r.appToken, r.getDisplayId());
         final TaskRecord task = r.task;
         if (task != null && task.removeActivity(r)) {
             if (DEBUG_STACK) Slog.i(TAG_STACK,
@@ -4136,6 +4238,8 @@
 
         mStackSupervisor.resumeFocusedStackTopActivityLocked();
         EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
+
+        mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId);
     }
 
     /**
@@ -4688,6 +4792,7 @@
                 // default configuration the next time it launches.
                 task.updateOverrideConfiguration(null);
             }
+            mService.mTaskChangeNotificationController.notifyTaskRemoved(task.taskId);
         }
 
         final ActivityRecord r = mResumedActivity;
@@ -4755,7 +4860,8 @@
                 voiceInteractor);
         // add the task to stack first, mTaskPositioner might need the stack association
         addTask(task, toTop, "createTaskRecord");
-        final boolean isLockscreenShown = mService.mLockScreenShown == LOCK_SCREEN_SHOWN;
+        final boolean isLockscreenShown =
+                mService.mStackSupervisor.mKeyguardController.isKeyguardShowing();
         if (!layoutTaskInStack(task, info.windowLayout) && mBounds != null && task.isResizeable()
                 && !isLockscreenShown) {
             task.updateOverrideConfiguration(mBounds);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index a111230..8bb0e1a 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -16,6 +16,79 @@
 
 package com.android.server.am;
 
+import static android.Manifest.permission.START_ANY_ACTIVITY;
+import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
+import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
+import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
+import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
+import static android.app.ActivityManager.RESIZE_MODE_FORCED;
+import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
+import static android.app.ActivityManager.START_TASK_TO_FRONT;
+import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
+import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
+import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.HOME_STACK_ID;
+import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IDLE;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+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.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
+import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
+import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
+import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
+import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
+import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
+import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
+import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
+import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
+import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
+import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
+import static com.android.server.am.ActivityStack.STACK_VISIBLE;
+import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
+import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
+import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
+import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
+import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
+import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS;
+
 import android.Manifest;
 import android.annotation.UserIdInt;
 import android.app.Activity;
@@ -26,13 +99,11 @@
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
-import android.app.IActivityContainer;
 import android.app.IActivityContainerCallback;
-import android.app.IActivityManager;
-import android.app.IActivityManager.WaitResult;
 import android.app.ProfilerInfo;
 import android.app.ResultInfo;
 import android.app.StatusBarManager;
+import android.app.WaitResult;
 import android.app.admin.IDevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -45,6 +116,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,12 +148,12 @@
 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;
 import android.util.SparseIntArray;
 import android.view.Display;
-import android.view.DisplayInfo;
 import android.view.InputEvent;
 import android.view.Surface;
 
@@ -104,81 +176,7 @@
 import java.util.Objects;
 import java.util.Set;
 
-import static android.Manifest.permission.START_ANY_ACTIVITY;
-import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
-import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
-import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
-import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
-import static android.app.ActivityManager.RESIZE_MODE_FORCED;
-import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
-import static android.app.ActivityManager.START_TASK_TO_FRONT;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
-import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.HOME_STACK_ID;
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
-import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IDLE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
-import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
-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;
-import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
-import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
-import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
-import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
-import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
-import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
-import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
-import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
-import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
-import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
-import static com.android.server.am.ActivityStack.STACK_VISIBLE;
-import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
-import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
-import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
-import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
-import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
-import static com.android.server.wm.AppTransition.TRANSIT_DOCK_TASK_FROM_RECENTS;
-
-public final class ActivityStackSupervisor extends ConfigurationContainer
+public class ActivityStackSupervisor extends ConfigurationContainer
         implements DisplayListener {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
     private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS;
@@ -318,10 +316,10 @@
     final ArrayList<ActivityRecord> mWaitingVisibleActivities = new ArrayList<>();
 
     /** List of processes waiting to find out about the next visible activity. */
-    final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible = new ArrayList<>();
+    final ArrayList<WaitResult> mWaitingActivityVisible = new ArrayList<>();
 
     /** List of processes waiting to find out about the next launched activity. */
-    final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched = new ArrayList<>();
+    final ArrayList<WaitResult> mWaitingActivityLaunched = new ArrayList<>();
 
     /** List of activities that are ready to be stopped, but waiting for the next activity to
      * settle down before doing so. */
@@ -419,7 +417,7 @@
     }
 
     @Override
-    protected ConfigurationContainer getChildAt(int index) {
+    protected ActivityDisplay getChildAt(int index) {
         return mActivityDisplays.valueAt(index);
     }
 
@@ -428,6 +426,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;
@@ -459,6 +475,8 @@
      */
     boolean mIsDockMinimized;
 
+    final KeyguardController mKeyguardController;
+
     /**
      * Description of a request to start a new activity, which has been held
      * due to app switches being disabled.
@@ -496,6 +514,7 @@
         mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
         mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext);
         mResizeDockedStackTimeout = new ResizeDockedStackTimeout(service, this, mHandler);
+        mKeyguardController = new KeyguardController(service, this);
     }
 
     void setRecentTasks(RecentTasks recentTasks) {
@@ -544,6 +563,7 @@
     void setWindowManager(WindowManagerService wm) {
         synchronized (mService) {
             mWindowManager = wm;
+            mKeyguardController.setWindowManager(wm);
 
             mDisplayManager =
                     (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
@@ -567,11 +587,6 @@
         }
     }
 
-    void notifyActivityDrawnForKeyguard() {
-        if (DEBUG_LOCKSCREEN) mService.logLockScreen("");
-        mWindowManager.notifyActivityDrawnForKeyguard();
-    }
-
     ActivityStack getFocusedStack() {
         return mFocusedStack;
     }
@@ -1190,20 +1205,24 @@
             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);
+        }
+
+        if (mKeyguardController.isKeyguardLocked()) {
+            mWindowManager.notifyUnknownAppVisibilityLaunched(r.appToken);
         }
 
         r.app = app;
@@ -1926,7 +1945,7 @@
             return null;
         }
         // TODO(multi-display): Allow creating stacks on secondary displays.
-        return createStackOnDisplay(stackId, Display.DEFAULT_DISPLAY, createOnTop);
+        return createStackOnDisplay(stackId, DEFAULT_DISPLAY, createOnTop);
     }
 
     ArrayList<ActivityStack> getStacks() {
@@ -1937,6 +1956,10 @@
         return allStacks;
     }
 
+    ArrayList<ActivityStack> getStacksOnDefaultDisplay() {
+        return mActivityDisplays.valueAt(DEFAULT_DISPLAY).mStacks;
+    }
+
     ActivityRecord getHomeActivity() {
         return getHomeActivityForUser(mCurrentUser);
     }
@@ -1989,15 +2012,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,
@@ -2281,7 +2299,7 @@
 
         ActivityContainer activityContainer = new ActivityContainer(stackId);
         mActivityContainers.put(stackId, activityContainer);
-        activityContainer.attachToDisplayLocked(activityDisplay, onTop);
+        activityContainer.addToDisplayLocked(activityDisplay, onTop);
         return activityContainer.mStack;
     }
 
@@ -2345,6 +2363,40 @@
     }
 
     /**
+     * Move stack with all its existing content to specified display.
+     * @param stackId Id of stack to move.
+     * @param displayId Id of display to move stack to.
+     */
+    void moveStackToDisplayLocked(int stackId, int displayId) {
+        final ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
+        if (activityDisplay == null) {
+            throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown displayId="
+                    + displayId);
+        }
+        final ActivityContainer activityContainer = mActivityContainers.get(stackId);
+        if (activityContainer != null) {
+            if (activityContainer.isAttachedLocked()) {
+                if (activityContainer.getDisplayId() == displayId) {
+                    throw new IllegalArgumentException("Trying to move stackId=" + stackId
+                            + " to its current displayId=" + displayId);
+                }
+
+                activityContainer.moveToDisplayLocked(activityDisplay);
+            } else {
+                throw new IllegalStateException("moveStackToDisplayLocked: Stack with stackId="
+                        + stackId + " is not attached to any display.");
+            }
+        } else {
+            throw new IllegalArgumentException("moveStackToDisplayLocked: Unknown stackId="
+                    + stackId);
+        }
+
+        ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
+                !PRESERVE_WINDOWS);
+        // TODO(multi-display): resize stacks properly if moved from split-screen.
+    }
+
+    /**
      * Moves the specified task record to the input stack id.
      * WARNING: This method performs an unchecked/raw move of the task and
      * can leave the system in an unstable state if used incorrectly.
@@ -2567,7 +2619,7 @@
         resumeFocusedStackTopActivityLocked();
 
         mWindowManager.animateResizePinnedStack(bounds, -1);
-        mService.notifyActivityPinnedLocked();
+        mService.mTaskChangeNotificationController.notifyActivityPinned();
     }
 
     boolean moveFocusableActivityStackToFrontLocked(ActivityRecord r, String reason) {
@@ -2889,7 +2941,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
@@ -2906,14 +2958,19 @@
 
     void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
             boolean preserveWindows) {
-        // First the front stacks. In case any are not fullscreen and are in front of home.
-        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            final int topStackNdx = stacks.size() - 1;
-            for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = stacks.get(stackNdx);
-                stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows);
+        mKeyguardController.beginActivityVisibilityUpdate();
+        try {
+            // First the front stacks. In case any are not fullscreen and are in front of home.
+            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
+                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
+                final int topStackNdx = stacks.size() - 1;
+                for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
+                    final ActivityStack stack = stacks.get(stackNdx);
+                    stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows);
+                }
             }
+        } finally {
+            mKeyguardController.endActivityVisibilityUpdate();
         }
     }
 
@@ -3144,15 +3201,30 @@
         pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
         pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
         pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
-                final SparseArray<String[]> packages = mService.mLockTaskPackages;
-                if (packages.size() > 0) {
-                    pw.println(" mLockTaskPackages (userId:packages)=");
-                    for (int i = 0; i < packages.size(); ++i) {
-                        pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
-                        pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
-                    }
-                }
-                pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
+        final SparseArray<String[]> packages = mService.mLockTaskPackages;
+        if (packages.size() > 0) {
+            pw.print(prefix); pw.println("mLockTaskPackages (userId:packages)=");
+            for (int i = 0; i < packages.size(); ++i) {
+                pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
+                pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
+            }
+        }
+        pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
+        mKeyguardController.dump(pw, prefix);
+    }
+
+    /**
+     * 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());
+        }
     }
 
     /**
@@ -3393,10 +3465,6 @@
         mHandler.sendMessage(mHandler.obtainMessage(HANDLE_DISPLAY_CHANGED, displayId, 0));
     }
 
-    DisplayInfo getDisplayInfo(int displayId) {
-        return mActivityDisplays.get(displayId).mDisplayInfo;
-    }
-
     private void handleDisplayAdded(int displayId) {
         boolean newDisplay;
         synchronized (mService) {
@@ -3428,7 +3496,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);
             }
@@ -3447,10 +3515,10 @@
     }
 
     private StackInfo getStackInfoLocked(ActivityStack stack) {
-        final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
+        final ActivityDisplay display = mActivityDisplays.get(DEFAULT_DISPLAY);
         StackInfo info = new StackInfo();
         mWindowManager.getStackBounds(stack.mStackId, info.bounds);
-        info.displayId = Display.DEFAULT_DISPLAY;
+        info.displayId = DEFAULT_DISPLAY;
         info.stackId = stack.mStackId;
         info.userId = stack.mCurrentUser;
         info.visible = stack.getStackVisibilityLocked(null) == STACK_VISIBLE;
@@ -3551,7 +3619,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.
@@ -3559,8 +3627,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);
         }
     }
 
@@ -3997,22 +4065,33 @@
             }
         }
 
-        void attachToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) {
-            if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this
+        /**
+         * Adds the stack to specified display. Also calls WindowManager to do the same from
+         * {@link ActivityStack#addToDisplay(ActivityDisplay, boolean)}.
+         * @param activityDisplay The display to add the stack to.
+         * @param onTop If true the stack will be place at the top of the display, else at the
+         *              bottom.
+         */
+        void addToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) {
+            if (DEBUG_STACK) Slog.d(TAG_STACK, "addToDisplayLocked: " + this
                     + " to display=" + activityDisplay + " onTop=" + onTop);
+            if (mActivityDisplay != null) {
+                throw new IllegalStateException("ActivityContainer is already attached, " +
+                        "displayId=" + mActivityDisplay.mDisplayId);
+            }
             mActivityDisplay = activityDisplay;
-            mStack.attachDisplay(activityDisplay, onTop);
+            mStack.addToDisplay(activityDisplay, onTop);
             activityDisplay.attachActivities(mStack, onTop);
         }
 
         @Override
-        public void attachToDisplay(int displayId) {
+        public void addToDisplay(int displayId) {
             synchronized (mService) {
                 ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
                 if (activityDisplay == null) {
                     return;
                 }
-                attachToDisplayLocked(activityDisplay, true);
+                addToDisplayLocked(activityDisplay, true);
             }
         }
 
@@ -4068,14 +4147,42 @@
             }
         }
 
-        protected void detachLocked() {
-            if (DEBUG_STACK) Slog.d(TAG_STACK, "detachLocked: " + this + " from display="
+        /** Remove the stack completely. */
+        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();
+                removeFromDisplayLocked();
             }
+            mStack.remove();
+        }
+
+        /**
+         * Remove the stack from its current {@link ActivityDisplay}, so it can be either destroyed
+         * completely or re-parented.
+         */
+        private void removeFromDisplayLocked() {
+            if (DEBUG_STACK) Slog.d(TAG_STACK, "removeFromDisplayLocked: " + this
+                    + " current displayId=" + mActivityDisplay.mDisplayId);
+
+            mActivityDisplay.detachActivitiesLocked(mStack);
+            mActivityDisplay = null;
+        }
+
+        /**
+         * Move the stack to specified display.
+         * @param activityDisplay Target display to move the stack to.
+         */
+        void moveToDisplayLocked(ActivityDisplay activityDisplay) {
+            if (DEBUG_STACK) Slog.d(TAG_STACK, "moveToDisplayLocked: " + this + " from display="
+                    + mActivityDisplay + " to display=" + activityDisplay
+                    + " Callers=" + Debug.getCallers(2));
+
+            removeFromDisplayLocked();
+
+            mActivityDisplay = activityDisplay;
+            mStack.moveToDisplay(activityDisplay);
+            activityDisplay.attachActivities(mStack, ON_TOP);
         }
 
         @Override
@@ -4150,8 +4257,7 @@
         }
 
         void onTaskListEmptyLocked() {
-            detachLocked();
-            deleteActivityContainer(this);
+            removeLocked();
             mHandler.obtainMessage(CONTAINER_CALLBACK_TASK_LIST_EMPTY, this).sendToTarget();
         }
 
@@ -4198,7 +4304,7 @@
                         new VirtualActivityDisplay(width, height, density);
                 mActivityDisplay = virtualActivityDisplay;
                 mActivityDisplays.put(virtualActivityDisplay.mDisplayId, virtualActivityDisplay);
-                attachToDisplayLocked(virtualActivityDisplay, true);
+                addToDisplayLocked(virtualActivityDisplay, true);
             }
 
             if (mSurface != null) {
@@ -4257,7 +4363,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 */
@@ -4281,7 +4388,6 @@
         void init(Display display) {
             mDisplay = display;
             mDisplayId = display.getDisplayId();
-            mDisplay.getDisplayInfo(mDisplayInfo);
         }
 
         void attachActivities(ActivityStack stack, boolean onTop) {
@@ -4368,7 +4474,7 @@
 
     ActivityStack findStackBehind(ActivityStack stack) {
         // TODO(multi-display): We are only looking for stacks on the default display.
-        final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
+        final ActivityDisplay display = mActivityDisplays.get(DEFAULT_DISPLAY);
         if (display == null) {
             return null;
         }
@@ -4483,7 +4589,7 @@
     public List<IBinder> getTopVisibleActivities() {
         // TODO(multi-display): Get rid of DEFAULT_DISPLAY here. Used in
         // VoiceInteractionManagerServiceImpl#showSessionLocked.
-        final ActivityDisplay display = mActivityDisplays.get(Display.DEFAULT_DISPLAY);
+        final ActivityDisplay display = mActivityDisplays.get(DEFAULT_DISPLAY);
         if (display == null) {
             return Collections.EMPTY_LIST;
         }
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 20a14d3..e4ec169 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -81,11 +81,11 @@
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.app.IActivityContainer;
-import android.app.IActivityManager;
 import android.app.IApplicationThread;
 import android.app.KeyguardManager;
 import android.app.PendingIntent;
 import android.app.ProfilerInfo;
+import android.app.WaitResult;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.IIntentSender;
@@ -577,10 +577,6 @@
             ActivityStack targetStack) {
 
         if (result < START_SUCCESS) {
-            // If someone asked to have the keyguard dismissed on the next activity start,
-            // but we are not actually doing an activity switch...  just dismiss the keyguard now,
-            // because we probably want to see whatever is behind it.
-            mSupervisor.notifyActivityDrawnForKeyguard();
             return;
         }
 
@@ -631,7 +627,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;
         }
     }
@@ -711,7 +707,7 @@
             String callingPackage, Intent intent, String resolvedType,
             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
             IBinder resultTo, String resultWho, int requestCode, int startFlags,
-            ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult,
+            ProfilerInfo profilerInfo, WaitResult outResult,
             Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
             IActivityContainer iContainer, TaskRecord inTask) {
         // Refuse possible leaked file descriptors
@@ -1661,11 +1657,6 @@
     private void resumeTargetStackIfNeeded() {
         if (mDoResume) {
             mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions);
-            if (!mMovedToFront) {
-                // Make sure to notify Keyguard as well if we are not running an app transition
-                // later.
-                mSupervisor.notifyActivityDrawnForKeyguard();
-            }
         } else {
             ActivityOptions.abort(mOptions);
         }
diff --git a/services/core/java/com/android/server/am/ContentProviderRecord.java b/services/core/java/com/android/server/am/ContentProviderRecord.java
index dceadf4..7b9b659 100644
--- a/services/core/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/core/java/com/android/server/am/ContentProviderRecord.java
@@ -16,7 +16,7 @@
 
 package com.android.server.am;
 
-import android.app.IActivityManager.ContentProviderHolder;
+import android.app.ContentProviderHolder;
 import android.content.ComponentName;
 import android.content.IContentProvider;
 import android.content.pm.ApplicationInfo;
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
new file mode 100644
index 0000000..98acc9c
--- /dev/null
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -0,0 +1,269 @@
+/*
+ * 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 static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+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.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
+import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
+import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
+import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_GOING_AWAY;
+import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_OCCLUDE;
+import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_UNOCCLUDE;
+import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
+
+import com.android.server.wm.WindowManagerService;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Controls Keyguard occluding, dismissing and transitions depending on what kind of activities are
+ * currently visible.
+ * <p>
+ * Note that everything in this class should only be accessed with the AM lock being held.
+ */
+class KeyguardController {
+
+    private final ActivityManagerService mService;
+    private final ActivityStackSupervisor mStackSupervisor;
+    private WindowManagerService mWindowManager;
+    private boolean mKeyguardShowing;
+    private boolean mKeyguardGoingAway;
+    private boolean mOccluded;
+    private ActivityRecord mDismissingKeyguardActivity;
+    private int mBeforeUnoccludeTransit;
+    private int mVisibilityTransactionDepth;
+
+    KeyguardController(ActivityManagerService service,
+            ActivityStackSupervisor stackSupervisor) {
+        mService = service;
+        mStackSupervisor = stackSupervisor;
+    }
+
+    void setWindowManager(WindowManagerService windowManager) {
+        mWindowManager = windowManager;
+    }
+
+    /**
+     * @return true if Keyguard is showing, not going away, and not being occluded, false otherwise
+     */
+    boolean isKeyguardShowing() {
+        return mKeyguardShowing && !mKeyguardGoingAway && !mOccluded;
+    }
+
+    /**
+     * @return true if Keyguard is either showing or occluded, but not going away
+     */
+    boolean isKeyguardLocked() {
+        return mKeyguardShowing && !mKeyguardGoingAway;
+    }
+
+    /**
+     * Update the Keyguard showing state.
+     */
+    void setKeyguardShown(boolean showing) {
+        if (showing == mKeyguardShowing) {
+            return;
+        }
+        mKeyguardShowing = showing;
+        if (showing) {
+            mKeyguardGoingAway = false;
+
+            // Allow an activity to redismiss Keyguard.
+            mDismissingKeyguardActivity = null;
+        }
+        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+        mService.updateSleepIfNeededLocked();
+    }
+
+    /**
+     * Called when Keyguard is going away.
+     *
+     * @param flags See {@link android.view.WindowManagerPolicy#KEYGUARD_GOING_AWAY_FLAG_TO_SHADE}
+     *              etc.
+     */
+    void keyguardGoingAway(int flags) {
+        if (mKeyguardShowing) {
+            mWindowManager.deferSurfaceLayout();
+            try {
+                mKeyguardGoingAway = true;
+                mWindowManager.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
+                        false /* alwaysKeepCurrent */, convertTransitFlags(flags),
+                        false /* forceOverride */);
+                mWindowManager.keyguardGoingAway(flags);
+                mService.updateSleepIfNeededLocked();
+
+                // Some stack visibility might change (e.g. docked stack)
+                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+                mWindowManager.executeAppTransition();
+                mService.applyVrModeIfNeededLocked(mStackSupervisor.getResumedActivityLocked(),
+                        true /* enable */);
+            } finally {
+                mWindowManager.continueSurfaceLayout();
+            }
+        }
+    }
+
+    private int convertTransitFlags(int keyguardGoingAwayFlags) {
+        int result = 0;
+        if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_TO_SHADE) != 0) {
+            result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
+        }
+        if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS) != 0) {
+            result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
+        }
+        if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0) {
+            result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
+        }
+        return result;
+    }
+
+    /**
+     * Starts a batch of visibility updates.
+     */
+    void beginActivityVisibilityUpdate() {
+        mVisibilityTransactionDepth++;
+    }
+
+    /**
+     * Ends a batch of visibility updates. After all batches are done, this method makes sure to
+     * update lockscreen occluded/dismiss state if needed.
+     */
+    void endActivityVisibilityUpdate() {
+        mVisibilityTransactionDepth--;
+        if (mVisibilityTransactionDepth == 0) {
+            visibilitiesUpdated();
+        }
+    }
+
+    private void visibilitiesUpdated() {
+        final boolean lastOccluded = mOccluded;
+        final ActivityRecord lastDismissingKeyguardActivity = mDismissingKeyguardActivity;
+        mOccluded = false;
+        mDismissingKeyguardActivity = null;
+        final ArrayList<ActivityStack> stacks = mStackSupervisor.getStacksOnDefaultDisplay();
+        final int topStackNdx = stacks.size() - 1;
+        for (int stackNdx = topStackNdx; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = stacks.get(stackNdx);
+
+            // Only the very top activity may control occluded state
+            if (stackNdx == topStackNdx) {
+                mOccluded = stack.topActivityOccludesKeyguard();
+            }
+            if (mDismissingKeyguardActivity == null
+                    && stack.getTopDismissingKeyguardActivity() != null) {
+                mDismissingKeyguardActivity = stack.getTopDismissingKeyguardActivity();
+            }
+        }
+        mOccluded |= mWindowManager.isShowingDream();
+        if (mOccluded != lastOccluded) {
+            handleOccludedChanged();
+        }
+        if (mDismissingKeyguardActivity != lastDismissingKeyguardActivity) {
+            handleDismissKeyguard();
+        }
+    }
+
+    /**
+     * Called when occluded state changed.
+     */
+    private void handleOccludedChanged() {
+        mWindowManager.onKeyguardOccludedChanged(mOccluded);
+        if (isKeyguardLocked()) {
+            mWindowManager.deferSurfaceLayout();
+            try {
+                mWindowManager.prepareAppTransition(resolveOccludeTransit(),
+                        false /* alwaysKeepCurrent */, 0 /* flags */, true /* forceOverride */);
+                mService.updateSleepIfNeededLocked();
+                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+                mWindowManager.executeAppTransition();
+            } finally {
+                mWindowManager.continueSurfaceLayout();
+            }
+        }
+        dismissDockedStackIfNeeded();
+    }
+
+    /**
+     * Called when somebody might want to dismiss the Keyguard.
+     */
+    private void handleDismissKeyguard() {
+        if (mDismissingKeyguardActivity != null) {
+            mWindowManager.dismissKeyguard();
+
+            // If we are about to unocclude the Keyguard, but we can dismiss it without security,
+            // we immediately dismiss the Keyguard so the activity gets shown without a flicker.
+            if (mKeyguardShowing && canDismissKeyguard()
+                    && mWindowManager.getPendingAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE) {
+                mWindowManager.prepareAppTransition(mBeforeUnoccludeTransit,
+                        false /* alwaysKeepCurrent */, 0 /* flags */, true /* forceOverride */);
+                mKeyguardGoingAway = true;
+                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+                mWindowManager.executeAppTransition();
+            }
+        }
+    }
+
+    /**
+     * @return true if Keyguard can be currently dismissed without entering credentials.
+     */
+    private boolean canDismissKeyguard() {
+        return mWindowManager.isKeyguardTrusted() || !mWindowManager.isKeyguardSecure();
+    }
+
+    private int resolveOccludeTransit() {
+        if (mBeforeUnoccludeTransit != TRANSIT_UNSET
+                && mWindowManager.getPendingAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE
+                && mOccluded) {
+
+            // Reuse old transit in case we are occluding Keyguard again, meaning that we never
+            // actually occclude/unocclude Keyguard, but just run a normal transition.
+            return mBeforeUnoccludeTransit;
+        } else if (!mOccluded) {
+
+            // Save transit in case we dismiss/occlude Keyguard shortly after.
+            mBeforeUnoccludeTransit = mWindowManager.getPendingAppTransition();
+            return TRANSIT_KEYGUARD_UNOCCLUDE;
+        } else {
+            return TRANSIT_KEYGUARD_OCCLUDE;
+        }
+    }
+
+    private void dismissDockedStackIfNeeded() {
+        if (mKeyguardShowing && mOccluded) {
+            // The lock screen is currently showing, but is occluded by a window that can
+            // show on top of the lock screen. In this can we want to dismiss the docked
+            // stack since it will be complicated/risky to try to put the activity on top
+            // of the lock screen in the right fullscreen configuration.
+            mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
+                    mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
+        }
+    }
+
+    void dump(PrintWriter pw, String prefix) {
+        pw.println(prefix + "KeyguardController:");
+        pw.println(prefix + "  mKeyguardShowing=" + mKeyguardShowing);
+        pw.println(prefix + "  mKeyguardGoingAway=" + mKeyguardGoingAway);
+        pw.println(prefix + "  mOccluded=" + mOccluded);
+        pw.println(prefix + "  mDismissingKeyguardActivity=" + mDismissingKeyguardActivity);
+        pw.println(prefix + "  mVisibilityTransactionDepth=" + mVisibilityTransactionDepth);
+    }
+}
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..86e3ccc 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -56,8 +56,6 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
 import java.util.Objects;
 
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
@@ -89,7 +87,6 @@
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.am.ActivityManagerService.LOCK_SCREEN_SHOWN;
 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;
@@ -298,6 +295,7 @@
         setIntent(_intent, info);
         setMinDimensions(info);
         touchActiveTime();
+        mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
     }
 
     TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
@@ -329,6 +327,7 @@
         mTaskToReturnTo = HOME_ACTIVITY_TYPE;
         lastTaskDescription = _taskDescription;
         touchActiveTime();
+        mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
     }
 
     private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
@@ -383,6 +382,7 @@
         mPrivileged = privileged;
         mMinWidth = minWidth;
         mMinHeight = minHeight;
+        mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
     }
 
     void touchActiveTime() {
@@ -861,7 +861,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()) {
@@ -1697,7 +1697,7 @@
     /** Returns the bounds that should be used to launch this task. */
     Rect getLaunchBounds() {
         // If we're over lockscreen, forget about stack bounds and use fullscreen.
-        if (mService.mLockScreenShown == LOCK_SCREEN_SHOWN) {
+        if (mService.mStackSupervisor.mKeyguardController.isKeyguardShowing()) {
             return null;
         }
 
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 0f351f6..eb5e603 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -403,6 +403,7 @@
 
     /** Interface for UserManagerService. */
     private final UserManagerInternal mUserManagerInternal;
+    private final ActivityManagerInternal mActivityManagerInternal;
 
     private final UserRestrictionsListener mUserRestrictionsListener =
             new AudioServiceUserRestrictionsListener();
@@ -612,6 +613,7 @@
         mIsSingleVolume = AudioSystem.isSingleVolume(context);
 
         mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
+        mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
 
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
@@ -3109,14 +3111,28 @@
         boolean success =
             handleDeviceConnection(connected, outDevice, address, btDeviceName) &&
             handleDeviceConnection(connected, inDevice, address, btDeviceName);
-        if (success) {
-            synchronized (mScoClients) {
-                if (connected) {
-                    mBluetoothHeadsetDevice = btDevice;
-                } else {
-                    mBluetoothHeadsetDevice = null;
-                    resetBluetoothSco();
-                }
+
+        if (!success) {
+          return;
+        }
+
+        /* When one BT headset is disconnected while another BT headset
+         * is connected, don't mess with the headset device.
+         */
+        if ((state == BluetoothProfile.STATE_DISCONNECTED ||
+            state == BluetoothProfile.STATE_DISCONNECTING) &&
+            mBluetoothHeadset != null &&
+            mBluetoothHeadset.getAudioState(btDevice) == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
+            Log.w(TAG, "SCO connected through another device, returning");
+            return;
+        }
+
+        synchronized (mScoClients) {
+            if (connected) {
+                mBluetoothHeadsetDevice = btDevice;
+            } else {
+                mBluetoothHeadsetDevice = null;
+                resetBluetoothSco();
             }
         }
     }
@@ -3677,7 +3693,7 @@
 
     private void broadcastVibrateSetting(int vibrateType) {
         // Send broadcast
-        if (ActivityManagerNative.isSystemReady()) {
+        if (mActivityManagerInternal.isSystemReady()) {
             Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType);
             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType));
@@ -4046,21 +4062,23 @@
                 mIndexMap.put(device, index);
 
                 changed = oldIndex != index;
-                if (changed) {
-                    // Apply change to all streams using this one as alias
-                    // if changing volume of current device, also change volume of current
-                    // device on aliased stream
-                    boolean currentDevice = (device == getDeviceForStream(mStreamType));
-                    int numStreamTypes = AudioSystem.getNumStreamTypes();
-                    for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
-                        if (streamType != mStreamType &&
-                                mStreamVolumeAlias[streamType] == mStreamType) {
-                            int scaledIndex = rescaleIndex(index, mStreamType, streamType);
-                            mStreamStates[streamType].setIndex(scaledIndex, device, caller);
-                            if (currentDevice) {
-                                mStreamStates[streamType].setIndex(scaledIndex,
-                                        getDeviceForStream(streamType), caller);
-                            }
+                // Apply change to all streams using this one as alias if:
+                // - the index actually changed OR
+                // - there is no volume index stored for this device on alias stream.
+                // If changing volume of current device, also change volume of current
+                // device on aliased stream
+                final boolean currentDevice = (device == getDeviceForStream(mStreamType));
+                final int numStreamTypes = AudioSystem.getNumStreamTypes();
+                for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
+                    final VolumeStreamState aliasStreamState = mStreamStates[streamType];
+                    if (streamType != mStreamType &&
+                            mStreamVolumeAlias[streamType] == mStreamType &&
+                            (changed || !aliasStreamState.hasIndexForDevice(device))) {
+                        final int scaledIndex = rescaleIndex(index, mStreamType, streamType);
+                        aliasStreamState.setIndex(scaledIndex, device, caller);
+                        if (currentDevice) {
+                            aliasStreamState.setIndex(scaledIndex,
+                                    getDeviceForStream(streamType), caller);
                         }
                     }
                 }
@@ -4097,6 +4115,12 @@
             }
         }
 
+        public boolean hasIndexForDevice(int device) {
+            synchronized (VolumeStreamState.class) {
+                return (mIndexMap.get(device, -1) != -1);
+            }
+        }
+
         public int getMaxIndex() {
             return mIndexMax;
         }
@@ -5264,7 +5288,6 @@
                 state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
                                                BluetoothProfile.STATE_DISCONNECTED);
                 BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-
                 setBtScoDeviceConnectionState(btDevice, state);
             } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
                 boolean broadcast = false;
@@ -5412,8 +5435,7 @@
         // when the user switches back. For managed profiles, we should kill all recording apps
         ComponentName homeActivityName = null;
         if (!oldUser.isManagedProfile()) {
-            homeActivityName = LocalServices.getService(ActivityManagerInternal.class)
-                    .getHomeActivityForUser(oldUser.id);
+            homeActivityName = mActivityManagerInternal.getHomeActivityForUser(oldUser.id);
         }
         final String[] permissions = { Manifest.permission.RECORD_AUDIO };
         List<PackageInfo> packages;
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
index be68173..641c62f 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
@@ -19,10 +19,13 @@
 import android.content.Context;
 import android.net.ConnectivityMetricsEvent;
 import android.net.IIpConnectivityMetrics;
+import android.net.INetdEventCallback;
 import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.IpConnectivityLog;
+import android.os.Binder;
 import android.os.IBinder;
 import android.os.Parcelable;
+import android.os.Process;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
@@ -263,6 +266,33 @@
         private void enforcePermission(String what) {
             getContext().enforceCallingOrSelfPermission(what, "IpConnectivityMetrics");
         }
+
+        private void enforceNetdEventListeningPermission() {
+            final int uid = Binder.getCallingUid();
+            if (uid != Process.SYSTEM_UID) {
+                throw new SecurityException(String.format("Uid %d has no permission to listen for"
+                        + " netd events.", uid));
+            }
+        }
+
+        @Override
+        public boolean registerNetdEventCallback(INetdEventCallback callback) {
+            enforceNetdEventListeningPermission();
+            if (mNetdListener == null) {
+                return false;
+            }
+            return mNetdListener.registerNetdEventCallback(callback);
+        }
+
+        @Override
+        public boolean unregisterNetdEventCallback() {
+            enforceNetdEventListeningPermission();
+            if (mNetdListener == null) {
+                // if the service is null, we aren't registered anyway
+                return true;
+            }
+            return mNetdListener.unregisterNetdEventCallback();
+        }
     };
 
     private static final ToIntFunction<Context> READ_BUFFER_SIZE = (ctx) -> {
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/services/core/java/com/android/server/connectivity/MockableSystemProperties.java
similarity index 71%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to services/core/java/com/android/server/connectivity/MockableSystemProperties.java
index 5f66d16..4f68652 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/services/core/java/com/android/server/connectivity/MockableSystemProperties.java
@@ -14,6 +14,12 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package com.android.server.connectivity;
 
-parcelable PublishConfig;
+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/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
index 363d7cb..74a1f4f 100644
--- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
+++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
@@ -20,10 +20,12 @@
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.Network;
+import android.net.INetdEventCallback;
 import android.net.NetworkRequest;
 import android.net.metrics.DnsEvent;
 import android.net.metrics.IpConnectivityLog;
 import android.net.metrics.INetdEventListener;
+import android.os.RemoteException;
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
@@ -44,7 +46,7 @@
     public static final String SERVICE_NAME = "netd_listener";
 
     private static final String TAG = NetdEventListenerService.class.getSimpleName();
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
     private static final boolean VDBG = false;
 
     // TODO: read this constant from system property
@@ -86,7 +88,7 @@
             byte[] returnCodes = Arrays.copyOf(mReturnCodes, mEventCount);
             int[] latenciesMs = Arrays.copyOf(mLatenciesMs, mEventCount);
             mMetricsLog.log(new DnsEvent(mNetId, eventTypes, returnCodes, latenciesMs));
-            maybeLog(String.format("Logging %d results for netId %d", mEventCount, mNetId));
+            maybeLog("Logging %d results for netId %d", mEventCount, mNetId);
             mEventCount = 0;
         }
 
@@ -119,6 +121,21 @@
         }
     };
 
+    // Callback should only be registered/unregistered when logging is being enabled/disabled in DPM
+    // by the device owner. It's DevicePolicyManager's responsibility to ensure that.
+    @GuardedBy("this")
+    private INetdEventCallback mNetdEventCallback;
+
+    public synchronized boolean registerNetdEventCallback(INetdEventCallback callback) {
+        mNetdEventCallback = callback;
+        return true;
+    }
+
+    public synchronized boolean unregisterNetdEventCallback() {
+        mNetdEventCallback = null;
+        return true;
+    }
+
     public NetdEventListenerService(Context context) {
         this(context.getSystemService(ConnectivityManager.class), new IpConnectivityLog());
     }
@@ -136,9 +153,9 @@
     // Called concurrently by multiple binder threads.
     // This method must not block or perform long-running operations.
     public synchronized void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs,
-            String hostname, String[] ipAddresses, int ipAddressesCount, int uid) {
-        maybeVerboseLog(String.format("onDnsEvent(%d, %d, %d, %d)",
-                netId, eventType, returnCode, latencyMs));
+            String hostname, String[] ipAddresses, int ipAddressesCount, int uid)
+            throws RemoteException {
+        maybeVerboseLog("onDnsEvent(%d, %d, %d, %dms)", netId, eventType, returnCode, latencyMs);
 
         DnsEventBatch batch = mEventBatches.get(netId);
         if (batch == null) {
@@ -146,14 +163,23 @@
             mEventBatches.put(netId, batch);
         }
         batch.addResult((byte) eventType, (byte) returnCode, latencyMs);
+
+        if (mNetdEventCallback != null) {
+            mNetdEventCallback.onDnsEvent(hostname, ipAddresses, ipAddressesCount,
+                    System.currentTimeMillis(), uid);
+        }
     }
 
     @Override
     // Called concurrently by multiple binder threads.
     // This method must not block or perform long-running operations.
-    public synchronized void onConnectEvent(int netId, int latencyMs, String ipAddr, int port,
-            int uid) {
-        maybeVerboseLog(String.format("onConnectEvent(%d, %d)", netId, latencyMs));
+    public synchronized void onConnectEvent(int netId, int error, int latencyMs, String ipAddr, int port,
+            int uid) throws RemoteException {
+        maybeVerboseLog("onConnectEvent(%d, %d, %dms)", netId, error, latencyMs);
+
+        if (mNetdEventCallback != null) {
+            mNetdEventCallback.onConnectEvent(ipAddr, port, System.currentTimeMillis(), uid);
+        }
     }
 
     public synchronized void dump(PrintWriter writer) {
@@ -166,11 +192,11 @@
         pw.decreaseIndent();
     }
 
-    private static void maybeLog(String s) {
-        if (DBG) Log.d(TAG, s);
+    private static void maybeLog(String s, Object... args) {
+        if (DBG) Log.d(TAG, String.format(s, args));
     }
 
-    private static void maybeVerboseLog(String s) {
-        if (VDBG) Log.d(TAG, s);
+    private static void maybeVerboseLog(String s, Object... args) {
+        if (VDBG) Log.d(TAG, String.format(s, args));
     }
 }
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/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java
index 3072f43..393199d 100644
--- a/services/core/java/com/android/server/dreams/DreamController.java
+++ b/services/core/java/com/android/server/dreams/DreamController.java
@@ -44,6 +44,9 @@
 import java.io.PrintWriter;
 import java.util.NoSuchElementException;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
+
 /**
  * Internal controller for starting and stopping the current dream and managing related state.
  *
@@ -138,7 +141,7 @@
                     mCurrentDream.mCanDoze ? MetricsEvent.DOZING : MetricsEvent.DREAMING);
 
             try {
-                mIWindowManager.addWindowToken(token, WindowManager.LayoutParams.TYPE_DREAM);
+                mIWindowManager.addWindowToken(token, TYPE_DREAM, DEFAULT_DISPLAY);
             } catch (RemoteException ex) {
                 Slog.e(TAG, "Unable to add window token for dream.", ex);
                 stopDream(true /*immediate*/);
@@ -236,7 +239,7 @@
             oldDream.releaseWakeLockIfNeeded();
 
             try {
-                mIWindowManager.removeWindowToken(oldDream.mToken);
+                mIWindowManager.removeWindowToken(oldDream.mToken, DEFAULT_DISPLAY);
             } catch (RemoteException ex) {
                 Slog.w(TAG, "Error removing window token for dream.", ex);
             }
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index cda063d..49c4140 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -46,7 +46,9 @@
 import android.os.UserManager;
 import android.util.Slog;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.logging.MetricsLogger;
+import com.android.server.FgThread;
 import com.android.server.SystemService;
 
 import org.json.JSONArray;
@@ -111,6 +113,7 @@
     private Context mContext;
     private long mHalDeviceId;
     private int mFailedAttempts;
+    @GuardedBy("this")
     private IFingerprintDaemon mDaemon;
     private final PowerManager mPowerManager;
     private final AlarmManager mAlarmManager;
@@ -195,35 +198,41 @@
     public void binderDied() {
         Slog.v(TAG, "fingerprintd died");
         MetricsLogger.count(mContext, "fingerprintd_died", 1);
-        mDaemon = null;
+        synchronized (this) {
+            mDaemon = null;
+        }
         mCurrentUserId = UserHandle.USER_CURRENT;
         handleError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE);
     }
 
     public IFingerprintDaemon getFingerprintDaemon() {
-        if (mDaemon == null) {
-            mDaemon = IFingerprintDaemon.Stub.asInterface(ServiceManager.getService(FINGERPRINTD));
-            if (mDaemon != null) {
-                try {
-                    mDaemon.asBinder().linkToDeath(this, 0);
-                    mDaemon.init(mDaemonCallback);
-                    mHalDeviceId = mDaemon.openHal();
-                    if (mHalDeviceId != 0) {
-                        updateActiveGroup(ActivityManager.getCurrentUser(), null);
-                    } else {
-                        Slog.w(TAG, "Failed to open Fingerprint HAL!");
-                        MetricsLogger.count(mContext, "fingerprintd_openhal_error", 1);
-                        mDaemon = null;
+        synchronized (this) {
+            if (mDaemon == null) {
+                mDaemon = IFingerprintDaemon.Stub
+                        .asInterface(ServiceManager.getService(FINGERPRINTD));
+                if (mDaemon != null) {
+                    try {
+                        mDaemon.asBinder().linkToDeath(this, 0);
+                        mDaemon.init(mDaemonCallback);
+                        mHalDeviceId = mDaemon.openHal();
+                        if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId);
+                        if (mHalDeviceId != 0) {
+                            updateActiveGroup(ActivityManager.getCurrentUser(), null);
+                        } else {
+                            Slog.w(TAG, "Failed to open Fingerprint HAL!");
+                            MetricsLogger.count(mContext, "fingerprintd_openhal_error", 1);
+                            mDaemon = null;
+                        }
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "Failed to open fingeprintd HAL", e);
+                        mDaemon = null; // try again later!
                     }
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Failed to open fingeprintd HAL", e);
-                    mDaemon = null; // try again later!
+                } else {
+                    Slog.w(TAG, "fingerprint service not available");
                 }
-            } else {
-                Slog.w(TAG, "fingerprint service not available");
             }
+            return mDaemon;
         }
-        return mDaemon;
     }
 
     protected void handleEnumerate(long deviceId, int[] fingerIds, int[] groupIds) {
@@ -1005,8 +1014,7 @@
     @Override
     public void onStart() {
         publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper());
-        IFingerprintDaemon daemon = getFingerprintDaemon();
-        if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId);
+        FgThread.getHandler().post(() -> getFingerprintDaemon());
         listenForUserSwitches();
     }
 
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 970da99..a37dfed 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -824,7 +824,7 @@
             try {
                 ActivityManagerNative.getDefault().registerUidObserver(mUidObserver,
                         ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE
-                        | ActivityManager.UID_OBSERVER_IDLE);
+                        | ActivityManager.UID_OBSERVER_IDLE, null);
             } catch (RemoteException e) {
                 // ignored; both services live in system_server
             }
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index ae98077..45f54a9 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;
@@ -417,6 +415,12 @@
 
     private int mYearOfHardware = 0;
 
+    // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL
+    // stops output right at 600m/s, depriving this of the information of a device that reaches
+    // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases.
+    private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
+    private boolean mItarSpeedLimitExceeded = false;
+
     private final IGnssStatusProvider mGnssStatusProvider = new IGnssStatusProvider.Stub() {
         @Override
         public void registerGnssStatusCallback(IGnssStatusListener callback) {
@@ -520,42 +524,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);
@@ -1414,6 +1406,12 @@
             mStarted = true;
             mSingleShot = singleShot;
             mPositionMode = GPS_POSITION_MODE_STANDALONE;
+            // Notify about suppressed output, if speed limit was previously exceeded.
+            // Elsewhere, we check again with every speed output reported.
+            if (mItarSpeedLimitExceeded) {
+                Log.i(TAG, "startNavigating with ITAR limit in place. Output limited  " +
+                        "until slow enough speed reported.");
+            }
 
             boolean agpsEnabled =
                     (Settings.Global.getInt(mContext.getContentResolver(),
@@ -1500,7 +1498,17 @@
      * called from native code to update our position.
      */
     private void reportLocation(int flags, double latitude, double longitude, double altitude,
-            float speed, float bearing, float accuracy, long timestamp) {
+            float speedMetersPerSecond, float bearing, float accuracy, long timestamp) {
+        if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) {
+            mItarSpeedLimitExceeded = speedMetersPerSecond > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
+        }
+
+        if (mItarSpeedLimitExceeded) {
+            Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
+                    "  GPS/GNSS Navigation output blocked.");
+            return;  // No output of location allowed
+        }
+
         if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude +
                 " timestamp: " + timestamp);
 
@@ -1520,7 +1528,7 @@
                 mLocation.removeAltitude();
             }
             if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) {
-                mLocation.setSpeed(speed);
+                mLocation.setSpeed(speedMetersPerSecond);
             } else {
                 mLocation.removeSpeed();
             }
@@ -1704,23 +1712,29 @@
      * called from native code to report NMEA data received
      */
     private void reportNmea(long timestamp) {
-        int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);
-        String nmea = new String(mNmeaBuffer, 0 /* offset */, length);
-        mListenerHelper.onNmeaReceived(timestamp, nmea);
+        if (!mItarSpeedLimitExceeded) {
+            int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);
+            String nmea = new String(mNmeaBuffer, 0 /* offset */, length);
+            mListenerHelper.onNmeaReceived(timestamp, nmea);
+        }
     }
 
     /**
      * called from native code - Gps measurements callback
      */
     private void reportMeasurementData(GnssMeasurementsEvent event) {
-        mGnssMeasurementsProvider.onMeasurementsAvailable(event);
+        if (!mItarSpeedLimitExceeded) {
+            mGnssMeasurementsProvider.onMeasurementsAvailable(event);
+        }
     }
 
     /**
      * called from native code - GPS navigation message callback
      */
     private void reportNavigationMessage(GnssNavigationMessage event) {
-        mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
+        if (!mItarSpeedLimitExceeded) {
+            mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/net/NetworkIdentitySet.java b/services/core/java/com/android/server/net/NetworkIdentitySet.java
index 959a823..c48f430 100644
--- a/services/core/java/com/android/server/net/NetworkIdentitySet.java
+++ b/services/core/java/com/android/server/net/NetworkIdentitySet.java
@@ -91,6 +91,19 @@
         }
     }
 
+    /** @return whether any {@link NetworkIdentity} in this set is considered metered. */
+    public boolean isAnyMemberMetered() {
+        if (isEmpty()) {
+            return false;
+        }
+        for (NetworkIdentity ident : this) {
+            if (ident.getMetered()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /** @return whether any {@link NetworkIdentity} in this set is considered roaming. */
     public boolean isAnyMemberRoaming() {
         if (isEmpty()) {
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 2bccfee..d8103fc 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -611,7 +611,8 @@
 
             try {
                 mActivityManager.registerUidObserver(mUidObserver,
-                        ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE);
+                        ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE,
+                        null);
                 mNetworkManager.registerObserver(mAlertObserver);
             } catch (RemoteException e) {
                 // ignored; both services live in system_server
diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java
index 673dd8f..c45b416 100644
--- a/services/core/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java
@@ -17,6 +17,8 @@
 package com.android.server.net;
 
 import static android.net.NetworkStats.IFACE_ALL;
+import static android.net.NetworkStats.METERED_NO;
+import static android.net.NetworkStats.METERED_YES;
 import static android.net.NetworkStats.ROAMING_NO;
 import static android.net.NetworkStats.ROAMING_YES;
 import static android.net.NetworkStats.SET_ALL;
@@ -242,6 +244,7 @@
                 entry.uid = key.uid;
                 entry.set = key.set;
                 entry.tag = key.tag;
+                entry.metered = key.ident.isAnyMemberMetered() ? METERED_YES : METERED_NO;
                 entry.roaming = key.ident.isAnyMemberRoaming() ? ROAMING_YES : ROAMING_NO;
                 entry.rxBytes = historyEntry.rxBytes;
                 entry.rxPackets = historyEntry.rxPackets;
diff --git a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
index bcdeb66..31ed350 100644
--- a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
@@ -17,6 +17,7 @@
 package com.android.server.notification;
 
 import android.app.Notification;
+import android.app.NotificationManager;
 import android.content.Context;
 import android.service.notification.NotificationListenerService;
 import android.util.Log;
@@ -44,7 +45,7 @@
             return null;
         }
 
-        if (record.getImportance() >= NotificationListenerService.Ranking.IMPORTANCE_DEFAULT) {
+        if (record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT) {
             final Notification notification = record.getNotification();
             if ((notification.defaults & Notification.DEFAULT_VIBRATE) != 0 ||
                     notification.vibrate != null ||
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 4e50567..6ebdb3c 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -16,6 +16,8 @@
 
 package com.android.server.notification;
 
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
 import static android.service.notification.NotificationRankerService.REASON_APP_CANCEL;
 import static android.service.notification.NotificationRankerService.REASON_APP_CANCEL_ALL;
 import static android.service.notification.NotificationRankerService.REASON_CHANNEL_BANNED;
@@ -40,9 +42,9 @@
 import static android.service.notification.NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_ON;
 import static android.service.notification.NotificationListenerService.TRIM_FULL;
 import static android.service.notification.NotificationListenerService.TRIM_LIGHT;
-import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_DEFAULT;
-import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_NONE;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
 
 import android.Manifest;
@@ -975,6 +977,7 @@
         mUsageStats = new NotificationUsageStats(getContext());
         mRankingHandler = new RankingHandlerWorker(mRankingThread.getLooper());
         mRankingHelper = new RankingHelper(getContext(),
+                getContext().getPackageManager(),
                 mRankingHandler,
                 mUsageStats,
                 extractorNames);
@@ -1401,8 +1404,7 @@
                         }
 
                         Binder token = new Binder();
-                        mWindowManagerInternal.addWindowToken(token,
-                                WindowManager.LayoutParams.TYPE_TOAST);
+                        mWindowManagerInternal.addWindowToken(token, TYPE_TOAST, DEFAULT_DISPLAY);
                         record = new ToastRecord(callingPid, pkg, callback, duration, token);
                         mToastQueue.add(record);
                         index = mToastQueue.size() - 1;
@@ -1538,8 +1540,7 @@
         @Override
         public void setImportance(String pkg, int uid, int importance) {
             enforceSystemOrSystemUI("Caller not system or systemui");
-            setNotificationsEnabledForPackageImpl(pkg, uid,
-                    importance != NotificationListenerService.Ranking.IMPORTANCE_NONE);
+            setNotificationsEnabledForPackageImpl(pkg, uid, importance != IMPORTANCE_NONE);
             mRankingHelper.setImportance(pkg, uid, importance);
             savePolicyFile();
         }
@@ -1567,21 +1568,6 @@
         }
 
         @Override
-        public void updateNotificationChannel(String pkg, NotificationChannel channel) {
-            Preconditions.checkNotNull(channel);
-            Preconditions.checkNotNull(channel.getId());
-            checkCallerIsSystemOrSameApp(pkg);
-            if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
-                // cancel
-                cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channel.getId(), 0, 0, true,
-                        UserHandle.getUserId(Binder.getCallingUid()), REASON_CHANNEL_BANNED, null);
-            }
-            mRankingHelper.updateNotificationChannel(Binder.getCallingUid(), pkg,
-                    Binder.getCallingUid(), channel);
-            savePolicyFile();
-        }
-
-        @Override
         public NotificationChannel getNotificationChannel(String pkg, String channelId) {
             Preconditions.checkNotNull(channelId);
             checkCallerIsSystemOrSameApp(pkg);
@@ -1620,7 +1606,7 @@
                 cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channel.getId(), 0, 0, true,
                         UserHandle.getUserId(Binder.getCallingUid()), REASON_CHANNEL_BANNED, null);
             }
-            mRankingHelper.updateNotificationChannel(Binder.getCallingUid(), pkg, uid, channel);
+            mRankingHelper.updateNotificationChannel(pkg, uid, channel);
             savePolicyFile();
         }
 
@@ -2814,7 +2800,7 @@
 
         // setup local book-keeping
         final NotificationRecord r = new NotificationRecord(getContext(), n,
-                mRankingHelper.getNotificationChannel(pkg, callingUid,
+                mRankingHelper.getNotificationChannelWithFallback(pkg, callingUid,
                         n.getNotification().getNotificationChannel()));
         mHandler.post(new EnqueueNotificationRunnable(userId, r));
 
@@ -3022,7 +3008,8 @@
         final String key = record.getKey();
 
         // Should this notification make noise, vibe, or use the LED?
-        final boolean aboveThreshold = record.getImportance() >= IMPORTANCE_DEFAULT;
+        final boolean aboveThreshold =
+                record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT;
         final boolean canInterrupt = aboveThreshold && !record.isIntercepted();
         if (DBG || record.isIntercepted())
             Slog.v(TAG,
@@ -3076,8 +3063,8 @@
             } else if (notification.sound != null) {
                 soundUri = notification.sound;
                 hasValidSound = (soundUri != null);
-            } else if (record.getChannel().getDefaultRingtone() != null) {
-                soundUri = record.getChannel().getDefaultRingtone();
+            } else if (record.getChannel().getRingtone() != null) {
+                soundUri = record.getChannel().getRingtone();
                 hasValidSound = (soundUri != null);
             }
 
@@ -3094,9 +3081,7 @@
             // The DEFAULT_VIBRATE flag trumps any custom vibration AND the fallback.
             final boolean useDefaultVibrate =
                     (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
-
             final boolean hasChannelVibration = record.getChannel().shouldVibrate();
-
             hasValidVibrate = useDefaultVibrate || convertSoundToVibration ||
                     hasCustomVibrate || hasChannelVibration;
 
@@ -3269,7 +3254,7 @@
         }
 
         ToastRecord lastToast = mToastQueue.remove(index);
-        mWindowManagerInternal.removeWindowToken(lastToast.token, true);
+        mWindowManagerInternal.removeWindowToken(lastToast.token, true, DEFAULT_DISPLAY);
 
         keepProcessAliveIfNeededLocked(record.pid);
         if (mToastQueue.size() > 0) {
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index c5de93e..a1256db 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -15,12 +15,11 @@
  */
 package com.android.server.notification;
 
-import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_MIN;
-import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
-import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_DEFAULT;
-import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_HIGH;
-import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_LOW;
-import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_MAX;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
 
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -30,7 +29,6 @@
 import android.graphics.Bitmap;
 import android.graphics.drawable.Icon;
 import android.media.AudioAttributes;
-import android.net.Uri;
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
@@ -140,10 +138,8 @@
                 importance = IMPORTANCE_DEFAULT;
                 break;
             case Notification.PRIORITY_HIGH:
-                importance = IMPORTANCE_HIGH;
-                break;
             case Notification.PRIORITY_MAX:
-                importance = IMPORTANCE_MAX;
+                importance = IMPORTANCE_HIGH;
                 break;
         }
         stats.requestedImportance = importance;
@@ -153,7 +149,7 @@
                 || n.sound != null
                 || n.vibrate != null
                 || mNotificationChannel.shouldVibrate()
-                || mNotificationChannel.getDefaultRingtone() != null;
+                || mNotificationChannel.getRingtone() != null;
         stats.isNoisy = isNoisy;
 
         if (!isNoisy && importance > IMPORTANCE_LOW) {
@@ -167,7 +163,7 @@
         }
 
         if (n.fullScreenIntent != null) {
-            importance = IMPORTANCE_MAX;
+            importance = IMPORTANCE_HIGH;
         }
 
         stats.naturalImportance = importance;
@@ -319,10 +315,11 @@
     @Override
     public final String toString() {
         return String.format(
-                "NotificationRecord(0x%08x: pkg=%s user=%s id=%d tag=%s importance=%d key=%s: %s)",
+                "NotificationRecord(0x%08x: pkg=%s user=%s id=%d tag=%s importance=%d key=%s" +
+                        " channel=%s: %s)",
                 System.identityHashCode(this),
                 this.sbn.getPackageName(), this.sbn.getUser(), this.sbn.getId(),
-                this.sbn.getTag(), this.mImportance, this.sbn.getKey(),
+                this.sbn.getTag(), this.mImportance, this.sbn.getKey(), this.getChannel().getId(),
                 this.sbn.getNotification());
     }
 
@@ -384,7 +381,7 @@
     }
 
     private void applyUserImportance() {
-        if (mUserImportance != NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED) {
+        if (mUserImportance != IMPORTANCE_UNSPECIFIED) {
             mImportance = mUserImportance;
             mImportanceExplanation = getUserExplanation();
         }
@@ -395,7 +392,7 @@
     }
 
     public void setImportance(int importance, CharSequence explanation) {
-        if (importance != NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED) {
+        if (importance != IMPORTANCE_UNSPECIFIED) {
             mImportance = importance;
             mImportanceExplanation = explanation;
         }
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index 34c5283..e8cf6a1 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -16,7 +16,7 @@
 
 package com.android.server.notification;
 
-import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
 
 import android.app.Notification;
 import android.content.ContentValues;
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 2df4043..cb5fb0d 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -33,8 +33,10 @@
     int getImportance(String packageName, int uid);
 
     void createNotificationChannel(String pkg, int uid, NotificationChannel channel);
-    void updateNotificationChannel(int callingUid, String pkg, int uid, NotificationChannel channel);
+    void updateNotificationChannel(String pkg, int uid, NotificationChannel channel);
+    void updateNotificationChannelFromRanker(String pkg, int uid, NotificationChannel channel);
     NotificationChannel getNotificationChannel(String pkg, int uid, String channelId);
+    NotificationChannel getNotificationChannelWithFallback(String pkg, int uid, String channelId);
     void deleteNotificationChannel(String pkg, int uid, String channelId);
     ParceledListSlice<NotificationChannel> getNotificationChannels(String pkg, int uid);
 }
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index d59115e..1bb8b3b 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -15,12 +15,17 @@
  */
 package com.android.server.notification;
 
+import com.android.internal.R;
+
 import android.app.Notification;
 import android.app.NotificationChannel;
+import android.app.NotificationManager;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ParceledListSlice;
+import android.os.Build;
 import android.os.Process;
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerService.Ranking;
@@ -28,8 +33,6 @@
 import android.util.ArrayMap;
 import android.util.Slog;
 
-import com.android.internal.R;
-
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -63,8 +66,8 @@
     private static final String ATT_IMPORTANCE = "importance";
 
     private static final int DEFAULT_PRIORITY = Notification.PRIORITY_DEFAULT;
-    private static final int DEFAULT_VISIBILITY = Ranking.VISIBILITY_NO_OVERRIDE;
-    private static final int DEFAULT_IMPORTANCE = Ranking.IMPORTANCE_UNSPECIFIED;
+    private static final int DEFAULT_VISIBILITY = NotificationManager.VISIBILITY_NO_OVERRIDE;
+    private static final int DEFAULT_IMPORTANCE = NotificationManager.IMPORTANCE_UNSPECIFIED;
 
     private final NotificationSignalExtractor[] mSignalExtractors;
     private final NotificationComparator mPreliminaryComparator = new NotificationComparator();
@@ -76,11 +79,13 @@
 
     private final Context mContext;
     private final RankingHandler mRankingHandler;
+    private final PackageManager mPm;
 
-    public RankingHelper(Context context, RankingHandler rankingHandler,
+    public RankingHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
             NotificationUsageStats usageStats, String[] extractorNames) {
         mContext = context;
         mRankingHandler = rankingHandler;
+        mPm = pm;
 
         final int N = extractorNames.length;
         mSignalExtractors = new NotificationSignalExtractor[N];
@@ -131,7 +136,6 @@
 
     public void readXml(XmlPullParser parser, boolean forRestore)
             throws XmlPullParserException, IOException {
-        final PackageManager pm = mContext.getPackageManager();
         int type = parser.getEventType();
         if (type != XmlPullParser.START_TAG) return;
         String tag = parser.getName();
@@ -147,31 +151,22 @@
                 if (TAG_PACKAGE.equals(tag)) {
                     int uid = safeInt(parser, ATT_UID, Record.UNKNOWN_UID);
                     String name = parser.getAttributeValue(null, ATT_NAME);
-
                     if (!TextUtils.isEmpty(name)) {
                         if (forRestore) {
                             try {
                                 //TODO: http://b/22388012
-                                uid = pm.getPackageUidAsUser(name, UserHandle.USER_SYSTEM);
+                                uid = mPm.getPackageUidAsUser(name, UserHandle.USER_SYSTEM);
                             } catch (NameNotFoundException e) {
                                 // noop
                             }
                         }
-                        Record r = null;
-                        if (uid == Record.UNKNOWN_UID) {
-                            r = mRestoredWithoutUids.get(name);
-                            if (r == null) {
-                                r = new Record();
-                                r.pkg = name;
-                                mRestoredWithoutUids.put(name, r);
-                            }
-                        } else {
-                            r = getOrCreateRecord(name, uid);
-                        }
-                        r.importance = safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
-                        r.priority = safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY);
-                        r.visibility = safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
 
+                        Record r = getOrCreateRecord(name, uid,
+                                safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE),
+                                safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY),
+                                safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY));
+
+                        // Channels
                         final int innerDepth = parser.getDepth();
                         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                                 && (type != XmlPullParser.END_TAG
@@ -184,15 +179,19 @@
                             if (TAG_CHANNEL.equals(tagName)) {
                                 String id = parser.getAttributeValue(null, ATT_ID);
                                 CharSequence channelName = parser.getAttributeValue(null, ATT_NAME);
+                                int channelImportance =
+                                        safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
 
                                 if (!TextUtils.isEmpty(id)) {
-                                    final NotificationChannel channel =
-                                            new NotificationChannel(id, channelName);
+                                    final NotificationChannel channel = new NotificationChannel(id,
+                                            channelName, channelImportance);
                                     channel.populateFromXml(parser);
                                     r.channels.put(id, channel);
                                 }
                             }
                         }
+
+                        clampDefaultChannel(r);
                     }
                 }
             }
@@ -204,23 +203,81 @@
         return pkg + "|" + uid;
     }
 
-    private Record getOrCreateRecord(String pkg, int uid) {
+    private Record getRecord(String pkg, int uid) {
         final String key = recordKey(pkg, uid);
-        Record r = mRecords.get(key);
+        return mRecords.get(key);
+    }
+
+    private Record getOrCreateRecord(String pkg, int uid) {
+        return getOrCreateRecord(pkg, uid,
+                DEFAULT_IMPORTANCE, DEFAULT_PRIORITY, DEFAULT_VISIBILITY);
+    }
+
+    private Record getOrCreateRecord(String pkg, int uid, int importance, int priority,
+            int visibility) {
+        final String key = recordKey(pkg, uid);
+        Record r = (uid == Record.UNKNOWN_UID) ? mRestoredWithoutUids.get(pkg) : mRecords.get(key);
         if (r == null) {
             r = new Record();
             r.pkg = pkg;
             r.uid = uid;
-            NotificationChannel defaultChannel = createDefaultChannel();
-            r.channels.put(defaultChannel.getId(), defaultChannel);
-            mRecords.put(key, r);
+            r.importance = importance;
+            r.priority = priority;
+            r.visibility = visibility;
+            createDefaultChannelIfMissing(r);
+            if (r.uid == Record.UNKNOWN_UID) {
+                mRestoredWithoutUids.put(pkg, r);
+            } else {
+                mRecords.put(key, r);
+            }
+            clampDefaultChannel(r);
         }
         return r;
     }
 
-    private NotificationChannel createDefaultChannel() {
-        return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID,
-                mContext.getString(R.string.default_notification_channel_label));
+    // Clamp the importance level of the default channel for apps targeting the new SDK version,
+    // unless the user has already changed the importance.
+    private void clampDefaultChannel(Record r) {
+        try {
+            if (r.uid != Record.UNKNOWN_UID) {
+                int userId = UserHandle.getUserId(r.uid);
+                final ApplicationInfo applicationInfo =
+                        mPm.getApplicationInfoAsUser(r.pkg, 0, userId);
+                if (applicationInfo.targetSdkVersion > Build.VERSION_CODES.N_MR1) {
+                    final NotificationChannel defaultChannel =
+                            r.channels.get(NotificationChannel.DEFAULT_CHANNEL_ID);
+                    if ((defaultChannel.getUserLockedFields()
+                            & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0) {
+                        defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+                        updateConfig();
+                    }
+                }
+            }
+        } catch (NameNotFoundException e) {
+            // oh well.
+        }
+    }
+
+    private void createDefaultChannelIfMissing(Record r) {
+        if (!r.channels.containsKey(NotificationChannel.DEFAULT_CHANNEL_ID)) {
+            NotificationChannel channel;
+            channel = new NotificationChannel(
+                    NotificationChannel.DEFAULT_CHANNEL_ID,
+                    mContext.getString(R.string.default_notification_channel_label),
+                    r.importance);
+            channel.setBypassDnd(r.priority == Notification.PRIORITY_MAX);
+            channel.setLockscreenVisibility(r.visibility);
+            if (r.importance != NotificationManager.IMPORTANCE_UNSPECIFIED) {
+                channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+            }
+            if (r.priority != DEFAULT_PRIORITY) {
+                channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
+            }
+            if (r.visibility != DEFAULT_VISIBILITY) {
+                channel.lockFields(NotificationChannel.USER_LOCKED_VISIBILITY);
+            }
+            r.channels.put(channel.getId(), channel);
+        }
     }
 
     public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
@@ -397,6 +454,10 @@
                 mContext.getString(R.string.default_notification_channel_label))) {
             throw new IllegalArgumentException("Channel already exists");
         }
+        if (channel.getImportance() < NotificationManager.IMPORTANCE_NONE
+                || channel.getImportance() > NotificationManager.IMPORTANCE_MAX) {
+            throw new IllegalArgumentException("Invalid importance level");
+        }
         if (channel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) {
             channel.setLockscreenVisibility(Ranking.VISIBILITY_NO_OVERRIDE);
         }
@@ -405,17 +466,12 @@
     }
 
     @Override
-    public void updateNotificationChannel(int callingUid, String pkg, int uid,
-            NotificationChannel updatedChannel) {
+    public void updateNotificationChannel(String pkg, int uid, NotificationChannel updatedChannel) {
         Record r = getOrCreateRecord(pkg, uid);
         NotificationChannel channel = r.channels.get(updatedChannel.getId());
         if (channel == null) {
             throw new IllegalArgumentException("Channel does not exist");
         }
-        if (!isUidSystem(callingUid)) {
-            updatedChannel.setImportance(channel.getImportance());
-            updatedChannel.setName(channel.getName());
-        }
         if (updatedChannel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) {
             updatedChannel.setLockscreenVisibility(Ranking.VISIBILITY_NO_OVERRIDE);
         }
@@ -424,6 +480,57 @@
     }
 
     @Override
+    public void updateNotificationChannelFromRanker(String pkg, int uid,
+            NotificationChannel updatedChannel) {
+        Record r = getOrCreateRecord(pkg, uid);
+        NotificationChannel channel = r.channels.get(updatedChannel.getId());
+        if (channel == null) {
+            throw new IllegalArgumentException("Channel does not exist");
+        }
+
+        if ((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0) {
+            channel.setImportance(updatedChannel.getImportance());
+        }
+        if ((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_LIGHTS) == 0) {
+            channel.setLights(updatedChannel.shouldShowLights());
+        }
+        if ((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_PRIORITY) == 0) {
+            channel.setBypassDnd(updatedChannel.canBypassDnd());
+        }
+        if ((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_RINGTONE) == 0) {
+            channel.setRingtone(updatedChannel.getRingtone());
+        }
+        if ((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_VIBRATION) == 0) {
+            channel.setVibration(updatedChannel.shouldVibrate());
+        }
+        if ((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_VISIBILITY) == 0) {
+            if (updatedChannel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) {
+                channel.setLockscreenVisibility(Ranking.VISIBILITY_NO_OVERRIDE);
+            } else {
+                channel.setLockscreenVisibility(updatedChannel.getLockscreenVisibility());
+            }
+        }
+
+        r.channels.put(channel.getId(), channel);
+        updateConfig();
+    }
+
+    @Override
+    public NotificationChannel getNotificationChannelWithFallback(String pkg, int uid,
+            String channelId) {
+        Record r = getOrCreateRecord(pkg, uid);
+        if (channelId == null) {
+            channelId = NotificationChannel.DEFAULT_CHANNEL_ID;
+        }
+        NotificationChannel channel = r.channels.get(channelId);
+        if (channel != null) {
+            return channel;
+        } else {
+            return r.channels.get(NotificationChannel.DEFAULT_CHANNEL_ID);
+        }
+    }
+
+    @Override
     public NotificationChannel getNotificationChannel(String pkg, int uid, String channelId) {
         Record r = getOrCreateRecord(pkg, uid);
         if (channelId == null) {
@@ -434,8 +541,10 @@
 
     @Override
     public void deleteNotificationChannel(String pkg, int uid, String channelId) {
-        Record r = getOrCreateRecord(pkg, uid);
-        r.channels.remove(channelId);
+        Record r = getRecord(pkg, uid);
+        if (r != null) {
+            r.channels.remove(channelId);
+        }
     }
 
     @Override
@@ -446,7 +555,7 @@
         for (int i = 0; i < N; i++) {
             channels.add(r.channels.valueAt(i));
         }
-        return new ParceledListSlice<NotificationChannel>(channels);
+        return new ParceledListSlice<>(channels);
     }
 
     /**
@@ -459,11 +568,12 @@
     }
 
     public void setEnabled(String packageName, int uid, boolean enabled) {
-        boolean wasEnabled = getImportance(packageName, uid) != Ranking.IMPORTANCE_NONE;
+        boolean wasEnabled = getImportance(packageName, uid) != NotificationManager.IMPORTANCE_NONE;
         if (wasEnabled == enabled) {
             return;
         }
-        setImportance(packageName, uid, enabled ? DEFAULT_IMPORTANCE : Ranking.IMPORTANCE_NONE);
+        setImportance(packageName, uid,
+                enabled ? DEFAULT_IMPORTANCE : NotificationManager.IMPORTANCE_NONE);
     }
 
     public void dump(PrintWriter pw, String prefix, NotificationManagerService.DumpFilter filter) {
@@ -599,7 +709,7 @@
         ArrayMap<Integer, String> packageBans = new ArrayMap<>(N);
         for (int i = 0; i < N; i++) {
             final Record r = mRecords.valueAt(i);
-            if (r.importance == Ranking.IMPORTANCE_NONE) {
+            if (r.importance == NotificationManager.IMPORTANCE_NONE) {
                 packageBans.put(r.uid, r.pkg);
             }
         }
@@ -611,14 +721,13 @@
                 || mRestoredWithoutUids.isEmpty()) {
             return; // nothing to do
         }
-        final PackageManager pm = mContext.getPackageManager();
         boolean updated = false;
         for (String pkg : pkgList) {
             final Record r = mRestoredWithoutUids.get(pkg);
             if (r != null) {
                 try {
                     //TODO: http://b/22388012
-                    r.uid = pm.getPackageUidAsUser(r.pkg, UserHandle.USER_SYSTEM);
+                    r.uid = mPm.getPackageUidAsUser(r.pkg, UserHandle.USER_SYSTEM);
                     mRestoredWithoutUids.remove(pkg);
                     mRecords.put(recordKey(r.pkg, r.uid), r);
                     updated = true;
@@ -626,7 +735,15 @@
                     // noop
                 }
             }
+            try {
+                Record fullRecord = getRecord(pkg,
+                        mPm.getPackageUidAsUser(pkg, UserHandle.USER_SYSTEM));
+                if (fullRecord != null) {
+                    clampDefaultChannel(fullRecord);
+                }
+            } catch (NameNotFoundException e) {}
         }
+
         if (updated) {
             updateConfig();
         }
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 974d95d..ca77335 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1670,8 +1670,6 @@
             }
 
             final String packageName = res.pkg.applicationInfo.packageName;
-            Bundle extras = new Bundle(1);
-            extras.putInt(Intent.EXTRA_UID, res.uid);
 
             // Determine the set of users who are adding this package for
             // the first time vs. those who are seeing an update.
@@ -1701,11 +1699,14 @@
                 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
 
                 // Send added for users that see the package for the first time
-                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
-                        extras, 0 /*flags*/, null /*targetPackage*/,
-                        null /*finishedReceiver*/, firstUsers);
+                // sendPackageAddedForNewUsers also deals with system apps
+                int appId = UserHandle.getAppId(res.uid);
+                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
+                sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers);
 
                 // Send added for users that don't see the package for the first time
+                Bundle extras = new Bundle(1);
+                extras.putInt(Intent.EXTRA_UID, res.uid);
                 if (update) {
                     extras.putBoolean(Intent.EXTRA_REPLACING, true);
                 }
@@ -4083,6 +4084,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;
@@ -5417,15 +5423,23 @@
                             result.remove(xpResolveInfo);
                         }
                         if (result.size() == 0 && !addEphemeral) {
+                            // No result in current profile, but found candidate in parent user.
+                            // And we are not going to add emphemeral app, so we can return the
+                            // result straight away.
                             result.add(xpDomainInfo.resolveInfo);
                             return result;
                         }
+                    } else if (result.size() <= 1 && !addEphemeral) {
+                        // No result in parent user and <= 1 result in current profile, and we
+                        // are not going to add emphemeral app, so we can return the result without
+                        // further processing.
+                        return result;
                     }
-                    if (result.size() > 1 || addEphemeral) {
-                        result = filterCandidatesWithDomainPreferredActivitiesLPr(
-                                intent, flags, result, xpDomainInfo, userId);
-                        sortResult = true;
-                    }
+                    // We have more than one candidate (combining results from current and parent
+                    // profile), so we need filtering and sorting.
+                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
+                            intent, flags, result, xpDomainInfo, userId);
+                    sortResult = true;
                 }
             } else {
                 final PackageParser.Package pkg = mPackages.get(pkgName);
@@ -10109,6 +10123,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;
@@ -11766,31 +11788,57 @@
     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
             int userId) {
         final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
-        sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId);
+        sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId);
     }
 
-    private void sendPackageAddedForUser(String packageName, boolean isSystem,
-            int appId, int userId) {
+    private void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
+            int appId, int... userIds) {
+        if (ArrayUtils.isEmpty(userIds)) {
+            return;
+        }
         Bundle extras = new Bundle(1);
-        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId));
+        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
+        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
 
         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
-                packageName, extras, 0, null, null, new int[] {userId});
+                packageName, extras, 0, null, null, userIds);
+        if (isSystem) {
+            mHandler.post(() -> {
+                        for (int userId : userIds) {
+                            sendBootCompletedBroadcastToSystemApp(packageName, userId);
+                        }
+                    }
+            );
+        }
+    }
+
+    /**
+     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
+     * automatically without needing an explicit launch.
+     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
+     */
+    private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) {
+        // If user is not running, the app didn't miss any broadcast
+        if (!mUserManagerInternal.isUserRunning(userId)) {
+            return;
+        }
+        final IActivityManager am = ActivityManagerNative.getDefault();
         try {
-            IActivityManager am = ActivityManagerNative.getDefault();
-            if (isSystem && am.isUserRunning(userId, 0)) {
-                // The just-installed/enabled app is bundled on the system, so presumed
-                // to be able to run automatically without needing an explicit launch.
-                // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
-                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
-                        .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
-                        .setPackage(packageName);
-                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
+            // Deliver LOCKED_BOOT_COMPLETED first
+            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
+                    .setPackage(packageName);
+            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
+            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
+                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
+
+            // Deliver BOOT_COMPLETED only if user is unlocked
+            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
+                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
+                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
                         android.app.AppOpsManager.OP_NONE, null, false, false, userId);
             }
         } catch (RemoteException e) {
-            // shouldn't happen
-            Slog.w(TAG, "Unable to bootstrap installed package", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -15920,10 +15968,8 @@
                     ? appearedChildPackages.size() : 0;
             for (int i = 0; i < packageCount; i++) {
                 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
-                for (int userId : installedInfo.newUsers) {
-                    sendPackageAddedForUser(installedInfo.name, true,
-                            UserHandle.getAppId(installedInfo.uid), userId);
-                }
+                sendPackageAddedForNewUsers(installedInfo.name, true,
+                        UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers);
             }
         }
 
@@ -21215,6 +21261,11 @@
             PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
                     overridePolicy);
         }
+
+        @Override
+        public String getNameForUid(int uid) {
+            return PackageManagerService.this.getNameForUid(uid);
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index 2176eb1..442a4f4 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -65,8 +65,8 @@
     // Append privapp to existing seinfo label
     private static final String PRIVILEGED_APP_STR = ":privapp";
 
-    // Append autoplay to existing seinfo label
-    private static final String AUTOPLAY_APP_STR = ":autoplayapp";
+    // Append ephemeral to existing seinfo label
+    private static final String EPHEMERAL_APP_STR = ":ephemeralapp";
 
     /**
      * Load the mac_permissions.xml file containing all seinfo assignments used to
@@ -281,8 +281,8 @@
             }
         }
 
-        if (pkg.applicationInfo.isAutoPlayApp())
-            pkg.applicationInfo.seinfo += AUTOPLAY_APP_STR;
+        if (pkg.applicationInfo.isEphemeralApp())
+            pkg.applicationInfo.seinfo += EPHEMERAL_APP_STR;
 
         if (pkg.applicationInfo.isPrivilegedApp())
             pkg.applicationInfo.seinfo += PRIVILEGED_APP_STR;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 6d514e4..42cc3a8 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4263,7 +4263,6 @@
         ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS, "HAS_DOMAIN_URLS",
         ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE, "DEFAULT_TO_DEVICE_PROTECTED_STORAGE",
         ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE, "DIRECT_BOOT_AWARE",
-        ApplicationInfo.PRIVATE_FLAG_AUTOPLAY, "AUTOPLAY",
         ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE, "PARTIALLY_DIRECT_BOOT_AWARE",
         ApplicationInfo.PRIVATE_FLAG_EPHEMERAL, "EPHEMERAL",
         ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER, "REQUIRED_FOR_SYSTEM_USER",
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index d558b07..38d69ed 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -635,7 +635,11 @@
                 return false; // Shouldn't happen.
             }
 
-            if (!isNewApp && !forceRescan) {
+            // Always scan the settings app, since its version code is the same for DR and MR1.
+            // TODO Fix it properly: b/32554059
+            final boolean isSettings = "com.android.settings".equals(getPackageName());
+
+            if (!isNewApp && !forceRescan && !isSettings) {
                 // Return if the package hasn't changed, ie:
                 // - version code hasn't change
                 // - lastUpdateTime hasn't change
@@ -652,6 +656,11 @@
                     return false;
                 }
             }
+            if (isSettings) {
+                if (ShortcutService.DEBUG) {
+                    Slog.d(TAG, "Always scan settings.");
+                }
+            }
         } finally {
             s.logDurationStat(Stats.PACKAGE_UPDATE_CHECK, start);
         }
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 19bf751..37acf5c 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -239,10 +239,19 @@
 
     private static List<ResolveInfo> EMPTY_RESOLVE_INFO = new ArrayList<>(0);
 
-    private static Predicate<ResolveInfo> ACTIVITY_NOT_EXPORTED =
-            ri -> !ri.activityInfo.exported;
+    // Temporarily reverted to anonymous inner class form due to: b/32554459
+    private static Predicate<ResolveInfo> ACTIVITY_NOT_EXPORTED = new Predicate<ResolveInfo>() {
+        public boolean test(ResolveInfo ri) {
+            return !ri.activityInfo.exported;
+        }
+    };
 
-    private static Predicate<PackageInfo> PACKAGE_NOT_INSTALLED = pi -> !isInstalled(pi);
+    // Temporarily reverted to anonymous inner class form due to: b/32554459
+    private static Predicate<PackageInfo> PACKAGE_NOT_INSTALLED = new Predicate<PackageInfo>() {
+        public boolean test(PackageInfo pi) {
+            return !isInstalled(pi);
+        }
+    };
 
     private final Handler mHandler;
 
@@ -3668,7 +3677,7 @@
     @VisibleForTesting
     void injectRegisterUidObserver(IUidObserver observer, int which) {
         try {
-            ActivityManagerNative.getDefault().registerUidObserver(observer, which);
+            ActivityManagerNative.getDefault().registerUidObserver(observer, which, null);
         } catch (RemoteException shouldntHappen) {
         }
     }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index efd6f46..67488ce 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1487,8 +1487,7 @@
         // Skip over users being removed
         for (int i = 0; i < totalUserCount; i++) {
             UserInfo user = mUsers.valueAt(i).info;
-            if (!mRemovingUserIds.get(user.id)
-                    && !user.isGuest() && !user.partial) {
+            if (!mRemovingUserIds.get(user.id) && !user.isGuest()) {
                 aliveUserCount++;
             }
         }
@@ -2483,13 +2482,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 +3570,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..b7067d2 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -25,13 +25,83 @@
 import static android.content.res.Configuration.EMPTY;
 import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
 import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
-import static android.view.WindowManager.DOCKED_TOP;
 import static android.view.WindowManager.DOCKED_LEFT;
 import static android.view.WindowManager.DOCKED_RIGHT;
+import static android.view.WindowManager.DOCKED_TOP;
 import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
+import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
+import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+import static android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+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.LAST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.LAST_SYSTEM_WINDOW;
+import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
+import static android.view.WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
+import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
+import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
+import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
+import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
+import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
+import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
+import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
+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_SYSTEM_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
+import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
+import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
 import static android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION;
-import static android.view.WindowManager.LayoutParams.*;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED;
@@ -39,6 +109,7 @@
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
 
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManager.StackId;
 import android.app.ActivityManagerInternal;
@@ -112,10 +183,10 @@
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
+import android.util.LongSparseArray;
 import android.util.MutableBoolean;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.util.LongSparseArray;
 import android.view.Display;
 import android.view.Gravity;
 import android.view.HapticFeedbackConstants;
@@ -133,19 +204,21 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
 import android.view.WindowManagerGlobal;
 import android.view.WindowManagerInternal;
+import android.view.WindowManagerInternal.AppTransitionListener;
 import android.view.WindowManagerPolicy;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.animation.Animation;
 import android.view.animation.AnimationSet;
 import android.view.animation.AnimationUtils;
+
 import com.android.internal.R;
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.logging.MetricsLogger;
-import com.android.internal.policy.PhoneWindow;
 import com.android.internal.policy.IShortcutService;
+import com.android.internal.policy.PhoneWindow;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.ScreenShapeHelper;
 import com.android.internal.widget.PointerLocationView;
@@ -154,12 +227,12 @@
 import com.android.server.policy.keyguard.KeyguardServiceDelegate;
 import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener;
 import com.android.server.statusbar.StatusBarManagerInternal;
+import com.android.server.wm.AppTransition;
 
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.util.HashSet;
 import java.util.List;
 
 /**
@@ -280,8 +353,6 @@
     /**
      * Keyguard stuff
      */
-    private WindowState mKeyguardScrim;
-    private boolean mKeyguardHidden;
     private boolean mKeyguardDrawnOnce;
 
     /* Table of Application Launch keys.  Maps from key codes to intent categories.
@@ -582,54 +653,23 @@
     WindowState mTopFullscreenOpaqueOrDimmingWindowState;
     WindowState mTopDockedOpaqueWindowState;
     WindowState mTopDockedOpaqueOrDimmingWindowState;
-    HashSet<IApplicationToken> mAppsToBeHidden = new HashSet<IApplicationToken>();
-    HashSet<IApplicationToken> mAppsThatDismissKeyguard = new HashSet<IApplicationToken>();
     boolean mTopIsFullscreen;
     boolean mForceStatusBar;
     boolean mForceStatusBarFromKeyguard;
     private boolean mForceStatusBarTransparent;
     int mNavBarOpacityMode = NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED;
-    boolean mHideLockScreen;
     boolean mForcingShowNavBar;
     int mForcingShowNavBarLayer;
 
-    // States of keyguard dismiss.
-    private static final int DISMISS_KEYGUARD_NONE = 0; // Keyguard not being dismissed.
-    private static final int DISMISS_KEYGUARD_START = 1; // Keyguard needs to be dismissed.
-    private static final int DISMISS_KEYGUARD_CONTINUE = 2; // Keyguard has been dismissed.
-    int mDismissKeyguard = DISMISS_KEYGUARD_NONE;
+    private boolean mPendingKeyguardOccluded;
+    private boolean mKeyguardOccludedChanged;
 
-    /**
-     * Indicates that we asked the Keyguard to be dismissed and we just wait for the Keyguard to
-     * dismiss itself.
-     */
-    @GuardedBy("Lw")
-    private boolean mCurrentlyDismissingKeyguard;
-
-    /** The window that is currently dismissing the keyguard. Dismissing the keyguard must only
-     * be done once per window. */
-    private WindowState mWinDismissingKeyguard;
-
-    /** When window is currently dismissing the keyguard, dismissing the keyguard must handle
-     * the keygaurd secure state change instantly case, e.g. the use case of inserting a PIN
-     * lock SIM card. This variable is used to record the previous keyguard secure state for
-     * monitoring secure state change on window dismissing keyguard. */
-    private boolean mSecureDismissingKeyguard;
-
-    /** The window that is currently showing "over" the keyguard. If there is an app window
-     * belonging to another app on top of this the keyguard shows. If there is a fullscreen
-     * app window under this, still dismiss the keyguard but don't show the app underneath. Show
-     * the wallpaper. */
-    private WindowState mWinShowWhenLocked;
-
-    boolean mShowingLockscreen;
     boolean mShowingDream;
+    private boolean mLastShowingDream;
     boolean mDreamingLockscreen;
     boolean mDreamingSleepTokenNeeded;
     SleepToken mDreamingSleepToken;
     SleepToken mScreenOffSleepToken;
-    boolean mKeyguardSecure;
-    boolean mKeyguardSecureIncludingHidden;
     volatile boolean mKeyguardOccluded;
     boolean mHomePressed;
     boolean mHomeConsumed;
@@ -1044,6 +1084,7 @@
     }
 
     private void interceptBackKeyDown() {
+        MetricsLogger.count(mContext, "key_back_down", 1);
         // Reset back key state for long press
         mBackKeyHandled = false;
 
@@ -1911,6 +1952,19 @@
 
         mWindowManagerInternal.registerAppTransitionListener(
                 mStatusBarController.getAppTransitionListener());
+        mWindowManagerInternal.registerAppTransitionListener(new AppTransitionListener() {
+            @Override
+            public int onAppTransitionStartingLocked(int transit, IBinder openToken,
+                    IBinder closeToken,
+                    Animation openAnimation, Animation closeAnimation) {
+                return handleStartTransitionForKeyguardLw(transit, openAnimation);
+            }
+
+            @Override
+            public void onAppTransitionCancelledLocked(int transit) {
+                handleStartTransitionForKeyguardLw(transit, null /* transit */);
+            }
+        });
     }
 
     /**
@@ -2225,6 +2279,7 @@
             case TYPE_DREAM:
             case TYPE_INPUT_METHOD:
             case TYPE_WALLPAPER:
+            case TYPE_PRESENTATION:
             case TYPE_PRIVATE_PRESENTATION:
             case TYPE_VOICE_INTERACTION:
             case TYPE_ACCESSIBILITY_OVERLAY:
@@ -2316,7 +2371,6 @@
             case TYPE_BOOT_PROGRESS:
             case TYPE_DISPLAY_OVERLAY:
             case TYPE_INPUT_CONSUMER:
-            case TYPE_KEYGUARD_SCRIM:
             case TYPE_KEYGUARD_DIALOG:
             case TYPE_MAGNIFICATION_OVERLAY:
             case TYPE_NAVIGATION_BAR:
@@ -2330,6 +2384,7 @@
             case TYPE_STATUS_BAR_SUB_PANEL:
             case TYPE_SYSTEM_DIALOG:
             case TYPE_VOLUME_OVERLAY:
+            case TYPE_PRESENTATION:
             case TYPE_PRIVATE_PRESENTATION:
             case TYPE_DOCK_DIVIDER:
                 break;
@@ -2357,7 +2412,7 @@
                 // remove the wallpaper and keyguard flag so that any change in-flight after setting
                 // the keyguard as occluded wouldn't set these flags again.
                 // See {@link #processKeyguardSetHiddenResultLw}.
-                if (mKeyguardHidden) {
+                if (mKeyguardOccluded) {
                     attrs.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
                     attrs.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
                 }
@@ -2494,10 +2549,11 @@
             return 2;
         }
         switch (type) {
-        case TYPE_PRIVATE_PRESENTATION:
-            return 2;
         case TYPE_WALLPAPER:
             // wallpaper is at the bottom, though the window manager may move it.
+            return 1;
+        case TYPE_PRESENTATION:
+        case TYPE_PRIVATE_PRESENTATION:
             return 2;
         case TYPE_DOCK_DIVIDER:
             return 2;
@@ -2533,9 +2589,6 @@
         case TYPE_INPUT_METHOD_DIALOG:
             // on-screen keyboards and other such input method user interfaces go here.
             return 13;
-        case TYPE_KEYGUARD_SCRIM:
-            // the safety window that shows behind keyguard while keyguard is starting
-            return 14;
         case TYPE_STATUS_BAR_SUB_PANEL:
             return 15;
         case TYPE_STATUS_BAR:
@@ -2673,26 +2726,17 @@
     }
 
     @Override
-    public boolean isForceHiding(WindowManager.LayoutParams attrs) {
-        return (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
-                (isKeyguardHostWindow(attrs) &&
-                        (mKeyguardDelegate != null && mKeyguardDelegate.isShowing())) ||
-                (attrs.type == TYPE_KEYGUARD_SCRIM);
-    }
-
-    @Override
     public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) {
         return attrs.type == TYPE_STATUS_BAR;
     }
 
     @Override
-    public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) {
-        switch (attrs.type) {
+    public boolean canBeHiddenByKeyguardLw(WindowState win) {
+        switch (win.getAttrs().type) {
             case TYPE_STATUS_BAR:
             case TYPE_NAVIGATION_BAR:
             case TYPE_WALLPAPER:
             case TYPE_DREAM:
-            case TYPE_KEYGUARD_SCRIM:
                 return false;
             default:
                 // Hide only windows below the keyguard host window.
@@ -2701,9 +2745,34 @@
         }
     }
 
-    @Override
-    public WindowState getWinShowWhenLockedLw() {
-        return mWinShowWhenLocked;
+    private boolean shouldBeHiddenByKeyguard(WindowState win, WindowState imeTarget) {
+
+        // Keyguard visibility of window from activities are determined over activity visibility.
+        if (win.getAppToken() != null) {
+            return false;
+        }
+
+        final LayoutParams attrs = win.getAttrs();
+        final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleLw() &&
+                ((imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0
+                        || !canBeHiddenByKeyguardLw(imeTarget));
+
+        // Show IME over the keyguard if the target allows it
+        boolean allowWhenLocked = (win.isInputMethodWindow() || imeTarget == this)
+                && showImeOverKeyguard;;
+
+        if (isKeyguardLocked() && isKeyguardOccluded()) {
+            // Show SHOW_WHEN_LOCKED windows if Keyguard is occluded.
+            allowWhenLocked |= (attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0
+                    // Show error dialogs over apps that are shown on lockscreen
+                    || (attrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0;
+        }
+
+        boolean keyguardLocked = isKeyguardLocked();
+        boolean hideDockDivider = attrs.type == TYPE_DOCK_DIVIDER
+                && !mWindowManagerInternal.isStackVisible(DOCKED_STACK_ID);
+        return (keyguardLocked && !allowWhenLocked && win.getDisplayId() == Display.DEFAULT_DISPLAY)
+                || hideDockDivider;
     }
 
     /** {@inheritDoc} */
@@ -2771,7 +2840,7 @@
                 // Assumes it's safe to show starting windows of launched apps while
                 // the keyguard is being hidden. This is okay because starting windows never show
                 // secret information.
-                if (mKeyguardHidden) {
+                if (mKeyguardOccluded) {
                     windowFlags |= FLAG_SHOW_WHEN_LOCKED;
                 }
             }
@@ -2904,12 +2973,6 @@
                         android.Manifest.permission.STATUS_BAR_SERVICE,
                         "PhoneWindowManager");
                 break;
-            case TYPE_KEYGUARD_SCRIM:
-                if (mKeyguardScrim != null) {
-                    return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
-                }
-                mKeyguardScrim = win;
-                break;
         }
         return WindowManagerGlobal.ADD_OKAY;
     }
@@ -2920,11 +2983,7 @@
         if (mStatusBar == win) {
             mStatusBar = null;
             mStatusBarController.setWindow(null);
-            mKeyguardDelegate.showScrim();
-        } else if (mKeyguardScrim == win) {
-            Log.v(TAG, "Removing keyguard scrim");
-            mKeyguardScrim = null;
-        } if (mNavigationBar == win) {
+        } else if (mNavigationBar == win) {
             mNavigationBar = null;
             mNavigationBarController.setWindow(null);
         }
@@ -3081,7 +3140,7 @@
     }
 
     @Override
-    public Animation createForceHideEnterAnimation(boolean onWallpaper,
+    public Animation createHiddenByKeyguardExit(boolean onWallpaper,
             boolean goingToNotificationShade) {
         if (goingToNotificationShade) {
             return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_behind_enter_fade_in);
@@ -3102,7 +3161,7 @@
 
 
     @Override
-    public Animation createForceHideWallpaperExitAnimation(boolean goingToNotificationShade) {
+    public Animation createKeyguardWallpaperExit(boolean goingToNotificationShade) {
         if (goingToNotificationShade) {
             return null;
         } else {
@@ -3236,8 +3295,7 @@
             WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
             if (attrs != null) {
                 final int type = attrs.type;
-                if (type == WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM
-                        || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
+                if (type == TYPE_KEYGUARD_DIALOG
                         || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                     // the "app" is keyguard, so give it the key
                     return 0;
@@ -3703,12 +3761,35 @@
     }
 
     @Override
-    public boolean canShowDismissingWindowWhileLockedLw() {
-        // If the keyguard is trusted, it will unlock without a challenge. Therefore, if we are in
-        // the process of dismissing Keyguard, we don't need to hide them as the phone will be
-        // unlocked right away in any case.
-        return mKeyguardDelegate != null && mKeyguardDelegate.isTrusted()
-                && mCurrentlyDismissingKeyguard;
+    public void onKeyguardOccludedChangedLw(boolean occluded) {
+        if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
+            mPendingKeyguardOccluded = occluded;
+            mKeyguardOccludedChanged = true;
+        } else {
+            setKeyguardOccludedLw(occluded);
+        }
+    }
+
+    private int handleStartTransitionForKeyguardLw(int transit, @Nullable Animation anim) {
+        if (mKeyguardOccludedChanged) {
+            if (DEBUG_KEYGUARD) Slog.d(TAG, "transition/occluded changed occluded="
+                    + mPendingKeyguardOccluded);
+            mKeyguardOccludedChanged = false;
+            if (setKeyguardOccludedLw(mPendingKeyguardOccluded)) {
+                return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_WALLPAPER;
+            }
+        }
+        if (AppTransition.isKeyguardGoingAwayTransit(transit)) {
+            if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation");
+            final long startTime = anim != null
+                    ? SystemClock.uptimeMillis() + anim.getStartOffset()
+                    : SystemClock.uptimeMillis();
+            final long duration = anim != null
+                    ? anim.getDuration()
+                    : 0;
+            startKeyguardExitAnimation(startTime, duration);
+        }
+        return 0;
     }
 
     private void launchAssistLongPressAction() {
@@ -3853,7 +3934,7 @@
                 return;
             }
 
-            if (!mHideLockScreen && mKeyguardDelegate.isInputRestricted()) {
+            if (!mKeyguardOccluded && mKeyguardDelegate.isInputRestricted()) {
                 // when in keyguard restricted mode, must first verify unlock
                 // before launching home
                 mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() {
@@ -4166,7 +4247,7 @@
             boolean immersiveSticky = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
             boolean navAllowedHidden = immersive || immersiveSticky;
             navTranslucent &= !immersiveSticky;  // transient trumps translucent
-            boolean isKeyguardShowing = isStatusBarKeyguard() && !mHideLockScreen;
+            boolean isKeyguardShowing = isStatusBarKeyguard() && !mKeyguardOccluded;
             if (!isKeyguardShowing) {
                 navTranslucent &= areTranslucentBarsAllowed();
             }
@@ -5008,12 +5089,12 @@
 
         // Dock windows carve out the bottom of the screen, so normal windows
         // can't appear underneath them.
-        if (attrs.type == TYPE_INPUT_METHOD && win.isVisibleOrBehindKeyguardLw()
-                && win.isDisplayedLw() && !win.getGivenInsetsPendingLw()) {
+        if (attrs.type == TYPE_INPUT_METHOD && win.isVisibleLw()
+                && !win.getGivenInsetsPendingLw()) {
             setLastInputMethodWindowLw(null, null);
             offsetInputMethodWindowLw(win);
         }
-        if (attrs.type == TYPE_VOICE_INTERACTION && win.isVisibleOrBehindKeyguardLw()
+        if (attrs.type == TYPE_VOICE_INTERACTION && win.isVisibleLw()
                 && !win.getGivenInsetsPendingLw()) {
             offsetVoiceInputWindowLw(win);
         }
@@ -5073,41 +5154,31 @@
         mTopFullscreenOpaqueOrDimmingWindowState = null;
         mTopDockedOpaqueWindowState = null;
         mTopDockedOpaqueOrDimmingWindowState = null;
-        mAppsToBeHidden.clear();
-        mAppsThatDismissKeyguard.clear();
         mForceStatusBar = false;
         mForceStatusBarFromKeyguard = false;
         mForceStatusBarTransparent = false;
         mForcingShowNavBar = false;
         mForcingShowNavBarLayer = -1;
 
-        mHideLockScreen = false;
         mAllowLockscreenWhenOn = false;
-        mDismissKeyguard = DISMISS_KEYGUARD_NONE;
-        mShowingLockscreen = false;
         mShowingDream = false;
-        mWinShowWhenLocked = null;
-        mKeyguardSecure = isKeyguardSecure(mCurrentUserId);
-        mKeyguardSecureIncludingHidden = mKeyguardSecure
-                && (mKeyguardDelegate != null && mKeyguardDelegate.isShowing());
     }
 
     /** {@inheritDoc} */
     @Override
     public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs,
-            WindowState attached) {
-        if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw="
-                + win.isVisibleOrBehindKeyguardLw());
+            WindowState attached, WindowState imeTarget) {
+        final boolean visible = win.isVisibleLw();
+        if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisible=" + visible);
+        applyKeyguardPolicyLw(win, imeTarget);
         final int fl = PolicyControl.getWindowFlags(win, attrs);
-        if (mTopFullscreenOpaqueWindowState == null
-                && win.isVisibleLw() && attrs.type == TYPE_INPUT_METHOD) {
+        if (mTopFullscreenOpaqueWindowState == null && visible && attrs.type == TYPE_INPUT_METHOD) {
             mForcingShowNavBar = true;
             mForcingShowNavBarLayer = win.getSurfaceLayer();
         }
         if (attrs.type == TYPE_STATUS_BAR) {
             if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                 mForceStatusBarFromKeyguard = true;
-                mShowingLockscreen = true;
             }
             if ((attrs.privateFlags & PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT) != 0) {
                 mForceStatusBarTransparent = true;
@@ -5116,17 +5187,10 @@
 
         boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
                 && attrs.type < FIRST_SYSTEM_WINDOW;
-        final boolean showWhenLocked = (fl & FLAG_SHOW_WHEN_LOCKED) != 0;
-        final boolean dismissKeyguard = (fl & FLAG_DISMISS_KEYGUARD) != 0;
         final int stackId = win.getStackId();
-        if (mTopFullscreenOpaqueWindowState == null &&
-                win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()) {
+        if (mTopFullscreenOpaqueWindowState == null && visible) {
             if ((fl & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
-                if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
-                    mForceStatusBarFromKeyguard = true;
-                } else {
-                    mForceStatusBar = true;
-                }
+                mForceStatusBar = true;
             }
             if (attrs.type == TYPE_DREAM) {
                 // If the lockscreen was showing when the dream started then wait
@@ -5138,84 +5202,25 @@
                 }
             }
 
-            final IApplicationToken appToken = win.getAppToken();
-
             // For app windows that are not attached, we decide if all windows in the app they
             // represent should be hidden or if we should hide the lockscreen. For attached app
             // windows we defer the decision to the window it is attached to.
             if (appWindow && attached == null) {
-                if (showWhenLocked) {
-                    // Remove any previous windows with the same appToken.
-                    mAppsToBeHidden.remove(appToken);
-                    mAppsThatDismissKeyguard.remove(appToken);
-                    if (mAppsToBeHidden.isEmpty()) {
-                        if (dismissKeyguard && !mKeyguardSecure) {
-                            mAppsThatDismissKeyguard.add(appToken);
-                        } else if (win.isDrawnLw() || win.hasAppShownWindows()) {
-                            mWinShowWhenLocked = win;
-                            mHideLockScreen = true;
-                            mForceStatusBarFromKeyguard = false;
-                        }
-                    }
-                } else if (dismissKeyguard) {
-                    if (mKeyguardSecure) {
-                        mAppsToBeHidden.add(appToken);
-                    } else {
-                        mAppsToBeHidden.remove(appToken);
-                    }
-                    mAppsThatDismissKeyguard.add(appToken);
-                } else {
-                    mAppsToBeHidden.add(appToken);
-                }
                 if (isFullscreen(attrs) && StackId.normallyFullscreenWindows(stackId)) {
                     if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
                     mTopFullscreenOpaqueWindowState = win;
                     if (mTopFullscreenOpaqueOrDimmingWindowState == null) {
                         mTopFullscreenOpaqueOrDimmingWindowState = win;
                     }
-                    if (!mAppsThatDismissKeyguard.isEmpty() &&
-                            mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
-                        if (DEBUG_LAYOUT) Slog.v(TAG,
-                                "Setting mDismissKeyguard true by win " + win);
-                        mDismissKeyguard = (mWinDismissingKeyguard == win
-                                && mSecureDismissingKeyguard == mKeyguardSecure)
-                                ? DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
-                        mWinDismissingKeyguard = win;
-                        mSecureDismissingKeyguard = mKeyguardSecure;
-                        mForceStatusBarFromKeyguard = mShowingLockscreen && mKeyguardSecure;
-                    } else if (mAppsToBeHidden.isEmpty() && showWhenLocked
-                            && (win.isDrawnLw() || win.hasAppShownWindows())) {
-                        if (DEBUG_LAYOUT) Slog.v(TAG,
-                                "Setting mHideLockScreen to true by win " + win);
-                        mHideLockScreen = true;
-                        mForceStatusBarFromKeyguard = false;
-                    }
                     if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
                         mAllowLockscreenWhenOn = true;
                     }
                 }
-
-                if (!mKeyguardHidden && mWinShowWhenLocked != null &&
-                        mWinShowWhenLocked.getAppToken() != win.getAppToken() &&
-                        (attrs.flags & FLAG_SHOW_WHEN_LOCKED) == 0) {
-                    win.hideLw(false);
-                }
-            }
-        } else if (mTopFullscreenOpaqueWindowState == null && mWinShowWhenLocked == null) {
-            // No TopFullscreenOpaqueWindow is showing, but we found a SHOW_WHEN_LOCKED window
-            // that is being hidden in an animation - keep the
-            // keyguard hidden until the new window shows up and
-            // we know whether to show the keyguard or not.
-            if (win.isAnimatingLw() && appWindow && showWhenLocked && mKeyguardHidden) {
-                mHideLockScreen = true;
-                mWinShowWhenLocked = win;
             }
         }
 
-        final boolean reallyVisible = win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw();
-
         // Voice interaction overrides both top fullscreen and top docked.
-        if (reallyVisible && win.getAttrs().type == TYPE_VOICE_INTERACTION) {
+        if (visible && win.getAttrs().type == TYPE_VOICE_INTERACTION) {
             if (mTopFullscreenOpaqueWindowState == null) {
                 mTopFullscreenOpaqueWindowState = win;
                 if (mTopFullscreenOpaqueOrDimmingWindowState == null) {
@@ -5231,7 +5236,7 @@
         }
 
         // Keep track of the window if it's dimming but not necessarily fullscreen.
-        if (mTopFullscreenOpaqueOrDimmingWindowState == null && reallyVisible
+        if (mTopFullscreenOpaqueOrDimmingWindowState == null && visible
                 && win.isDimming() && StackId.normallyFullscreenWindows(stackId)) {
             mTopFullscreenOpaqueOrDimmingWindowState = win;
         }
@@ -5239,7 +5244,7 @@
         // We need to keep track of the top "fullscreen" opaque window for the docked stack
         // separately, because both the "real fullscreen" opaque window and the one for the docked
         // stack can control View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.
-        if (mTopDockedOpaqueWindowState == null && reallyVisible && appWindow && attached == null
+        if (mTopDockedOpaqueWindowState == null && visible && appWindow && attached == null
                 && isFullscreen(attrs) && stackId == DOCKED_STACK_ID) {
             mTopDockedOpaqueWindowState = win;
             if (mTopDockedOpaqueOrDimmingWindowState == null) {
@@ -5249,12 +5254,22 @@
 
         // Also keep track of any windows that are dimming but not necessarily fullscreen in the
         // docked stack.
-        if (mTopDockedOpaqueOrDimmingWindowState == null && reallyVisible && win.isDimming()
+        if (mTopDockedOpaqueOrDimmingWindowState == null && visible && win.isDimming()
                 && stackId == DOCKED_STACK_ID) {
             mTopDockedOpaqueOrDimmingWindowState = win;
         }
     }
 
+    private void applyKeyguardPolicyLw(WindowState win, WindowState imeTarget) {
+        if (canBeHiddenByKeyguardLw(win)) {
+            if (shouldBeHiddenByKeyguard(win, imeTarget)) {
+                win.hideLw(false /* doAnimation */);
+            } else {
+                win.showLw(false /* doAnimation */);
+            }
+        }
+    }
+
     private boolean isFullscreen(WindowManager.LayoutParams attrs) {
         return attrs.x == 0 && attrs.y == 0
                 && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
@@ -5264,17 +5279,6 @@
     /** {@inheritDoc} */
     @Override
     public int finishPostLayoutPolicyLw() {
-        if (mWinShowWhenLocked != null && mTopFullscreenOpaqueWindowState != null &&
-                mWinShowWhenLocked.getAppToken() != mTopFullscreenOpaqueWindowState.getAppToken()
-                && isKeyguardLocked()) {
-            // A dialog is dismissing the keyguard. Put the wallpaper behind it and hide the
-            // fullscreen window.
-            // TODO: Make sure FLAG_SHOW_WALLPAPER is restored when dialog is dismissed. Or not.
-            mWinShowWhenLocked.getAttrs().flags |= FLAG_SHOW_WALLPAPER;
-            mTopFullscreenOpaqueWindowState.hideLw(false);
-            mTopFullscreenOpaqueWindowState = mWinShowWhenLocked;
-        }
-
         int changes = 0;
         boolean topIsFullscreen = false;
 
@@ -5287,7 +5291,7 @@
         // started while the lockscreen was showing and remember this state
         // while the dream is showing.
         if (!mShowingDream) {
-            mDreamingLockscreen = mShowingLockscreen;
+            mDreamingLockscreen = isKeyguardShowingAndNotOccluded();
             if (mDreamingSleepTokenNeeded) {
                 mDreamingSleepTokenNeeded = false;
                 mHandler.obtainMessage(MSG_UPDATE_DREAMING_SLEEP_TOKEN, 0, 1).sendToTarget();
@@ -5378,76 +5382,17 @@
             mTopIsFullscreen = topIsFullscreen;
         }
 
-        // Hide the key guard if a visible window explicitly specifies that it wants to be
-        // displayed when the screen is locked.
-        if (mKeyguardDelegate != null && mStatusBar != null) {
-            if (localLOGV) Slog.v(TAG, "finishPostLayoutPolicyLw: mHideKeyguard="
-                    + mHideLockScreen);
-            if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !mKeyguardSecure) {
-                mKeyguardHidden = true;
-                if (setKeyguardOccludedLw(true)) {
-                    changes |= FINISH_LAYOUT_REDO_LAYOUT
-                            | FINISH_LAYOUT_REDO_CONFIG
-                            | FINISH_LAYOUT_REDO_WALLPAPER;
-                }
-                if (mKeyguardDelegate.isShowing()) {
-                    mHandler.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            mKeyguardDelegate.keyguardDone(false, false);
-                        }
-                    });
-                }
-            } else if (mHideLockScreen) {
-                mKeyguardHidden = true;
-                mWinDismissingKeyguard = null;
-                if (setKeyguardOccludedLw(true)) {
-                    changes |= FINISH_LAYOUT_REDO_LAYOUT
-                            | FINISH_LAYOUT_REDO_CONFIG
-                            | FINISH_LAYOUT_REDO_WALLPAPER;
-                }
-            } else if (mDismissKeyguard != DISMISS_KEYGUARD_NONE) {
-                mKeyguardHidden = false;
-                boolean willDismiss = false;
-                if (mDismissKeyguard == DISMISS_KEYGUARD_START) {
-                    final boolean trusted = mKeyguardDelegate.isTrusted();
-                    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 */));
-                }
-
-                // If we are currently dismissing Keyguard, there is no need to unocclude it.
-                if (!mCurrentlyDismissingKeyguard) {
-                    if (setKeyguardOccludedLw(false)) {
-                        changes |= FINISH_LAYOUT_REDO_LAYOUT
-                                | FINISH_LAYOUT_REDO_CONFIG
-                                | FINISH_LAYOUT_REDO_WALLPAPER;
-                    }
-                }
-            } else {
-                mWinDismissingKeyguard = null;
-                mSecureDismissingKeyguard = false;
-                mKeyguardHidden = false;
-                if (setKeyguardOccludedLw(false)) {
-                    changes |= FINISH_LAYOUT_REDO_LAYOUT
-                            | FINISH_LAYOUT_REDO_CONFIG
-                            | FINISH_LAYOUT_REDO_WALLPAPER;
-                }
-            }
-        }
-
         if ((updateSystemUiVisibilityLw()&SYSTEM_UI_CHANGING_LAYOUT) != 0) {
             // If the navigation bar has been hidden or shown, we need to do another
             // layout pass to update that window.
             changes |= FINISH_LAYOUT_REDO_LAYOUT;
         }
 
+        if (mShowingDream != mLastShowingDream) {
+            mLastShowingDream = mShowingDream;
+            mWindowManagerFuncs.notifyShowingDreamChanged();
+        }
+
         // update since mAllowLockscreenWhenOn might have changed
         updateLockScreenTimeout();
         return changes;
@@ -5459,6 +5404,7 @@
      * @return Whether the flags have changed and we have to redo the layout.
      */
     private boolean setKeyguardOccludedLw(boolean isOccluded) {
+        if (DEBUG_KEYGUARD) Slog.d(TAG, "setKeyguardOccluded occluded=" + isOccluded);
         boolean wasOccluded = mKeyguardOccluded;
         boolean showing = mKeyguardDelegate.isShowing();
         if (wasOccluded && !isOccluded && showing) {
@@ -5468,9 +5414,6 @@
             if (!mKeyguardDelegate.hasLockscreenWallpaper()) {
                 mStatusBar.getAttrs().flags |= FLAG_SHOW_WALLPAPER;
             }
-            Animation anim = AnimationUtils.loadAnimation(mContext,
-                    com.android.internal.R.anim.wallpaper_open_exit);
-            mWindowManagerFuncs.overridePlayingAppAnimationsLw(anim);
             return true;
         } else if (!wasOccluded && isOccluded && showing) {
             mKeyguardOccluded = true;
@@ -5487,14 +5430,6 @@
         }
     }
 
-    private void onKeyguardShowingStateChanged(boolean showing) {
-        if (!showing) {
-            synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
-                mCurrentlyDismissingKeyguard = false;
-            }
-        }
-    }
-
     private boolean isStatusBarKeyguard() {
         return mStatusBar != null
                 && (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
@@ -5502,7 +5437,7 @@
 
     @Override
     public boolean allowAppAnimationsLw() {
-        if (isStatusBarKeyguard() || mShowingDream) {
+        if (mShowingDream) {
             // If keyguard or dreams is currently visible, no reason to animate behind it.
             return false;
         }
@@ -6274,7 +6209,7 @@
     }
 
     void dispatchMediaKeyWithWakeLockToAudioService(KeyEvent event) {
-        if (ActivityManagerNative.isSystemReady()) {
+        if (mActivityManagerInternal.isSystemReady()) {
             MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(event, true);
         }
     }
@@ -6654,6 +6589,12 @@
         return mKeyguardDelegate.isShowing() && !mKeyguardOccluded;
     }
 
+    @Override
+    public boolean isKeyguardTrustedLw() {
+        if (mKeyguardDelegate == null) return false;
+        return mKeyguardDelegate.isTrusted();
+    }
+
     /** {@inheritDoc} */
     @Override
     public boolean isKeyguardLocked() {
@@ -6669,8 +6610,9 @@
 
     /** {@inheritDoc} */
     @Override
-    public boolean isKeyguardShowingOrOccluded() {
-        return mKeyguardDelegate == null ? false : mKeyguardDelegate.isShowing();
+    public boolean isKeyguardOccluded() {
+        if (mKeyguardDelegate == null) return false;
+        return mKeyguardOccluded;
     }
 
     /** {@inheritDoc} */
@@ -6684,25 +6626,9 @@
     public void dismissKeyguardLw() {
         if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
             if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.dismissKeyguardLw");
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    // ask the keyguard to prompt the user to authenticate if necessary
-                    mKeyguardDelegate.dismiss(false /* allowWhileOccluded */);
-                }
-            });
-        }
-    }
 
-    @Override
-    public void notifyActivityDrawnForKeyguardLw() {
-        if (mKeyguardDelegate != null) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mKeyguardDelegate.onActivityDrawn();
-                }
-            });
+            // ask the keyguard to prompt the user to authenticate if necessary
+            mKeyguardDelegate.dismiss(true /* allowWhileOccluded */);
         }
     }
 
@@ -6714,6 +6640,11 @@
     }
 
     @Override
+    public boolean isShowingDreamLw() {
+        return mShowingDream;
+    }
+
+    @Override
     public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
         if (mKeyguardDelegate != null) {
             if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.startKeyguardExitAnimation");
@@ -7025,8 +6956,7 @@
     /** {@inheritDoc} */
     @Override
     public void systemReady() {
-        mKeyguardDelegate = new KeyguardServiceDelegate(mContext,
-                this::onKeyguardShowingStateChanged);
+        mKeyguardDelegate = new KeyguardServiceDelegate(mContext);
         mKeyguardDelegate.onSystemReady();
 
         readCameraLensCoverState();
@@ -7573,7 +7503,7 @@
             }
         }
         final WindowState win = winCandidate;
-        if ((win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 && mHideLockScreen == true) {
+        if ((win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 && mKeyguardOccluded) {
             // We are updating at a point where the keyguard has gotten
             // focus, but we were last in a state where the top window is
             // hiding it.  This is probably because the keyguard as been
@@ -7630,7 +7560,7 @@
     }
 
     private int updateLightStatusBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming) {
-        WindowState statusColorWin = isStatusBarKeyguard() && !mHideLockScreen
+        WindowState statusColorWin = isStatusBarKeyguard() && !mKeyguardOccluded
                 ? mStatusBar
                 : opaqueOrDimming;
 
@@ -7671,7 +7601,7 @@
         final boolean forceOpaqueStatusBar = mForceShowSystemBars && !mForceStatusBarFromKeyguard;
 
         // apply translucent bar vis flags
-        WindowState fullscreenTransWin = isStatusBarKeyguard() && !mHideLockScreen
+        WindowState fullscreenTransWin = isStatusBarKeyguard() && !mKeyguardOccluded
                 ? mStatusBar
                 : mTopFullscreenOpaqueWindowState;
         vis = mStatusBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);
@@ -7697,7 +7627,7 @@
                     | View.SYSTEM_UI_FLAG_IMMERSIVE
                     | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                     | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-            if (mHideLockScreen) {
+            if (mKeyguardOccluded) {
                 flags |= View.STATUS_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSLUCENT;
             }
             vis = (vis & ~flags) | (oldVis & flags);
@@ -7919,6 +7849,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
@@ -8060,8 +7996,7 @@
                 pw.print(","); pw.print(mDockBottom); pw.println(")");
         pw.print(prefix); pw.print("mDockLayer="); pw.print(mDockLayer);
                 pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer);
-        pw.print(prefix); pw.print("mShowingLockscreen="); pw.print(mShowingLockscreen);
-                pw.print(" mShowingDream="); pw.print(mShowingDream);
+        pw.print(prefix); pw.print("mShowingDream="); pw.print(mShowingDream);
                 pw.print(" mDreamingLockscreen="); pw.print(mDreamingLockscreen);
                 pw.print(" mDreamingSleepToken="); pw.println(mDreamingSleepToken);
         if (mLastInputMethodWindow != null) {
@@ -8089,10 +8024,6 @@
             pw.print(prefix); pw.print("mFocusedApp=");
                     pw.println(mFocusedApp);
         }
-        if (mWinDismissingKeyguard != null) {
-            pw.print(prefix); pw.print("mWinDismissingKeyguard=");
-                    pw.println(mWinDismissingKeyguard);
-        }
         if (mTopFullscreenOpaqueWindowState != null) {
             pw.print(prefix); pw.print("mTopFullscreenOpaqueWindowState=");
                     pw.println(mTopFullscreenOpaqueWindowState);
@@ -8107,14 +8038,13 @@
                     pw.println(mForcingShowNavBarLayer);
         }
         pw.print(prefix); pw.print("mTopIsFullscreen="); pw.print(mTopIsFullscreen);
-                pw.print(" mHideLockScreen="); pw.println(mHideLockScreen);
+                pw.print(" mKeyguardOccluded="); pw.println(mKeyguardOccluded);
+                pw.print(" mKeyguardOccludedChanged="); pw.println(mKeyguardOccludedChanged);
+                pw.print(" mPendingKeyguardOccluded="); pw.println(mPendingKeyguardOccluded);
         pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar);
                 pw.print(" mForceStatusBarFromKeyguard=");
                 pw.println(mForceStatusBarFromKeyguard);
-        pw.print(prefix); pw.print("mDismissKeyguard="); pw.print(mDismissKeyguard);
-                pw.print(" mCurrentlyDismissingKeyguard="); pw.println(mCurrentlyDismissingKeyguard);
-                pw.print(" mWinDismissingKeyguard="); pw.print(mWinDismissingKeyguard);
-                pw.print(" mHomePressed="); pw.println(mHomePressed);
+        pw.print(prefix); pw.print("mHomePressed="); pw.println(mHomePressed);
         pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn);
                 pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout);
                 pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive);
diff --git a/services/core/java/com/android/server/policy/StatusBarController.java b/services/core/java/com/android/server/policy/StatusBarController.java
index 1dbc44e..7d67b60 100644
--- a/services/core/java/com/android/server/policy/StatusBarController.java
+++ b/services/core/java/com/android/server/policy/StatusBarController.java
@@ -56,8 +56,8 @@
         }
 
         @Override
-        public void onAppTransitionStartingLocked(IBinder openToken, IBinder closeToken,
-                final Animation openAnimation, final Animation closeAnimation) {
+        public int onAppTransitionStartingLocked(int transit, IBinder openToken,
+                IBinder closeToken, final Animation openAnimation, final Animation closeAnimation) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
@@ -71,10 +71,11 @@
                     }
                 }
             });
+            return 0;
         }
 
         @Override
-        public void onAppTransitionCancelledLocked() {
+        public void onAppTransitionCancelledLocked(int transit) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 10c237f..28f36f7 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -1,12 +1,13 @@
 package com.android.server.policy.keyguard;
 
+import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
+import android.app.ActivityManagerNative;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.content.pm.ActivityInfo;
 import android.content.res.Resources;
-import android.graphics.PixelFormat;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -15,15 +16,13 @@
 import android.util.Log;
 import android.util.Slog;
 import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
 import android.view.WindowManagerPolicy.OnKeyguardExitResult;
 
 import com.android.internal.policy.IKeyguardDrawnCallback;
 import com.android.internal.policy.IKeyguardExitCallback;
 import com.android.internal.policy.IKeyguardService;
+import com.android.server.LocalServices;
 import com.android.server.UiThread;
-import com.android.server.policy.keyguard.KeyguardStateMonitor.OnShowingStateChangedCallback;
 
 import java.io.PrintWriter;
 
@@ -46,23 +45,13 @@
 
     protected KeyguardServiceWrapper mKeyguardService;
     private final Context mContext;
-    private final View mScrim; // shown if keyguard crashes
-    private final Handler mScrimHandler;
+    private final Handler mHandler;
     private final KeyguardState mKeyguardState = new KeyguardState();
     private DrawnListener mDrawnListenerWhenConnect;
-    private final OnShowingStateChangedCallback mShowingStateChangedCallback;
 
     private static final class KeyguardState {
         KeyguardState() {
-            // Assume keyguard is showing and secure until we know for sure. This is here in
-            // the event something checks before the service is actually started.
-            // KeyguardService itself should default to this state until the real state is known.
-            showing = true;
-            showingAndNotOccluded = true;
-            secure = true;
-            deviceHasKeyguard = true;
-            enabled = true;
-            currentUser = UserHandle.USER_NULL;
+            reset();
         }
         boolean showing;
         boolean showingAndNotOccluded;
@@ -78,6 +67,18 @@
         public boolean bootCompleted;
         public int screenState;
         public int interactiveState;
+
+        private void reset() {
+            // Assume keyguard is showing and secure until we know for sure. This is here in
+            // the event something checks before the service is actually started.
+            // KeyguardService itself should default to this state until the real state is known.
+            showing = true;
+            showingAndNotOccluded = true;
+            secure = true;
+            deviceHasKeyguard = true;
+            enabled = true;
+            currentUser = UserHandle.USER_NULL;
+        }
     };
 
     public interface DrawnListener {
@@ -98,7 +99,6 @@
             if (mDrawnListener != null) {
                 mDrawnListener.onDrawn();
             }
-            hideScrim();
         }
     };
 
@@ -119,12 +119,9 @@
         }
     };
 
-    public KeyguardServiceDelegate(Context context,
-            OnShowingStateChangedCallback showingStateChangedCallback) {
+    public KeyguardServiceDelegate(Context context) {
         mContext = context;
-        mScrimHandler = UiThread.getHandler();
-        mShowingStateChangedCallback = showingStateChangedCallback;
-        mScrim = createScrim(context, mScrimHandler);
+        mHandler = UiThread.getHandler();
     }
 
     public void bindService(Context context) {
@@ -137,7 +134,7 @@
         intent.setComponent(keyguardComponent);
 
         if (!context.bindServiceAsUser(intent, mKeyguardConnection,
-                Context.BIND_AUTO_CREATE, mScrimHandler, UserHandle.SYSTEM)) {
+                Context.BIND_AUTO_CREATE, mHandler, UserHandle.SYSTEM)) {
             Log.v(TAG, "*** Keyguard: can't bind to " + keyguardComponent);
             mKeyguardState.showing = false;
             mKeyguardState.showingAndNotOccluded = false;
@@ -147,7 +144,6 @@
                 // is at least self-healing but a race condition here can lead to the scrim being
                 // stuck on keyguard-less devices.
                 mKeyguardState.deviceHasKeyguard = false;
-                hideScrim();
             }
         } else {
             if (DEBUG) Log.v(TAG, "*** Keyguard started");
@@ -159,7 +155,7 @@
         public void onServiceConnected(ComponentName name, IBinder service) {
             if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)");
             mKeyguardService = new KeyguardServiceWrapper(mContext,
-                    IKeyguardService.Stub.asInterface(service), mShowingStateChangedCallback);
+                    IKeyguardService.Stub.asInterface(service));
             if (mKeyguardState.systemIsReady) {
                 // If the system is ready, it means keyguard crashed and restarted.
                 mKeyguardService.onSystemReady();
@@ -196,8 +192,15 @@
         public void onServiceDisconnected(ComponentName name) {
             if (DEBUG) Log.v(TAG, "*** Keyguard disconnected (boo!)");
             mKeyguardService = null;
+            mKeyguardState.reset();
+            mHandler.post(() -> {
+                try {
+                    ActivityManagerNative.getDefault().setLockScreenShown(true);
+                } catch (RemoteException e) {
+                    // Local call.
+                }
+            });
         }
-
     };
 
     public boolean isShowing() {
@@ -234,12 +237,6 @@
         }
     }
 
-    public void keyguardDone(boolean authenticated, boolean wakeup) {
-        if (mKeyguardService != null) {
-            mKeyguardService.keyguardDone(authenticated, wakeup);
-        }
-    }
-
     public void setOccluded(boolean isOccluded, boolean animate) {
         if (mKeyguardService != null) {
             if (DEBUG) Log.v(TAG, "setOccluded(" + isOccluded + ") animate=" + animate);
@@ -301,7 +298,6 @@
             // This shouldn't happen, but if it does, show the scrim immediately and
             // invoke the listener's callback after the service actually connects.
             mDrawnListenerWhenConnect = drawnListener;
-            showScrim();
         }
         mKeyguardState.screenState = SCREEN_STATE_TURNING_ON;
     }
@@ -369,61 +365,6 @@
         }
     }
 
-    private static View createScrim(Context context, Handler handler) {
-        final View view = new View(context);
-
-        int flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
-                | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
-                | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER
-                ;
-
-        final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;
-        final int type = WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
-        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                stretch, stretch, type, flags, PixelFormat.TRANSLUCENT);
-        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
-        lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
-        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED;
-        lp.setTitle("KeyguardScrim");
-        final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-        // Disable pretty much everything in statusbar until keyguard comes back and we know
-        // the state of the world.
-        view.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME
-                | View.STATUS_BAR_DISABLE_BACK
-                | View.STATUS_BAR_DISABLE_RECENT
-                | View.STATUS_BAR_DISABLE_EXPAND
-                | View.STATUS_BAR_DISABLE_SEARCH);
-        handler.post(new Runnable() {
-            @Override
-            public void run() {
-                wm.addView(view, lp);
-            }
-        });
-        return view;
-    }
-
-    public void showScrim() {
-        synchronized (mKeyguardState) {
-            if (!mKeyguardState.deviceHasKeyguard) return;
-            mScrimHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mScrim.setVisibility(View.VISIBLE);
-                }
-            });
-        }
-    }
-
-    public void hideScrim() {
-        mScrimHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                mScrim.setVisibility(View.GONE);
-            }
-        });
-    }
-
     public void onBootCompleted() {
         if (mKeyguardService != null) {
             mKeyguardService.onBootCompleted();
@@ -431,12 +372,6 @@
         mKeyguardState.bootCompleted = true;
     }
 
-    public void onActivityDrawn() {
-        if (mKeyguardService != null) {
-            mKeyguardService.onActivityDrawn();
-        }
-    }
-
     public void dump(String prefix, PrintWriter pw) {
         pw.println(prefix + TAG);
         prefix += "  ";
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
index acc67db..b457f8d 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
@@ -26,7 +26,6 @@
 import com.android.internal.policy.IKeyguardExitCallback;
 import com.android.internal.policy.IKeyguardService;
 import com.android.internal.policy.IKeyguardStateCallback;
-import com.android.server.policy.keyguard.KeyguardStateMonitor.OnShowingStateChangedCallback;
 
 import java.io.PrintWriter;
 
@@ -40,11 +39,9 @@
     private IKeyguardService mService;
     private String TAG = "KeyguardServiceWrapper";
 
-    public KeyguardServiceWrapper(Context context, IKeyguardService service,
-            OnShowingStateChangedCallback showingStateChangedCallback) {
+    public KeyguardServiceWrapper(Context context, IKeyguardService service) {
         mService = service;
-        mKeyguardStateMonitor = new KeyguardStateMonitor(context, service,
-                showingStateChangedCallback);
+        mKeyguardStateMonitor = new KeyguardStateMonitor(context, service);
     }
 
     @Override // Binder interface
@@ -57,15 +54,6 @@
     }
 
     @Override // Binder interface
-    public void keyguardDone(boolean authenticated, boolean wakeup) {
-        try {
-            mService.keyguardDone(authenticated, wakeup);
-        } catch (RemoteException e) {
-            Slog.w(TAG , "Remote Exception", e);
-        }
-    }
-
-    @Override // Binder interface
     public void setOccluded(boolean isOccluded, boolean animate) {
         try {
             mService.setOccluded(isOccluded, animate);
@@ -229,15 +217,6 @@
     }
 
     @Override // Binder interface
-    public void onActivityDrawn() {
-        try {
-            mService.onActivityDrawn();
-        } catch (RemoteException e) {
-            Slog.w(TAG , "Remote Exception", e);
-        }
-    }
-
-    @Override // Binder interface
     public IBinder asBinder() {
         return mService.asBinder();
     }
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index 712b625..f19f0aa 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -49,13 +49,11 @@
     private int mCurrentUserId;
 
     private final LockPatternUtils mLockPatternUtils;
-    private final OnShowingStateChangedCallback mOnShowingStateChangedCallback;
 
-    public KeyguardStateMonitor(Context context, IKeyguardService service,
-            OnShowingStateChangedCallback showingStateChangedCallback) {
+    public KeyguardStateMonitor(Context context, IKeyguardService service) {
         mLockPatternUtils = new LockPatternUtils(context);
         mCurrentUserId = ActivityManager.getCurrentUser();
-        mOnShowingStateChangedCallback = showingStateChangedCallback;
+
         try {
             service.addStateMonitorCallback(this);
         } catch (RemoteException e) {
@@ -86,7 +84,6 @@
     @Override // Binder interface
     public void onShowingStateChanged(boolean showing) {
         mIsShowing = showing;
-        mOnShowingStateChangedCallback.onShowingStateChanged(showing);
     }
 
     @Override // Binder interface
@@ -126,8 +123,4 @@
         pw.println(prefix + "mTrusted=" + mTrusted);
         pw.println(prefix + "mCurrentUserId=" + mCurrentUserId);
     }
-
-    public interface OnShowingStateChangedCallback {
-        void onShowingStateChanged(boolean showing);
-    }
 }
\ No newline at end of file
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 4e9f5a2..00700b8 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -648,7 +648,7 @@
             Slog.d(TAG, "Sending wake up broadcast.");
         }
 
-        if (ActivityManagerNative.isSystemReady()) {
+        if (mActivityManagerInternal.isSystemReady()) {
             mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,
                     mWakeUpBroadcastDone, mHandler, 0, null, null);
         } else {
@@ -671,7 +671,7 @@
             Slog.d(TAG, "Sending go to sleep broadcast.");
         }
 
-        if (ActivityManagerNative.isSystemReady()) {
+        if (mActivityManagerInternal.isSystemReady()) {
             mContext.sendOrderedBroadcastAsUser(mScreenOffIntent, UserHandle.ALL, null,
                     mGoToSleepBroadcastDone, mHandler, 0, null, null);
         } else {
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 706828b..d755e58 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,91 @@
         }
     }
 
+    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);
+            }
+            final boolean oldShouldAllow = state.mProcState
+                    <= ActivityManager.PROCESS_STATE_RECEIVER;
+            state.mProcState = procState;
+            if (state.mNumWakeLocks > 0) {
+                if (mDeviceIdleMode) {
+                    handleUidStateChangeLocked();
+                } else if (!state.mActive && oldShouldAllow !=
+                        (procState <= ActivityManager.PROCESS_STATE_RECEIVER)) {
+                    // If this uid is not active, but the process state has changed such
+                    // that we may still want to allow it to hold a wake lock, then take care of it.
+                    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 +2717,21 @@
         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 &&
+                            wakeLock.mUidState.mProcState > ActivityManager.PROCESS_STATE_RECEIVER;
                 }
             }
             if (wakeLock.mDisabled != disabled) {
@@ -2964,10 +3059,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 +3228,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 +3245,7 @@
             mHistoryTag = historyTag;
             mOwnerUid = ownerUid;
             mOwnerPid = ownerPid;
+            mUidState = uidState;
         }
 
         @Override
@@ -3312,6 +3421,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 +4000,16 @@
         }
 
         @Override
+        public void startUidChanges() {
+            startUidChangesInternal();
+        }
+
+        @Override
+        public void finishUidChanges() {
+            finishUidChangesInternal();
+        }
+
+        @Override
         public void updateUidProcState(int uid, int procState) {
             updateUidProcStateInternal(uid, procState);
         }
@@ -3890,6 +4020,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/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index badee82..a920d54 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -17,7 +17,6 @@
 
 package com.android.server.power;
 
-import android.app.ActivityManagerNative;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.IActivityManager;
@@ -415,7 +414,7 @@
         Log.i(TAG, "Shutting down activity manager...");
 
         final IActivityManager am =
-            ActivityManagerNative.asInterface(ServiceManager.checkService("activity"));
+                IActivityManager.Stub.asInterface(ServiceManager.checkService("activity"));
         if (am != null) {
             try {
                 am.shutdown(MAX_BROADCAST_TIME);
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 353d663..62f5468 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -1014,6 +1014,9 @@
                     synchronized (mDeviceLockedForUser) {
                         mDeviceLockedForUser.delete(userId);
                     }
+                    synchronized (mTrustUsuallyManagedForUser) {
+                        mTrustUsuallyManagedForUser.delete(userId);
+                    }
                     refreshAgentList(userId);
                     refreshDeviceLockedForUser(userId);
                 }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 7439f535..96662b5 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -22,6 +22,8 @@
 import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
 import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
 import static android.os.ParcelFileDescriptor.MODE_TRUNCATE;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
@@ -1692,8 +1694,7 @@
                 if (wallpaper.userId == mCurrentUserId) {
                     if (DEBUG)
                         Slog.v(TAG, "Adding window token: " + newConn.mToken);
-                    mIWindowManager.addWindowToken(newConn.mToken,
-                            WindowManager.LayoutParams.TYPE_WALLPAPER);
+                    mIWindowManager.addWindowToken(newConn.mToken, TYPE_WALLPAPER, DEFAULT_DISPLAY);
                     mLastWallpaper = wallpaper;
                 }
             } catch (RemoteException e) {
@@ -1728,7 +1729,7 @@
             try {
                 if (DEBUG)
                     Slog.v(TAG, "Removing window token: " + wallpaper.connection.mToken);
-                mIWindowManager.removeWindowToken(wallpaper.connection.mToken);
+                mIWindowManager.removeWindowToken(wallpaper.connection.mToken, DEFAULT_DISPLAY);
             } catch (RemoteException e) {
             }
             wallpaper.connection.mService = null;
@@ -1745,7 +1746,7 @@
     void attachServiceLocked(WallpaperConnection conn, WallpaperData wallpaper) {
         try {
             conn.mService.attach(conn, conn.mToken,
-                    WindowManager.LayoutParams.TYPE_WALLPAPER, false,
+                    TYPE_WALLPAPER, false,
                     wallpaper.width, wallpaper.height, wallpaper.padding);
         } catch (RemoteException e) {
             Slog.w(TAG, "Failed attaching wallpaper; clearing", e);
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java
index 9f0f11a..302f9f6 100644
--- a/services/core/java/com/android/server/webkit/SystemImpl.java
+++ b/services/core/java/com/android/server/webkit/SystemImpl.java
@@ -26,6 +26,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.UserInfo;
 import android.content.res.XmlResourceParser;
+import android.database.ContentObserver;
 import android.os.Build;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -270,8 +271,21 @@
     }
 
     @Override
-    public void setMultiprocessEnabled(boolean enabled) {
-        WebViewZygote.setMultiprocessEnabled(enabled);
+    public void setMultiProcessEnabledFromContext(Context context) {
+        boolean enableMultiProcess = false;
+        try {
+            enableMultiProcess = Settings.Global.getInt(context.getContentResolver(),
+                    Settings.Global.WEBVIEW_MULTIPROCESS) == 1;
+        } catch (Settings.SettingNotFoundException ex) {
+        }
+        WebViewZygote.setMultiprocessEnabled(enableMultiProcess);
+    }
+
+    @Override
+    public void registerContentObserver(Context context, ContentObserver contentObserver) {
+        context.getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.WEBVIEW_MULTIPROCESS),
+                false, contentObserver);
     }
 
     // flags declaring we want extra info from the package manager for webview providers
diff --git a/services/core/java/com/android/server/webkit/SystemInterface.java b/services/core/java/com/android/server/webkit/SystemInterface.java
index 7c934fc..2d7a998 100644
--- a/services/core/java/com/android/server/webkit/SystemInterface.java
+++ b/services/core/java/com/android/server/webkit/SystemInterface.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.ContentObserver;
 import android.webkit.WebViewProviderInfo;
 
 /**
@@ -49,5 +50,6 @@
     public PackageInfo getPackageInfoForProvider(WebViewProviderInfo configInfo)
             throws NameNotFoundException;
 
-    public void setMultiprocessEnabled(boolean enabled);
+    public void setMultiProcessEnabledFromContext(Context context);
+    public void registerContentObserver(Context context, ContentObserver contentObserver);
 }
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index 57cd768..453e745 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -20,12 +20,10 @@
 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;
@@ -79,7 +77,7 @@
     private SystemInterface mSystemInterface;
     private WebViewUpdater mWebViewUpdater;
     private SettingsObserver mSettingsObserver;
-    private Context mContext;
+    final private Context mContext;
 
     public WebViewUpdateServiceImpl(Context context, SystemInterface systemInterface) {
         mContext = context;
@@ -725,15 +723,10 @@
      * 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);
+            mSystemInterface.registerContentObserver(mContext, this);
 
             // Push the current value of the setting immediately.
             notifyZygote();
@@ -745,15 +738,7 @@
         }
 
         private void notifyZygote() {
-            boolean enableMultiprocess = false;
-
-            try {
-                enableMultiprocess = Settings.Global.getInt(mResolver,
-                        Settings.Global.WEBVIEW_MULTIPROCESS) == 1;
-            } catch (Settings.SettingNotFoundException ex) {
-            }
-
-            mSystemInterface.setMultiprocessEnabled(enableMultiprocess);
+            mSystemInterface.setMultiProcessEnabledFromContext(mContext);
         }
     }
 }
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 893749e..670b9cc 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();
 
@@ -1285,8 +1283,7 @@
         }
 
         private static boolean isReportedWindowType(int windowType) {
-            return (windowType != WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM
-                    && windowType != WindowManager.LayoutParams.TYPE_WALLPAPER
+            return (windowType != WindowManager.LayoutParams.TYPE_WALLPAPER
                     && windowType != WindowManager.LayoutParams.TYPE_BOOT_PROGRESS
                     && windowType != WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY
                     && windowType != WindowManager.LayoutParams.TYPE_DRAG
@@ -1299,12 +1296,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/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index cd46165..862c145 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -135,6 +135,21 @@
     public static final int TRANSIT_ACTIVITY_RELAUNCH = 18;
     /** A task is being docked from recents. */
     public static final int TRANSIT_DOCK_TASK_FROM_RECENTS = 19;
+    /** Keyguard is going away */
+    public static final int TRANSIT_KEYGUARD_GOING_AWAY = 20;
+    /** Keyguard is going away with showing an activity behind that requests wallpaper */
+    public static final int TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER = 21;
+    /** Keyguard is being occluded */
+    public static final int TRANSIT_KEYGUARD_OCCLUDE = 22;
+    /** Keyguard is being unoccluded */
+    public static final int TRANSIT_KEYGUARD_UNOCCLUDE = 23;
+
+    /** Transition flag: Keyguard is going away, but keeping the notification shade open */
+    public static final int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE = 0x1;
+    /** Transition flag: Keyguard is going away, but doesn't want an animation for it */
+    public static final int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION = 0x2;
+    /** Transition flag: Keyguard is going away while it was showing the system wallpaper. */
+    public static final int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER = 0x4;
 
     /** Fraction of animation at which the recents thumbnail stays completely transparent */
     private static final float RECENTS_THUMBNAIL_FADEIN_FRACTION = 0.5f;
@@ -162,6 +177,7 @@
     private final WindowManagerService mService;
 
     private int mNextAppTransition = TRANSIT_UNSET;
+    private int mNextAppTransitionFlags = 0;
     private int mLastUsedAppTransition = TRANSIT_UNSET;
     private String mLastOpeningApp;
     private String mLastClosingApp;
@@ -286,8 +302,9 @@
         return mNextAppTransition;
      }
 
-    private void setAppTransition(int transit) {
+    private void setAppTransition(int transit, int flags) {
         mNextAppTransition = transit;
+        mNextAppTransitionFlags |= flags;
         setLastAppTransition(TRANSIT_UNSET, null, null);
     }
 
@@ -372,27 +389,33 @@
         return false;
     }
 
-    void goodToGo(AppWindowAnimator topOpeningAppAnimator, AppWindowAnimator topClosingAppAnimator,
-            ArraySet<AppWindowToken> openingApps, ArraySet<AppWindowToken> closingApps) {
-        int appTransition = mNextAppTransition;
+    /**
+     * @return bit-map of WindowManagerPolicy#FINISH_LAYOUT_REDO_* to indicate whether another
+     *         layout pass needs to be done
+     */
+    int goodToGo(int transit, AppWindowAnimator topOpeningAppAnimator,
+            AppWindowAnimator topClosingAppAnimator, ArraySet<AppWindowToken> openingApps,
+            ArraySet<AppWindowToken> closingApps) {
         mNextAppTransition = TRANSIT_UNSET;
+        mNextAppTransitionFlags = 0;
         mAppTransitionState = APP_STATE_RUNNING;
-        notifyAppTransitionStartingLocked(
+        int redoLayout = notifyAppTransitionStartingLocked(transit,
                 topOpeningAppAnimator != null ? topOpeningAppAnimator.mAppToken.token : null,
                 topClosingAppAnimator != null ? topClosingAppAnimator.mAppToken.token : null,
                 topOpeningAppAnimator != null ? topOpeningAppAnimator.animation : null,
                 topClosingAppAnimator != null ? topClosingAppAnimator.animation : null);
         mService.getDefaultDisplayContentLocked().getDockedDividerController()
-                .notifyAppTransitionStarting(openingApps, appTransition);
+                .notifyAppTransitionStarting(openingApps, transit);
 
         // Prolong the start for the transition when docking a task from recents, unless recents
         // ended it already then we don't need to wait.
-        if (mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS && !mProlongedAnimationsEnded) {
+        if (transit == TRANSIT_DOCK_TASK_FROM_RECENTS && !mProlongedAnimationsEnded) {
             for (int i = openingApps.size() - 1; i >= 0; i--) {
                 final AppWindowAnimator appAnimator = openingApps.valueAt(i).mAppAnimator;
                 appAnimator.startProlongAnimation(PROLONG_ANIMATION_AT_START);
             }
         }
+        return redoLayout;
     }
 
     /**
@@ -413,10 +436,11 @@
     }
 
     void freeze() {
-        setAppTransition(AppTransition.TRANSIT_UNSET);
+        final int transit = mNextAppTransition;
+        setAppTransition(AppTransition.TRANSIT_UNSET, 0 /* flags */);
         clear();
         setReady();
-        notifyAppTransitionCancelledLocked();
+        notifyAppTransitionCancelledLocked(transit);
     }
 
     void registerListenerLocked(AppTransitionListener listener) {
@@ -435,18 +459,20 @@
         }
     }
 
-    private void notifyAppTransitionCancelledLocked() {
+    private void notifyAppTransitionCancelledLocked(int transit) {
         for (int i = 0; i < mListeners.size(); i++) {
-            mListeners.get(i).onAppTransitionCancelledLocked();
+            mListeners.get(i).onAppTransitionCancelledLocked(transit);
         }
     }
 
-    private void notifyAppTransitionStartingLocked(IBinder openToken,
+    private int notifyAppTransitionStartingLocked(int transit, IBinder openToken,
             IBinder closeToken, Animation openAnimation, Animation closeAnimation) {
+        int redoLayout = 0;
         for (int i = 0; i < mListeners.size(); i++) {
-            mListeners.get(i).onAppTransitionStartingLocked(openToken, closeToken, openAnimation,
-                    closeAnimation);
+            redoLayout |= mListeners.get(i).onAppTransitionStartingLocked(transit, openToken,
+                    closeToken, openAnimation, closeAnimation);
         }
+        return redoLayout;
     }
 
     private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
@@ -1406,7 +1432,8 @@
     boolean canSkipFirstFrame() {
         return mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM
                 && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE
-                && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CLIP_REVEAL;
+                && mNextAppTransitionType != NEXT_TRANSIT_TYPE_CLIP_REVEAL
+                && mNextAppTransition != TRANSIT_KEYGUARD_GOING_AWAY;
     }
 
     /**
@@ -1435,7 +1462,13 @@
             @Nullable Rect surfaceInsets, boolean isVoiceInteraction, boolean freeform,
             int taskId) {
         Animation a;
-        if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN
+        if (isKeyguardGoingAwayTransit(transit) && enter) {
+            a = loadKeyguardExitAnimation(transit);
+        } else if (transit == TRANSIT_KEYGUARD_OCCLUDE) {
+            a = null;
+        } else if (transit == TRANSIT_KEYGUARD_UNOCCLUDE && !enter) {
+            a = loadAnimationRes(lp, com.android.internal.R.anim.wallpaper_open_exit);
+        } else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN
                 || transit == TRANSIT_TASK_OPEN
                 || transit == TRANSIT_TASK_TO_FRONT)) {
             a = loadAnimationRes(lp, enter
@@ -1590,14 +1623,30 @@
         return a;
     }
 
+    private Animation loadKeyguardExitAnimation(int transit) {
+        if ((mNextAppTransitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) != 0) {
+            return null;
+        }
+        final boolean toShade =
+                (mNextAppTransitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0;
+        return mService.mPolicy.createHiddenByKeyguardExit(
+                transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER, toShade);
+    }
+
     int getAppStackClipMode() {
         return mNextAppTransition == TRANSIT_ACTIVITY_RELAUNCH
                 || mNextAppTransition == TRANSIT_DOCK_TASK_FROM_RECENTS
+                || mNextAppTransition == TRANSIT_KEYGUARD_GOING_AWAY
+                || mNextAppTransition == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER
                 || mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL
                 ? STACK_CLIP_NONE
                 : STACK_CLIP_AFTER_ANIM;
     }
 
+    public int getTransitFlags() {
+        return mNextAppTransitionFlags;
+    }
+
     void postAnimationCallback() {
         if (mNextAppTransitionCallback != null) {
             mService.mH.sendMessage(mService.mH.obtainMessage(H.DO_ANIMATION_CALLBACK,
@@ -1819,6 +1868,18 @@
             case TRANSIT_DOCK_TASK_FROM_RECENTS: {
                 return "TRANSIT_DOCK_TASK_FROM_RECENTS";
             }
+            case TRANSIT_KEYGUARD_GOING_AWAY: {
+                return "TRANSIT_KEYGUARD_GOING_AWAY";
+            }
+            case TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER: {
+                return "TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER";
+            }
+            case TRANSIT_KEYGUARD_OCCLUDE: {
+                return "TRANSIT_KEYGUARD_OCCLUDE";
+            }
+            case TRANSIT_KEYGUARD_UNOCCLUDE: {
+                return "TRANSIT_KEYGUARD_UNOCCLUDE";
+            }
             default: {
                 return "<UNKNOWN>";
             }
@@ -1933,22 +1994,24 @@
      * @return true if transition is not running and should not be skipped, false if transition is
      *         already running
      */
-    boolean prepareAppTransitionLocked(int transit, boolean alwaysKeepCurrent) {
+    boolean prepareAppTransitionLocked(int transit, boolean alwaysKeepCurrent, int flags,
+            boolean forceOverride) {
         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Prepare app transition:"
                 + " transit=" + appTransitionToString(transit)
                 + " " + this
                 + " alwaysKeepCurrent=" + alwaysKeepCurrent
                 + " Callers=" + Debug.getCallers(3));
-        if (!isTransitionSet() || mNextAppTransition == TRANSIT_NONE) {
-            setAppTransition(transit);
+        if (forceOverride || isKeyguardTransit(transit) || !isTransitionSet()
+                || mNextAppTransition == TRANSIT_NONE) {
+            setAppTransition(transit, flags);
         } else if (!alwaysKeepCurrent) {
             if (transit == TRANSIT_TASK_OPEN && isTransitionEqual(TRANSIT_TASK_CLOSE)) {
                 // Opening a new task always supersedes a close for the anim.
-                setAppTransition(transit);
+                setAppTransition(transit, flags);
             } else if (transit == TRANSIT_ACTIVITY_OPEN
                     && isTransitionEqual(TRANSIT_ACTIVITY_CLOSE)) {
                 // Opening a new activity always supersedes a close for the anim.
-                setAppTransition(transit);
+                setAppTransition(transit, flags);
             }
         }
         boolean prepared = prepare();
@@ -1960,6 +2023,20 @@
     }
 
     /**
+     * @return true if {@param transit} is representing a transition in which Keyguard is going
+     *         away, false otherwise
+     */
+    public static boolean isKeyguardGoingAwayTransit(int transit) {
+        return transit == TRANSIT_KEYGUARD_GOING_AWAY
+                || transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
+    }
+
+    private static boolean isKeyguardTransit(int transit) {
+        return isKeyguardGoingAwayTransit(transit) || transit == TRANSIT_KEYGUARD_OCCLUDE
+                || transit == TRANSIT_KEYGUARD_UNOCCLUDE;
+    }
+
+    /**
      * @return whether the specified {@param uiMode} is the TV mode.
      */
     private boolean isTvUiMode(int uiMode) {
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index e774259..e1b598a 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -17,6 +17,8 @@
 package com.android.server.wm;
 
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
+
+import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
@@ -95,6 +97,8 @@
     // that if recents doesn't tell us to remove the prolonged animation, we will get rid of it
     // when new animation is set.
     private boolean mClearProlongedAnimation;
+    private int mTransit;
+    private int mTransitFlags;
 
     /** WindowStateAnimator from mAppAnimator.allAppWindows as of last performLayout */
     ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<>();
@@ -114,15 +118,16 @@
         mAnimator = mService.mAnimator;
     }
 
-    public void setAnimation(Animation anim, int width, int height, boolean skipFirstFrame,
-            int stackClip) {
+    public void setAnimation(Animation anim, int width, int height, int parentWidth,
+            int parentHeight, boolean skipFirstFrame, int stackClip, int transit,
+            int transitFlags) {
         if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting animation in " + mAppToken
                 + ": " + anim + " wxh=" + width + "x" + height
                 + " hasContentToDisplay=" + mAppToken.hasContentToDisplay());
         animation = anim;
         animating = false;
         if (!anim.isInitialized()) {
-            anim.initialize(width, height, width, height);
+            anim.initialize(width, height, parentWidth, parentHeight);
         }
         anim.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
         anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
@@ -144,7 +149,9 @@
         hasTransformation = true;
         mStackClip = stackClip;
 
-        this.mSkipFirstFrame = skipFirstFrame;
+        mSkipFirstFrame = skipFirstFrame;
+        mTransit = transit;
+        mTransitFlags = transitFlags;
 
         if (!mAppToken.fillsParent()) {
             anim.setBackgroundColor(0);
@@ -185,12 +192,22 @@
             mAppToken.clearAllDrawn();
         }
         mStackClip = STACK_CLIP_BEFORE_ANIM;
+        mTransit = TRANSIT_UNSET;
+        mTransitFlags = 0;
     }
 
     public boolean isAnimating() {
         return animation != null || mAppToken.inPendingTransaction;
     }
 
+    public int getTransit() {
+        return mTransit;
+    }
+
+    int getTransitFlags() {
+        return mTransitFlags;
+    }
+
     public void clearThumbnail() {
         if (thumbnail != null) {
             thumbnail.hide();
@@ -216,6 +233,7 @@
             toAppAnimator.updateLayers();
             updateLayers();
             toAppAnimator.usingTransferredAnimation = true;
+            toAppAnimator.mTransit = mTransit;
         }
         if (transferWinAnimator != null) {
             mAllAppWinAnimators.remove(transferWinAnimator);
@@ -435,6 +453,8 @@
         if (animating || animation != null) {
             pw.print(prefix); pw.print("animating="); pw.println(animating);
             pw.print(prefix); pw.print("animation="); pw.println(animation);
+            pw.print(prefix); pw.print("mTransit="); pw.println(mTransit);
+            pw.print(prefix); pw.print("mTransitFlags="); pw.println(mTransitFlags);
         }
         if (hasTransformation) {
             pw.print(prefix); pw.print("XForm: ");
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 56eaa83..622eece 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -19,27 +19,34 @@
 import static android.app.ActivityManager.StackId;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
 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.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
 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_STARTING_WINDOW;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
 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.NOTIFY_ACTIVITY_DRAWN;
 import static com.android.server.wm.WindowManagerService.H.NOTIFY_STARTING_WINDOW_DRAWN;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
 import static com.android.server.wm.WindowManagerService.logWithStack;
 
+import android.os.Debug;
 import com.android.server.input.InputApplicationHandle;
 import com.android.server.wm.WindowManagerService.H;
 
@@ -152,6 +159,9 @@
     int mRotationAnimationHint;
     private int mPendingRelaunchCount;
 
+    private boolean mLastContainsShowWhenLockedWindow;
+    private boolean mLastContainsDismissKeyguardWindow;
+
     private ArrayList<WindowSurfaceController.SurfaceControlWithBackground> mSurfaceViewBackgrounds =
         new ArrayList<>();
 
@@ -393,6 +403,63 @@
         return super.checkCompleteDeferredRemoval();
     }
 
+    void onRemovedFromDisplay() {
+        AppWindowToken startingToken = null;
+
+        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + this);
+
+        boolean delayed = setVisibility(null, false, TRANSIT_UNSET, true, voiceInteraction);
+
+        mService.mOpeningApps.remove(this);
+        waitingToShow = false;
+        if (mService.mClosingApps.contains(this)) {
+            delayed = true;
+        } else if (mService.mAppTransition.isTransitionSet()) {
+            mService.mClosingApps.add(this);
+            delayed = true;
+        }
+
+        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app " + this + " delayed=" + delayed
+                + " animation=" + mAppAnimator.animation + " animating=" + mAppAnimator.animating);
+
+        if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
+                + this + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
+
+        final TaskStack stack = mTask.mStack;
+        if (delayed && !isEmpty()) {
+            // set the token aside because it has an active animation to be finished
+            if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM,
+                    "removeAppToken make exiting: " + this);
+            stack.mExitingAppTokens.add(this);
+            mIsExiting = true;
+        } else {
+            // Make sure there is no animation running on this token, so any windows associated
+            // with it will be removed as soon as their animations are complete
+            mAppAnimator.clearAnimation();
+            mAppAnimator.animating = false;
+            removeIfPossible();
+        }
+
+        removed = true;
+        if (startingData != null) {
+            startingToken = this;
+        }
+        stopFreezingScreen(true, true);
+        if (mService.mFocusedApp == this) {
+            if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this);
+            mService.mFocusedApp = null;
+            mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
+            mService.mInputMonitor.setFocusedAppLw(null);
+        }
+
+        if (!delayed) {
+            updateReportedVisibilityLocked();
+        }
+
+        // Will only remove if startingToken non null.
+        mService.scheduleRemoveStartingWindowLocked(startingToken);
+    }
+
     void clearAnimatingFlags() {
         boolean wallpaperMightChange = false;
         for (int i = mChildren.size() - 1; i >= 0; i--) {
@@ -676,6 +743,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);
@@ -690,6 +785,13 @@
         if (gotReplacementWindow) {
             mService.scheduleWindowReplacementTimeouts(this);
         }
+        checkKeyguardFlagsChanged();
+    }
+
+    @Override
+    void removeChild(WindowState child) {
+        super.removeChild(child);
+        checkKeyguardFlagsChanged();
     }
 
     private boolean waitingForReplacement() {
@@ -780,21 +882,6 @@
         }
     }
 
-    /**
-     * See {@link WindowManagerService#overridePlayingAppAnimationsLw}
-     */
-    void overridePlayingAppAnimations(Animation a) {
-        if (mAppAnimator.isAnimating()) {
-            final WindowState win = findMainWindow();
-            if (win == null) {
-                return;
-            }
-            final int width = win.mContainingFrame.width();
-            final int height = win.mContainingFrame.height();
-            mAppAnimator.setAnimation(a, width, height, false, STACK_CLIP_NONE);
-        }
-    }
-
     void resetJustMovedInStack() {
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             (mChildren.get(i)).resetJustMovedInStack();
@@ -918,8 +1005,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 +1035,7 @@
 
             mService.updateFocusedWindowLocked(
                     UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
-            mService.getDefaultDisplayContentLocked().setLayoutNeeded();
+            getDisplayContent().setLayoutNeeded();
             mService.mWindowPlacerLocked.performSurfacePlacement();
             Binder.restoreCallingIdentity(origId);
             return true;
@@ -1197,6 +1283,35 @@
         mFillsParent = fillsParent;
     }
 
+    boolean containsDismissKeyguardWindow() {
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            if ((mChildren.get(i).mAttrs.flags & FLAG_DISMISS_KEYGUARD) != 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    boolean containsShowWhenLockedWindow() {
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            if ((mChildren.get(i).mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void checkKeyguardFlagsChanged() {
+        final boolean containsDismissKeyguard = containsDismissKeyguardWindow();
+        final boolean containsShowWhenLocked = containsShowWhenLockedWindow();
+        if (containsDismissKeyguard != mLastContainsDismissKeyguardWindow
+                || containsShowWhenLocked != mLastContainsShowWhenLockedWindow) {
+            mService.notifyKeyguardFlagsChanged(null /* callback */);
+        }
+        mLastContainsDismissKeyguardWindow = containsDismissKeyguard;
+        mLastContainsShowWhenLockedWindow = containsShowWhenLocked;
+    }
+
     @Override
     void dump(PrintWriter pw, String prefix) {
         super.dump(pw, prefix);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 7cd9971..ec4cdf2 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -29,9 +29,13 @@
 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;
@@ -40,57 +44,67 @@
 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_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 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_SCREEN_ON;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
-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.DEBUG_SCREENSHOT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
+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_WALLPAPER_LIGHT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
 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;
@@ -107,13 +121,14 @@
 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;
@@ -123,6 +138,7 @@
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 
 /**
@@ -138,14 +154,24 @@
     /** Unique identifier of this stack. */
     private final int mDisplayId;
 
-    // The display only has 2 child window containers. mTaskStackContainers which contains all
-    // window containers that are related to apps (Activities) and mNonAppWindowContainers which
-    // contains all window containers not related to apps (e.g. Status bar).
+    /** The containers below are the only child containers the display can have. */
+    // Contains all window containers that are related to apps (Activities)
     private final TaskStackContainers mTaskStackContainers = new TaskStackContainers();
-    private final NonAppWindowContainers mNonAppWindowContainers = new NonAppWindowContainers();
+    // Contains all non-app window containers that should be displayed above the app containers
+    // (e.g. Status bar)
+    private final NonAppWindowContainers mAboveAppWindowsContainers =
+            new NonAppWindowContainers("mAboveAppWindowsContainers");
+    // Contains all non-app window containers that should be displayed below the app containers
+    // (e.g. Wallpaper).
+    private final NonAppWindowContainers mBelowAppWindowsContainers =
+            new NonAppWindowContainers("mBelowAppWindowsContainers");
+    // Contains all IME window containers. Note that the z-ordering of the IME windows will depend
+    // on the IME target. We mainly have this container grouping so we can keep track of all the IME
+    // window containers together and move them in-sync if/when needed.
+    private final NonAppWindowContainers mImeWindowsContainers =
+            new NonAppWindowContainers("mImeWindowsContainers");
 
-    /** Z-ordered (bottom-most first) list of all Window objects. Assigned to an element
-     * from mDisplayWindows; */
+    // Z-ordered (bottom-most first) list of all Window objects.
     private final WindowList mWindows = new WindowList();
 
     // Mapping from a token IBinder to a WindowToken object on this display.
@@ -168,6 +194,7 @@
     // Accessed directly by all users.
     private boolean mLayoutNeeded;
     int pendingLayoutChanges;
+    // TODO(multi-display): remove some of the usages.
     final boolean isDefaultDisplay;
 
     /** Window tokens that are in the process of exiting, but still on screen for animations. */
@@ -196,6 +223,7 @@
     private boolean mDeferredRemoval;
 
     final DockedStackDividerController mDividerControllerLocked;
+    final PinnedStackController mPinnedStackControllerLocked;
 
     final DimLayerController mDimLayerController;
 
@@ -204,6 +232,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 =
@@ -237,21 +273,20 @@
         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.
+        super.addChild(mBelowAppWindowsContainers, null);
         super.addChild(mTaskStackContainers, null);
-        super.addChild(mNonAppWindowContainers, null);
+        super.addChild(mAboveAppWindowsContainers, null);
+        super.addChild(mImeWindowsContainers, null);
     }
 
     int getDisplayId() {
         return mDisplayId;
     }
 
-    WindowList getWindowList() {
-        return mWindows;
-    }
-
     WindowToken getWindowToken(IBinder binder) {
         return mTokenMap.get(binder);
     }
@@ -279,18 +314,57 @@
         if (token.asAppWindowToken() == null) {
             // Add non-app token to container hierarchy on the display. App tokens are added through
             // the parent container managing them (e.g. Tasks).
-            mNonAppWindowContainers.addChild(token, null);
+            switch (token.windowType) {
+                case TYPE_WALLPAPER:
+                    mBelowAppWindowsContainers.addChild(token);
+                    break;
+                case TYPE_INPUT_METHOD:
+                case TYPE_INPUT_METHOD_DIALOG:
+                    mImeWindowsContainers.addChild(token);
+                    break;
+                default:
+                    mAboveAppWindowsContainers.addChild(token);
+                    break;
+            }
         }
     }
 
     WindowToken removeWindowToken(IBinder binder) {
         final WindowToken token = mTokenMap.remove(binder);
         if (token != null && token.asAppWindowToken() == null) {
-            mNonAppWindowContainers.removeChild(token);
+            switch (token.windowType) {
+                case TYPE_WALLPAPER:
+                    mBelowAppWindowsContainers.removeChild(token);
+                    break;
+                case TYPE_INPUT_METHOD:
+                case TYPE_INPUT_METHOD_DIALOG:
+                    mImeWindowsContainers.removeChild(token);
+                    break;
+                default:
+                    mAboveAppWindowsContainers.removeChild(token);
+                    break;
+            }
         }
         return token;
     }
 
+    void removeAppToken(IBinder binder) {
+        final WindowToken token = removeWindowToken(binder);
+        if (token == null) {
+            Slog.w(TAG_WM, "removeAppToken: Attempted to remove non-existing token: " + binder);
+            return;
+        }
+
+        final AppWindowToken appToken = token.asAppWindowToken();
+
+        if (appToken == null) {
+            Slog.w(TAG_WM, "Attempted to remove non-App token: " + binder + " token=" + token);
+            return;
+        }
+
+        appToken.onRemovedFromDisplay();
+    }
+
     Display getDisplay() {
         return mDisplay;
     }
@@ -307,6 +381,10 @@
         return mDividerControllerLocked;
     }
 
+    PinnedStackController getPinnedStackController() {
+        return mPinnedStackControllerLocked;
+    }
+
     /**
      * Returns true if the specified UID has access to this display.
      */
@@ -345,6 +423,7 @@
         mService.reconfigureDisplayLocked(this);
 
         getDockedDividerController().onConfigurationChanged();
+        getPinnedStackController().onConfigurationChanged();
     }
 
     /**
@@ -427,24 +506,7 @@
             }
             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");
+            if (policy.isKeyguardShowingAndNotOccluded()) {
                 return mService.mLastKeyguardForcedOrientation;
             }
         }
@@ -508,9 +570,72 @@
         out.set(mContentRect);
     }
 
-    /** Refer to {@link WindowManagerService#attachStack(int, int, boolean)} */
-    void attachStack(TaskStack stack, boolean onTop) {
-        mTaskStackContainers.attachStack(stack, onTop);
+    /**
+     * Adds the stack to this display.
+     * @see WindowManagerService#addStackToDisplay(int, int, boolean)
+     */
+    Rect addStackToDisplay(int stackId, boolean onTop) {
+        boolean attachedToDisplay = false;
+        TaskStack stack = mService.mStackIdToStack.get(stackId);
+        if (stack == null) {
+            if (DEBUG_STACK) Slog.d(TAG_WM, "Create new stackId=" + stackId + " on displayId="
+                    + mDisplayId);
+
+            stack = getStackById(stackId);
+            if (stack != null) {
+                // It's already attached to the display...clear mDeferRemoval and move stack to
+                // appropriate z-order on display as needed.
+                stack.mDeferRemoval = false;
+                moveStack(stack, onTop);
+                attachedToDisplay = true;
+            } else {
+                stack = new TaskStack(mService, stackId);
+            }
+
+            mService.mStackIdToStack.put(stackId, stack);
+            if (stackId == DOCKED_STACK_ID) {
+                mDividerControllerLocked.notifyDockedStackExistsChanged(true);
+            }
+        } else {
+            final DisplayContent currentDC = stack.getDisplayContent();
+            if (currentDC != null) {
+                throw new IllegalStateException("Trying to add stackId=" + stackId
+                        + "to displayId=" + mDisplayId + ", but it's already attached to displayId="
+                        + currentDC.getDisplayId());
+            }
+        }
+
+        if (!attachedToDisplay) {
+            mTaskStackContainers.addStackToDisplay(stack, onTop);
+        }
+
+        if (stack.getRawFullscreen()) {
+            return null;
+        }
+        final Rect bounds = new Rect();
+        stack.getRawBounds(bounds);
+        return bounds;
+    }
+
+    /** Removes the stack from the display and prepares for changing the parent. */
+    private void removeStackFromDisplay(TaskStack stack) {
+        mTaskStackContainers.removeStackFromDisplay(stack);
+    }
+
+    /** Moves the stack to this display and returns the updated bounds. */
+    Rect moveStackToDisplay(TaskStack stack) {
+        final DisplayContent currentDisplayContent = stack.getDisplayContent();
+        if (currentDisplayContent == null) {
+            throw new IllegalStateException("Trying to move stackId=" + stack.mStackId
+                    + " which is not currently attached to any display");
+        }
+        if (stack.getDisplayContent().getDisplayId() == mDisplayId) {
+            throw new IllegalArgumentException("Trying to move stackId=" + stack.mStackId
+                    + " to its current displayId=" + mDisplayId);
+        }
+
+        currentDisplayContent.removeStackFromDisplay(stack);
+        return addStackToDisplay(stack.mStackId, true /* onTop */);
     }
 
     void moveStack(TaskStack stack, boolean toTop) {
@@ -539,14 +664,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);
@@ -607,7 +724,7 @@
             win.getTouchableRegion(mTmpRegion);
             mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
         }
-        if (getDockedStackVisibleForUserLocked() != null) {
+        if (getDockedStackLocked() != null) {
             mDividerControllerLocked.getTouchRegion(mTmpRect);
             mTmpRegion.set(mTmpRect);
             mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
@@ -618,9 +735,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);
@@ -635,7 +752,7 @@
         rebuildAppWindowList();
     }
 
-    void resetAnimationBackgroundAnimator() {
+    private void resetAnimationBackgroundAnimator() {
         for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
             mTaskStackContainers.get(stackNdx).resetAnimationBackgroundAnimator();
         }
@@ -645,7 +762,7 @@
         return mDimLayerController.animateDimLayers();
     }
 
-    void resetDimming() {
+    private void resetDimming() {
         mDimLayerController.resetDimming();
     }
 
@@ -653,7 +770,7 @@
         return mDimLayerController.isDimming();
     }
 
-    void stopDimmingIfNeeded() {
+    private void stopDimmingIfNeeded() {
         mDimLayerController.stopDimmingIfNeeded();
     }
 
@@ -788,6 +905,7 @@
             mDividerControllerLocked.setAdjustedForIme(
                     false /*ime*/, false /*divider*/, dockVisible /*animate*/, imeWin, imeHeight);
         }
+        mPinnedStackControllerLocked.setAdjustedForIme(imeVisible, imeHeight);
     }
 
     void setInputMethodAnimLayerAdjustment(int adj) {
@@ -908,7 +1026,7 @@
                     + " mLayoutNeeded=" + mLayoutNeeded);
 
         pw.println();
-        pw.println("  Application tokens in top down Z order:");
+        pw.println(prefix + "Application tokens in top down Z order:");
         for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) {
             final TaskStack stack = mTaskStackContainers.get(stackNdx);
             stack.dump(prefix + "  ", pw);
@@ -927,9 +1045,11 @@
             }
         }
         pw.println();
-        mDimLayerController.dump(prefix + "  ", pw);
+        mDimLayerController.dump(prefix, pw);
         pw.println();
-        mDividerControllerLocked.dump(prefix + "  ", pw);
+        mDividerControllerLocked.dump(prefix, pw);
+        pw.println();
+        mPinnedStackControllerLocked.dump(prefix, pw);
 
         if (mInputMethodAnimLayerAdjustment != 0) {
             pw.println(subPrefix
@@ -956,11 +1076,10 @@
 
     /**
      * Like {@link #getDockedStackLocked}, but also returns the docked stack if it's currently not
-     * visible, as long as it's not hidden because the current user doesn't have any tasks there.
+     * visible.
      */
-    TaskStack getDockedStackVisibleForUserLocked() {
-        final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
-        return (stack != null && stack.isVisible(true /* ignoreKeyguard */)) ? stack : null;
+    TaskStack getDockedStackIgnoringVisibility() {
+        return mService.mStackIdToStack.get(DOCKED_STACK_ID);
     }
 
     /** Find the visible, touch-deliverable window under the given point */
@@ -998,10 +1117,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) {
@@ -1016,11 +1134,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),
@@ -1085,12 +1202,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
@@ -1128,7 +1246,7 @@
                 }
             }
             addWindowToListBefore(win, pos);
-            return 0;
+            return;
         }
 
         // Continue looking down until we find the first token that has windows on this display.
@@ -1154,7 +1272,7 @@
                 }
             }
             addWindowToListAfter(win, pos);
-            return 0;
+            return;
         }
 
         // Just search for the start of this layer.
@@ -1175,7 +1293,6 @@
                 + mWindows.size());
         mWindows.add(i + 1, win);
         mService.mWindowsChanged = true;
-        return 0;
     }
 
     /** Adds this non-app window to the window list. */
@@ -1205,34 +1322,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;
@@ -1282,14 +1400,14 @@
 
     /** 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)) {
+        if (mWallpaperController.adjustWallpaperWindows(mWindows.getReadOnly())) {
             assignWindowLayers(true /*setLayoutNeeded*/);
         }
     }
@@ -1386,6 +1504,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();
@@ -1467,8 +1739,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
@@ -1476,8 +1746,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.
@@ -1492,7 +1762,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++;
@@ -1500,7 +1770,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++;
@@ -1513,17 +1783,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 {
@@ -1540,7 +1810,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 {
@@ -1565,11 +1835,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));
@@ -1582,7 +1851,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;
@@ -1607,7 +1876,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="
@@ -1623,7 +1892,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);
@@ -1688,7 +1957,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;
                 }
@@ -1741,7 +2010,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;
@@ -1754,13 +2022,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);
         }
     }
 
@@ -1769,7 +2037,7 @@
         mLayoutNeeded = true;
     }
 
-    void clearLayoutNeeded() {
+    private void clearLayoutNeeded() {
         if (DEBUG_LAYOUT) Slog.w(TAG_WM, "clearLayoutNeeded: callers=" + Debug.getCallers(3));
         mLayoutNeeded = false;
     }
@@ -1778,23 +2046,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
@@ -1804,16 +2069,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. */
@@ -1862,9 +2120,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));
         }
     }
 
@@ -1909,6 +2166,20 @@
         }
     }
 
+    /**
+     * Starts the Keyguard exit animation on all windows that don't belong to an app token.
+     */
+    void startKeyguardExitOnNonAppWindows(boolean onWallpaper, boolean goingToShade) {
+        final WindowManagerPolicy policy = mService.mPolicy;
+        for (int i = mWindows.size() - 1; i >= 0; i--) {
+            final WindowState window = mWindows.get(i);
+            if (window.mAppToken == null && policy.canBeHiddenByKeyguardLw(window)) {
+                window.mWinAnimator.setAnimation(
+                        policy.createHiddenByKeyguardExit(onWallpaper, goingToShade));
+            }
+        }
+    }
+
     boolean checkWaitingForWindows() {
 
         boolean haveBootMsg = false;
@@ -1964,59 +2235,10 @@
     }
 
     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);
@@ -2035,129 +2257,6 @@
                                 "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;
@@ -2182,77 +2281,7 @@
                     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) {
@@ -2418,19 +2447,683 @@
         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)) {
+            if (win.isVisibleLw() && (win.mAppToken != null || 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);
+
+            // TODO(multi-display): For now adjusting wallpaper only on primary display to avoid
+            // the wallpaper window jumping across displays.
+            // Remove check for default display when there will be support for multiple wallpaper
+            // targets (on different displays).
+            if (isDefaultDisplay && (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.obtainMessage(SEND_NEW_CONFIGURATION, mDisplayId).sendToTarget();
                 }
             }
+
+            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);
+                    mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow(),
+                            mService.mInputMethodTarget);
+                }
+                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.canBeHiddenByKeyguardLw(win))
+                    || 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.canBeHiddenByKeyguardLw(win)) {
+                    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();
         }
     }
 
@@ -2485,9 +3178,13 @@
      * Window container class that contains all containers on this display relating to Apps.
      * I.e Activities.
      */
-    private class TaskStackContainers extends DisplayChildWindowContainer<TaskStack> {
+    private final class TaskStackContainers extends DisplayChildWindowContainer<TaskStack> {
 
-        void attachStack(TaskStack stack, boolean onTop) {
+        /**
+         * Adds the stack to this container.
+         * @see WindowManagerService#addStackToDisplay(int, int, boolean)
+         */
+        void addStackToDisplay(TaskStack stack, boolean onTop) {
             if (stack.mStackId == HOME_STACK_ID) {
                 if (mHomeStack != null) {
                     throw new IllegalArgumentException("attachStack: HOME_STACK_ID (0) not first.");
@@ -2498,6 +3195,21 @@
             stack.onDisplayChanged(DisplayContent.this);
         }
 
+        /** Removes the stack from its container and prepare for changing the parent. */
+        void removeStackFromDisplay(TaskStack stack) {
+            removeChild(stack);
+            stack.onRemovedFromDisplay();
+            // TODO: remove when window list will be gone.
+            // Manually remove records from window list and tap excluded windows list.
+            for (int i = mWindows.size() - 1; i >= 0; --i) {
+                final WindowState windowState = mWindows.get(i);
+                if (stack == windowState.getStack()) {
+                    mWindows.remove(i);
+                    mTapExcludedWindows.remove(windowState);
+                }
+            }
+        }
+
         void moveStack(TaskStack stack, boolean toTop) {
             if (StackId.isAlwaysOnTop(stack.mStackId) && !toTop) {
                 // This stack is always-on-top silly...
@@ -2567,7 +3279,28 @@
      * Window container class that contains all containers on this display that are not related to
      * Apps. E.g. status bar.
      */
-    private static class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> {
+    private final class NonAppWindowContainers extends DisplayChildWindowContainer<WindowToken> {
+        /**
+         * Compares two child window tokens returns -1 if the first is lesser than the second in
+         * terms of z-order and 1 otherwise.
+         */
+        final Comparator<WindowToken> mWindowComparator = (token1, token2) ->
+                // Tokens with higher base layer are z-ordered on-top.
+                mService.mPolicy.windowTypeToLayerLw(token1.windowType)
+                < mService.mPolicy.windowTypeToLayerLw(token2.windowType) ? -1 : 1;
 
+        private final String mName;
+        NonAppWindowContainers(String name) {
+            mName = name;
+        }
+
+        void addChild(WindowToken token) {
+            addChild(token, mWindowComparator);
+        }
+
+        @Override
+        String getName() {
+            return mName;
+        }
     }
 }
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 8b5f62e..743caf8 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -44,7 +44,6 @@
 import android.util.Slog;
 import android.view.DisplayInfo;
 import android.view.IDockedStackListener;
-import android.view.SurfaceControl;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
@@ -57,7 +56,6 @@
 import com.android.server.wm.WindowManagerService.H;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 
 /**
  * Keeps information about the docked stack divider.
@@ -268,7 +266,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();
         }
@@ -283,7 +281,7 @@
         if (mWindow == null) {
             return;
         }
-        TaskStack stack = mDisplayContent.mService.mStackIdToStack.get(DOCKED_STACK_ID);
+        TaskStack stack = mDisplayContent.getDockedStackIgnoringVisibility();
 
         // If the stack is invisible, we policy force hide it in WindowAnimator.shouldForceHide
         final boolean visible = stack != null;
@@ -371,6 +369,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);
@@ -535,7 +534,7 @@
     }
 
     private void checkMinimizeChanged(boolean animate) {
-        if (mDisplayContent.getDockedStackVisibleForUserLocked() == null) {
+        if (mDisplayContent.getDockedStackIgnoringVisibility() == null) {
             return;
         }
         final TaskStack homeStack = mDisplayContent.getHomeStack();
@@ -682,7 +681,7 @@
     }
 
     private boolean setMinimizedDockedStack(boolean minimized) {
-        final TaskStack stack = mDisplayContent.getDockedStackVisibleForUserLocked();
+        final TaskStack stack = mDisplayContent.getDockedStackIgnoringVisibility();
         notifyDockedStackMinimizedChanged(minimized, 0);
         return stack != null && stack.setAdjustedForMinimizedDock(minimized ? 1f : 0f);
     }
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..1ccf722
--- /dev/null
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -0,0 +1,318 @@
+/*
+ * 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 android.view.Display.DEFAULT_DISPLAY;
+
+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.DisplayInfo;
+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 ValueAnimator mBoundsAnimator = null;
+
+    // Used to calculate stack bounds across rotations
+    private final DisplayInfo mDisplayInfo = new DisplayInfo();
+
+    // 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();
+    private final Rect mTmpRect = 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;
+            });
+        }
+
+        @Override
+        public void setSnapToEdge(final boolean snapToEdge) {
+            mHandler.post(() -> {
+                mSnapAlgorithm.setSnapToEdge(snapToEdge);
+            });
+        }
+    }
+
+    /**
+     * 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());
+        mDisplayInfo.copyFrom(mDisplayContent.getDisplayInfo());
+        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 Rect insetBounds = new Rect();
+        getInsetBounds(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) {
+        return getMovementBounds(stackBounds, true /* adjustForIme */);
+    }
+
+    /**
+     * @return the movement bounds for the given {@param stackBounds} and the current state of the
+     *         controller.
+     */
+    Rect getMovementBounds(Rect stackBounds, boolean adjustForIme) {
+        final Rect movementBounds = new Rect();
+        getInsetBounds(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());
+
+        // Apply the movement bounds adjustments based on the current state
+        if (adjustForIme) {
+            if (mIsImeShowing) {
+                movementBounds.bottom -= mImeHeight;
+            }
+        }
+        return movementBounds;
+    }
+
+    /**
+     * @return the repositioned PIP bounds given it's pre-change bounds, and the new display info.
+     */
+    Rect onDisplayChanged(Rect preChangeStackBounds, DisplayInfo displayInfo) {
+        final Rect postChangeStackBounds = new Rect(preChangeStackBounds);
+        if (!mDisplayInfo.equals(displayInfo)) {
+            // Calculate the snap fraction of the current stack along the old movement bounds, and
+            // then update the stack bounds to the same fraction along the rotated movement bounds.
+            final Rect preChangeMovementBounds = getMovementBounds(preChangeStackBounds);
+            final float snapFraction = mSnapAlgorithm.getSnapFraction(preChangeStackBounds,
+                    preChangeMovementBounds);
+            mDisplayInfo.copyFrom(displayInfo);
+
+            final Rect postChangeMovementBounds = getMovementBounds(preChangeStackBounds,
+                    false /* adjustForIme */);
+            mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
+                    snapFraction);
+        }
+        return postChangeStackBounds;
+    }
+
+    /**
+     * 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);
+        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
+            final Rect movementBounds = getMovementBounds(stackBounds);
+            final Rect toBounds = new Rect(stackBounds);
+            if (adjustedForIme) {
+                // IME visible
+                toBounds.offset(0, Math.min(0, movementBounds.bottom - stackBounds.top));
+            } else {
+                // IME hidden
+                if (stackBounds.top == prevMovementBounds.bottom) {
+                    // If the PIP is resting on top of the IME, then adjust it with the hiding IME
+                    toBounds.offsetTo(toBounds.left, movementBounds.bottom);
+                }
+            }
+            if (!toBounds.equals(stackBounds)) {
+                if (mBoundsAnimator != null) {
+                    mBoundsAnimator.cancel();
+                }
+                mBoundsAnimator = mMotionHelper.createAnimationToBounds(stackBounds, toBounds);
+                mBoundsAnimator.start();
+            }
+        }
+    }
+
+    /**
+     * 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(Rect outRect) {
+        mService.mPolicy.getStableInsetsLw(mDisplayInfo.rotation, mDisplayInfo.logicalWidth,
+                mDisplayInfo.logicalHeight, mTmpInsets);
+        outRect.set(mTmpInsets.left + mScreenEdgeInsets.x, mTmpInsets.top + mScreenEdgeInsets.y,
+                mDisplayInfo.logicalWidth - mTmpInsets.right - mScreenEdgeInsets.x,
+                mDisplayInfo.logicalHeight - mTmpInsets.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.print(prefix + "  defaultBounds="); getDefaultBounds().printShortString(pw);
+        pw.println();
+        mService.getStackBounds(PINNED_STACK_ID, mTmpRect);
+        pw.print(prefix + "  movementBounds="); getMovementBounds(mTmpRect).printShortString(pw);
+        pw.println();
+        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 24a0d1a..f038135 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,17 +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
-    // tokens for but that are not current attached to any display. We need to track this here
-    // because a binder token can be added through {@link WindowManagerService#addWindowToken},
-    // but we don't know what display windows for the token will be added to until
-    // {@link WindowManagerService#addWindow} is called.
-    private final HashMap<IBinder, Integer> mUnattachedBinderTokens = new HashMap();
-
     // State for the RemoteSurfaceTrace system used in testing. If this is enabled SurfaceControl
     // instances will be replaced with an instance that writes a binary representation of all
     // commands to mSurfaceTraceFd.
@@ -236,7 +204,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);
@@ -247,50 +215,6 @@
         return dc;
     }
 
-    /** Adds the input stack id to the input display id and returns the bounds of the added stack.*/
-    Rect addStackToDisplay(int stackId, int displayId, boolean onTop) {
-        final DisplayContent dc = getDisplayContent(displayId);
-        if (dc == null) {
-            Slog.w(TAG_WM, "addStackToDisplay: Trying to add stackId=" + stackId
-                    + " to unknown displayId=" + displayId + " callers=" + Debug.getCallers(6));
-            return null;
-        }
-
-        boolean attachedToDisplay = false;
-        TaskStack stack = mService.mStackIdToStack.get(stackId);
-        if (stack == null) {
-            if (DEBUG_STACK) Slog.d(TAG_WM, "attachStack: stackId=" + stackId);
-
-            stack = dc.getStackById(stackId);
-            if (stack != null) {
-                // It's already attached to the display...clear mDeferRemoval and move stack to
-                // appropriate z-order on display as needed.
-                stack.mDeferRemoval = false;
-                dc.moveStack(stack, onTop);
-                attachedToDisplay = true;
-            } else {
-                stack = new TaskStack(mService, stackId);
-            }
-
-            mService.mStackIdToStack.put(stackId, stack);
-            if (stackId == DOCKED_STACK_ID) {
-                mService.getDefaultDisplayContentLocked().mDividerControllerLocked
-                        .notifyDockedStackExistsChanged(true);
-            }
-        }
-
-        if (!attachedToDisplay) {
-            dc.attachStack(stack, onTop);
-        }
-
-        if (stack.getRawFullscreen()) {
-            return null;
-        }
-        final Rect bounds = new Rect();
-        stack.getRawBounds(bounds);
-        return bounds;
-    }
-
     boolean isLayoutNeeded() {
         final int numDisplays = mChildren.size();
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
@@ -306,14 +230,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())
@@ -334,7 +258,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) {
@@ -351,7 +275,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);
@@ -364,36 +288,6 @@
         return null;
     }
 
-    /** Return the window token associated with the input binder token on the input display */
-    WindowToken getWindowToken(IBinder binder, DisplayContent dc) {
-        final WindowToken token = dc.getWindowToken(binder);
-        if (token != null) {
-            return token;
-        }
-
-        // There is no window token mapped to the binder on the display. Create and map a window
-        // token if it is currently allowed.
-        if (!mUnattachedBinderTokens.containsKey(binder)) {
-            return null;
-        }
-
-        final int type = mUnattachedBinderTokens.get(binder);
-        return new WindowToken(mService, binder, type, true, dc);
-    }
-
-    /** Returns all window tokens mapped to the input binder. */
-    ArrayList<WindowToken> getWindowTokens(IBinder binder) {
-        mTmpTokensList.clear();
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final DisplayContent dc = mChildren.get(i);
-            final WindowToken token = dc.getWindowToken(binder);
-            if (token != null) {
-                mTmpTokensList.add(token);
-            }
-        }
-        return mTmpTokensList;
-    }
-
     /**
      * Returns the app window token for the input binder if it exist in the system.
      * NOTE: Only one AppWindowToken is allowed to exist in the system for a binder token, since
@@ -427,139 +321,6 @@
         return null;
     }
 
-    void addWindowToken(IBinder binder, int type) {
-        if (mUnattachedBinderTokens.containsKey(binder)) {
-            Slog.w(TAG_WM, "addWindowToken: Attempted to add existing binder token: " + binder);
-            return;
-        }
-
-        final ArrayList<WindowToken> tokens = getWindowTokens(binder);
-
-        if (!tokens.isEmpty()) {
-            Slog.w(TAG_WM, "addWindowToken: Attempted to add binder token: " + binder
-                    + " for already created window tokens: " + tokens);
-            return;
-        }
-
-        mUnattachedBinderTokens.put(binder, type);
-
-        // 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 DisplayContent dc = getDisplayContent(DEFAULT_DISPLAY);
-        final WindowToken token = new WindowToken(mService, binder, type, true, dc);
-        if (type == TYPE_WALLPAPER) {
-            dc.mWallpaperController.addWallpaperToken(token);
-        }
-    }
-
-    ArrayList<WindowToken> removeWindowToken(IBinder binder) {
-        mUnattachedBinderTokens.remove(binder);
-
-        mTmpTokensList.clear();
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final DisplayContent dc = mChildren.get(i);
-            final WindowToken token = dc.removeWindowToken(binder);
-            if (token != null) {
-                mTmpTokensList.add(token);
-            }
-        }
-        return mTmpTokensList;
-    }
-
-    /**
-     * Removed the mapping to the input binder for the system if it no longer as a window token
-     * associated with it on any display.
-     */
-    void removeWindowTokenIfPossible(IBinder binder) {
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final DisplayContent dc = mChildren.get(i);
-            final WindowToken token = dc.getWindowToken(binder);
-            if (token != null) {
-                return;
-            }
-        }
-
-        mUnattachedBinderTokens.remove(binder);
-    }
-
-    void removeAppToken(IBinder binder) {
-        final ArrayList<WindowToken> removedTokens = removeWindowToken(binder);
-        if (removedTokens == null || removedTokens.isEmpty()) {
-            Slog.w(TAG_WM, "removeAppToken: Attempted to remove non-existing token: " + binder);
-            return;
-        }
-
-        for (int i = removedTokens.size() - 1; i >= 0; --i) {
-            WindowToken wtoken = removedTokens.get(i);
-            AppWindowToken appToken = wtoken.asAppWindowToken();
-
-            if (appToken == null) {
-                Slog.w(TAG_WM,
-                        "Attempted to remove non-App token: " + binder + " wtoken=" + wtoken);
-                continue;
-            }
-
-            AppWindowToken startingToken = null;
-
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + appToken);
-
-            boolean delayed = appToken.setVisibility(null, false, TRANSIT_UNSET, true,
-                    appToken.voiceInteraction);
-
-            mService.mOpeningApps.remove(appToken);
-            appToken.waitingToShow = false;
-            if (mService.mClosingApps.contains(appToken)) {
-                delayed = true;
-            } else if (mService.mAppTransition.isTransitionSet()) {
-                mService.mClosingApps.add(appToken);
-                delayed = true;
-            }
-
-            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app " + appToken
-                    + " delayed=" + delayed
-                    + " animation=" + appToken.mAppAnimator.animation
-                    + " animating=" + appToken.mAppAnimator.animating);
-
-            if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
-                    + appToken + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
-
-            final TaskStack stack = appToken.mTask.mStack;
-            if (delayed && !appToken.isEmpty()) {
-                // set the token aside because it has an active animation to be finished
-                if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM,
-                        "removeAppToken make exiting: " + appToken);
-                stack.mExitingAppTokens.add(appToken);
-                appToken.mIsExiting = true;
-            } else {
-                // Make sure there is no animation running on this token, so any windows associated
-                // with it will be removed as soon as their animations are complete
-                appToken.mAppAnimator.clearAnimation();
-                appToken.mAppAnimator.animating = false;
-                appToken.removeIfPossible();
-            }
-
-            appToken.removed = true;
-            if (appToken.startingData != null) {
-                startingToken = appToken;
-            }
-            appToken.stopFreezingScreen(true, true);
-            if (mService.mFocusedApp == appToken) {
-                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + appToken);
-                mService.mFocusedApp = null;
-                mService.updateFocusedWindowLocked(
-                        UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
-                mService.mInputMonitor.setFocusedAppLw(null);
-            }
-
-            if (!delayed) {
-                appToken.updateReportedVisibilityLocked();
-            }
-
-            // Will only remove if startingToken non null.
-            mService.scheduleRemoveStartingWindowLocked(startingToken);
-        }
-    }
-
     // TODO: Users would have their own window containers under the display container?
     void switchUser() {
         final int count = mChildren.size();
@@ -569,8 +330,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;
@@ -603,6 +389,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();
@@ -611,7 +407,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)) {
@@ -624,17 +420,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);
             }
         }
     }
@@ -642,7 +437,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);
@@ -657,7 +452,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);
@@ -677,7 +472,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;
@@ -711,84 +506,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;
-        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 = dc.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 && 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);
         }
     }
 
@@ -803,57 +524,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++) {
@@ -1145,8 +842,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;
             }
@@ -1202,8 +901,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;
 
@@ -1226,214 +925,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) {
-                    dc.adjustWallpaperWindows();
-                }
-
-                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()
-                        && dc.mWallpaperController.isWallpaperTarget(w)) {
-                    // This is the wallpaper target and its obscured state changed... make sure the
-                    // current wallpaper's visibility has been updated accordingly.
-                    dc.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.
-                            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 +960,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 +981,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 +1090,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/Task.java b/services/core/java/com/android/server/wm/Task.java
index 19c9b7d..b889db2 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. */
@@ -349,7 +350,7 @@
         return mFillsParent
                 || !StackId.isTaskResizeableByDockedStack(mStack.mStackId)
                 || displayContent == null
-                || displayContent.getDockedStackVisibleForUserLocked() != null;
+                || displayContent.getDockedStackIgnoringVisibility() != null;
     }
 
     /** Original bounds of the task if applicable, otherwise fullscreen rect. */
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 9effb8d..a0270c6 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().onDisplayChanged(mBounds,
+                        getDisplayInfo());
+                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);
@@ -617,6 +627,7 @@
         mAnimationBackgroundSurface = new DimLayer(mService, this, mDisplayContent.getDisplayId(),
                 "animation background stackId=" + mStackId);
 
+        final Rect oldBounds = new Rect(mBounds);
         Rect bounds = null;
         final TaskStack dockedStack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
         if (mStackId == DOCKED_STACK_ID
@@ -641,6 +652,12 @@
 
         updateDisplayInfo(bounds);
 
+        // Update the pinned stack controller after the display info is updated
+        if (mStackId == PINNED_STACK_ID) {
+            mDisplayContent.getPinnedStackController().onDisplayChanged(oldBounds,
+                    getDisplayInfo());
+        }
+
         super.onDisplayChanged(dc);
     }
 
@@ -776,6 +793,14 @@
     void removeImmediately() {
         super.removeImmediately();
 
+        onRemovedFromDisplay();
+    }
+
+    /**
+     * Removes the stack it from its current parent, so it can be either destroyed completely or
+     * re-parented.
+     */
+    void onRemovedFromDisplay() {
         mDisplayContent.mDimLayerController.removeDimLayerUser(this);
         EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
 
@@ -783,14 +808,13 @@
             mAnimationBackgroundSurface.destroySurface();
             mAnimationBackgroundSurface = null;
         }
-        mDisplayContent = null;
-
-        mService.mWindowPlacerLocked.requestTraversal();
 
         if (mStackId == DOCKED_STACK_ID) {
-            mService.getDefaultDisplayContentLocked().mDividerControllerLocked
-                    .notifyDockedStackExistsChanged(false);
+            mDisplayContent.mDividerControllerLocked.notifyDockedStackExistsChanged(false);
         }
+
+        mDisplayContent = null;
+        mService.mWindowPlacerLocked.requestTraversal();
     }
 
     void resetAnimationBackgroundAnimator() {
@@ -860,7 +884,7 @@
             mAdjustImeAmount = adjustAmount;
             mAdjustDividerAmount = adjustDividerAmount;
             updateAdjustedBounds();
-            return isVisible(true /* ignoreKeyguard */);
+            return isVisible();
         } else {
             return false;
         }
@@ -896,7 +920,7 @@
         if (minimizeAmount != mMinimizeAmount) {
             mMinimizeAmount = minimizeAmount;
             updateAdjustedBounds();
-            return isVisible(true /* ignoreKeyguard */);
+            return isVisible();
         } else {
             return false;
         }
@@ -1010,7 +1034,7 @@
         }
 
         if (dockSide == DOCKED_TOP) {
-            mService.getStableInsetsLocked(mTmpRect);
+            mService.getStableInsetsLocked(DEFAULT_DISPLAY, mTmpRect);
             int topInset = mTmpRect.top;
             mTmpAdjustedBounds.set(mBounds);
             mTmpAdjustedBounds.bottom =
@@ -1041,7 +1065,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) {
@@ -1207,21 +1231,6 @@
         }
     }
 
-    boolean isVisible() {
-        return isVisible(false /* ignoreKeyguard */);
-    }
-
-    boolean isVisible(boolean ignoreKeyguard) {
-        final boolean keyguardOn = mService.mPolicy.isKeyguardShowingOrOccluded()
-                && !mService.mAnimator.mKeyguardGoingAway;
-        if (!ignoreKeyguard && keyguardOn && !StackId.isAllowedOverLockscreen(mStackId)) {
-            // The keyguard is showing and the stack shouldn't show on top of the keyguard.
-            return false;
-        }
-
-        return super.isVisible();
-    }
-
     boolean hasTaskForUser(int userId) {
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final Task task = mChildren.get(i);
diff --git a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
new file mode 100644
index 0000000..2f49c82
--- /dev/null
+++ b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
@@ -0,0 +1,139 @@
+/*
+ * 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 android.annotation.NonNull;
+import android.util.ArrayMap;
+
+import com.android.server.wm.WindowManagerService.H;
+
+import java.io.PrintWriter;
+
+/**
+ * Manages the set of {@link AppWindowToken}s for which we don't know yet whether it's visible or
+ * not. This happens when starting an activity while the lockscreen is showing. In that case, the
+ * keyguard flags an app might set influence it's visibility, so we wait until this is resolved to
+ * start the transition to avoid flickers.
+ */
+class UnknownAppVisibilityController {
+
+    /**
+     * We are currently waiting until the app is done resuming.
+     */
+    private static final int UNKNOWN_STATE_WAITING_RESUME = 1;
+
+    /**
+     * The activity has finished resuming, and we are waiting on the next relayout.
+     */
+    private static final int UNKNOWN_STATE_WAITING_RELAYOUT = 2;
+
+    /**
+     * The client called {@link Session#relayout} with the appropriate Keyguard flags and we are
+     * waiting until activity manager has updated the visibilities of all the apps.
+     */
+    private static final int UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE = 3;
+
+    // Set of apps for which we don't know yet whether it's visible or not, depending on what kind
+    // of lockscreen flags the app might set during its first relayout.
+    private final ArrayMap<AppWindowToken, Integer> mUnknownApps = new ArrayMap<>();
+
+    private final WindowManagerService mService;
+
+    UnknownAppVisibilityController(WindowManagerService service) {
+        mService = service;
+    }
+
+    boolean allResolved() {
+        return mUnknownApps.isEmpty();
+    }
+
+    void clear() {
+        mUnknownApps.clear();
+    }
+
+    String getDebugMessage() {
+        final StringBuilder builder = new StringBuilder();
+        for (int i = mUnknownApps.size() - 1; i >= 0; i--) {
+            builder.append("app=").append(mUnknownApps.keyAt(i))
+                    .append(" state=").append(mUnknownApps.valueAt(i));
+            if (i != 0) {
+                builder.append(' ');
+            }
+        }
+        return builder.toString();
+    }
+
+    void appRemoved(@NonNull AppWindowToken appWindow) {
+        mUnknownApps.remove(appWindow);
+    }
+
+    /**
+     * Notifies that {@param appWindow} has been launched behind Keyguard, and we need to wait until
+     * it is resumed and relaid out to resolve the visibility.
+     */
+    void notifyLaunched(@NonNull AppWindowToken appWindow) {
+        mUnknownApps.put(appWindow, UNKNOWN_STATE_WAITING_RESUME);
+    }
+
+    /**
+     * Notifies that {@param appWindow} has finished resuming.
+     */
+    void notifyAppResumedFinished(@NonNull AppWindowToken appWindow) {
+        if (mUnknownApps.containsKey(appWindow)
+                && mUnknownApps.get(appWindow) == UNKNOWN_STATE_WAITING_RESUME) {
+            mUnknownApps.put(appWindow, UNKNOWN_STATE_WAITING_RELAYOUT);
+        }
+    }
+
+    /**
+     * Notifies that {@param appWindow} has relaid out.
+     */
+    void notifyRelayouted(@NonNull AppWindowToken appWindow) {
+        if (!mUnknownApps.containsKey(appWindow)) {
+            return;
+        }
+        int state = mUnknownApps.get(appWindow);
+        if (state == UNKNOWN_STATE_WAITING_RELAYOUT) {
+            mUnknownApps.put(appWindow, UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE);
+            mService.notifyKeyguardFlagsChanged(this::notifyVisibilitiesUpdated);
+        }
+    }
+
+    private void notifyVisibilitiesUpdated() {
+        boolean changed = false;
+        for (int i = mUnknownApps.size() - 1; i >= 0; i--) {
+            if (mUnknownApps.valueAt(i) == UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE) {
+                mUnknownApps.removeAt(i);
+                changed = true;
+            }
+        }
+        if (changed) {
+            mService.mWindowPlacerLocked.performSurfacePlacement();
+        }
+    }
+
+    void dump(PrintWriter pw, String prefix) {
+        if (mUnknownApps.isEmpty()) {
+            return;
+        }
+        pw.println(prefix + "Unknown visibilities:");
+        for (int i = mUnknownApps.size() - 1; i >= 0; i--) {
+            pw.println(prefix + "  app=" + mUnknownApps.keyAt(i)
+                    + " state=" + mUnknownApps.valueAt(i));
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 4ab8887..250d381 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -18,9 +18,12 @@
 
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 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.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+
+import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
@@ -39,6 +42,7 @@
 import android.util.Slog;
 import android.view.DisplayInfo;
 import android.view.WindowManager;
+import android.view.animation.Animation;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -126,6 +130,16 @@
         return isWallpaperVisible(mWallpaperTarget);
     }
 
+    /**
+     * Starts {@param a} on all wallpaper windows.
+     */
+    void startWallpaperAnimation(Animation a) {
+        for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+            final WindowToken token = mWallpaperTokens.get(curTokenNdx);
+            token.startAnimation(a);
+        }
+    }
+
     private boolean isWallpaperVisible(WindowState wallpaperTarget) {
         if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
                 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
@@ -374,7 +388,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;
@@ -383,6 +397,7 @@
         boolean inFreeformSpace = false;
         boolean replacing = false;
         boolean keyguardGoingAwayWithWallpaper = false;
+        boolean needsShowWhenLockedWallpaper = false;
 
         for (int i = windows.size() - 1; i >= 0; i--) {
             w = windows.get(i);
@@ -413,7 +428,19 @@
 
             replacing |= w.mWillReplaceWindow;
             keyguardGoingAwayWithWallpaper |= (w.mAppToken != null
-                    && w.mWinAnimator.mKeyguardGoingAwayWithWallpaper);
+                    && AppTransition.isKeyguardGoingAwayTransit(
+                            w.mAppToken.mAppAnimator.getTransit())
+                    && (w.mAppToken.mAppAnimator.getTransitFlags()
+                            & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0);
+
+            if ((w.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0
+                    && mService.mPolicy.isKeyguardLocked()
+                    && mService.mPolicy.isKeyguardOccluded()) {
+                // The lowest show when locked window decides whether we need to put the wallpaper
+                // behind.
+                needsShowWhenLockedWallpaper = !isFullscreen(w.mAttrs)
+                        || (w.mAppToken != null && !w.mAppToken.fillsParent());
+            }
 
             final boolean hasWallpaper = (w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
             if (hasWallpaper && w.isOnScreen() && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
@@ -447,17 +474,22 @@
             // appear and can determine the visibility, to avoid flickering.
             result.setWallpaperTarget(result.topWallpaper, result.topWallpaperIndex);
 
-        } else if (keyguardGoingAwayWithWallpaper) {
-            // If the app is executing an animation because the keyguard is going away (and the
-            // keyguard was showing the wallpaper) keep the wallpaper during the animation so it
-            // doesn't flicker out by having it be its own target.
+        } else if (keyguardGoingAwayWithWallpaper || needsShowWhenLockedWallpaper) {
+            // Keep the wallpaper during Keyguard exit but also when it's needed for a
+            // non-fullscreen show when locked activity.
             result.setWallpaperTarget(result.topWallpaper, result.topWallpaperIndex);
         }
     }
 
+    private boolean isFullscreen(WindowManager.LayoutParams attrs) {
+        return attrs.x == 0 && attrs.y == 0
+                && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
+                && attrs.height == WindowManager.LayoutParams.MATCH_PARENT;
+    }
+
     /** 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 +590,7 @@
         return true;
     }
 
-    private boolean updateWallpaperWindowsTargetByLayer(WindowList windows,
+    private boolean updateWallpaperWindowsTargetByLayer(ReadOnlyWindowList windows,
             FindWallpaperTargetResult result) {
 
         WindowState wallpaperTarget = result.wallpaperTarget;
@@ -609,7 +641,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,7 +660,7 @@
         return changed;
     }
 
-    boolean adjustWallpaperWindows(WindowList windows) {
+    boolean adjustWallpaperWindows(ReadOnlyWindowList windows) {
         mService.mRoot.mWallpaperMayChange = false;
 
         // First find top-most window that has asked to be on top of the wallpaper;
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 4c62245..993a918 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -17,11 +17,7 @@
 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_DOCK_DIVIDER;
 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;
@@ -39,7 +35,6 @@
 import android.view.Choreographer;
 import android.view.SurfaceControl;
 import android.view.WindowManagerPolicy;
-import android.view.animation.Animation;
 
 import java.io.PrintWriter;
 
@@ -50,9 +45,6 @@
 public class WindowAnimator {
     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 */
-    static final long KEYGUARD_ANIM_TIMEOUT_MS = 1000;
-
     final WindowManagerService mService;
     final Context mContext;
     final WindowManagerPolicy mPolicy;
@@ -86,37 +78,10 @@
 
     boolean mInitialized = false;
 
-    boolean mKeyguardGoingAway;
-    int mKeyguardGoingAwayFlags;
-    boolean mKeyguardAnimatingIn;
-
-    /** Use one animation for all entering activities after keyguard is dismissed. */
-    Animation mPostKeyguardExitAnimation;
-
-    // forceHiding states.
-    static final int KEYGUARD_NOT_SHOWN     = 0;
-    static final int KEYGUARD_SHOWN         = 1;
-    static final int KEYGUARD_ANIMATING_OUT = 2;
-    int mForceHiding = KEYGUARD_NOT_SHOWN;
-
     // When set to true the animator will go over all windows after an animation frame is posted and
     // check if some got replaced and can be removed.
     private boolean mRemoveReplacedWindows = false;
 
-    private final AppTokenList mTmpExitingAppTokens = new AppTokenList();
-
-    /** The window that was previously hiding the Keyguard. */
-    WindowState mLastShowWinWhenLocked;
-
-    String forceHidingToString() {
-        switch (mForceHiding) {
-            case KEYGUARD_NOT_SHOWN:    return "KEYGUARD_NOT_SHOWN";
-            case KEYGUARD_SHOWN:        return "KEYGUARD_SHOWN";
-            case KEYGUARD_ANIMATING_OUT:return "KEYGUARD_ANIMATING_OUT";
-            default: return "KEYGUARD STATE UNKNOWN " + mForceHiding;
-        }
-    }
-
     WindowAnimator(final WindowManagerService service) {
         mService = service;
         mContext = service.mContext;
@@ -153,63 +118,6 @@
         mDisplayContentsAnimators.delete(displayId);
     }
 
-    /**
-     * @return The window that is currently hiding the Keyguard, or if it was hiding the Keyguard,
-     *         and it's still animating.
-     */
-    private WindowState getWinShowWhenLockedOrAnimating() {
-        final WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw();
-        if (winShowWhenLocked != null) {
-            return winShowWhenLocked;
-        }
-        if (mLastShowWinWhenLocked != null && mLastShowWinWhenLocked.isOnScreen()
-                && mLastShowWinWhenLocked.isAnimatingLw()
-                && (mLastShowWinWhenLocked.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
-            return mLastShowWinWhenLocked;
-        }
-        return null;
-    }
-
-    boolean shouldForceHide(WindowState win) {
-        final WindowState imeTarget = mService.mInputMethodTarget;
-        final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleNow() &&
-                ((imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0
-                        || !mPolicy.canBeForceHidden(imeTarget, imeTarget.mAttrs));
-
-        final WindowState winShowWhenLocked = getWinShowWhenLockedOrAnimating();
-        final AppWindowToken appShowWhenLocked = winShowWhenLocked == null ?
-                null : winShowWhenLocked.mAppToken;
-
-        boolean allowWhenLocked = false;
-        // Show IME over the keyguard if the target allows it
-        allowWhenLocked |= (win.mIsImWindow || imeTarget == win) && showImeOverKeyguard;
-        // Show SHOW_WHEN_LOCKED windows that turn on the screen
-        allowWhenLocked |= (win.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0 && win.mTurnOnScreen;
-
-        if (appShowWhenLocked != null) {
-            allowWhenLocked |= appShowWhenLocked == win.mAppToken
-                    // Show all SHOW_WHEN_LOCKED windows if some apps are shown over lockscreen
-                    || (win.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0
-                    // Show error dialogs over apps that are shown on lockscreen
-                    || (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0;
-        }
-
-        // Allow showing a window that dismisses Keyguard if the policy allows it. This is used for
-        // when the policy knows that the Keyguard can be dismissed without user interaction to
-        // provide a smooth transition in that case.
-        allowWhenLocked |= (win.mAttrs.flags & FLAG_DISMISS_KEYGUARD) != 0
-                && mPolicy.canShowDismissingWindowWhileLockedLw();
-
-        // Only hide windows if the keyguard is active and not animating away.
-        boolean keyguardOn = mPolicy.isKeyguardShowingOrOccluded()
-                && mForceHiding != KEYGUARD_ANIMATING_OUT
-                && !mKeyguardAnimatingIn;
-        boolean hideDockDivider = win.mAttrs.type == TYPE_DOCK_DIVIDER
-                && win.getDisplayContent().getDockedStackLocked() == null;
-        return keyguardOn && !allowWhenLocked && (win.getDisplayId() == DEFAULT_DISPLAY)
-                || hideDockDivider;
-    }
-
     /** Locked on mService.mWindowMap. */
     private void animateLocked(long frameTimeNs) {
         if (!mInitialized) {
@@ -388,7 +296,6 @@
         if (dumpAll) {
             pw.print(prefix); pw.print("mAnimTransactionSequence=");
                     pw.print(mAnimTransactionSequence);
-                    pw.print(" mForceHiding="); pw.println(forceHidingToString());
             pw.print(prefix); pw.print("mCurrentTime=");
                     pw.println(TimeUtils.formatUptime(mCurrentTime));
         }
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index db61c3e..e30ebcb 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -413,12 +413,6 @@
         }
     }
 
-    void overridePlayingAppAnimations(Animation a) {
-        for (int i = mChildren.size() - 1; i >= 0; i--) {
-            mChildren.get(i).overridePlayingAppAnimations(a);
-        }
-    }
-
     void setOrientation(int orientation) {
         mOrientation = orientation;
     }
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 40001b2..7723752 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,32 +166,32 @@
 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;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
 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.INPUT_FEATURE_NO_INPUT_CHANNEL;
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 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_DRAG;
-import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
 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;
@@ -204,6 +204,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;
@@ -219,8 +220,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;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
@@ -241,7 +240,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
@@ -521,14 +519,13 @@
     int mLastOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
     boolean mAltOrientation = false;
 
-    private boolean mKeyguardWaitingForActivityDrawn;
-
     int mDockedStackCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
     Rect mDockedStackCreateBounds;
 
     private final SparseIntArray mTmpTaskIds = new SparseIntArray();
 
     boolean mForceResizableTasks = false;
+    boolean mSupportsPictureInPicture = false;
 
     int getDragLayerLocked() {
         return mPolicy.windowTypeToLayerLw(TYPE_DRAG) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
@@ -586,6 +583,9 @@
     final ArraySet<AppWindowToken> mOpeningApps = new ArraySet<>();
     final ArraySet<AppWindowToken> mClosingApps = new ArraySet<>();
 
+    final UnknownAppVisibilityController mUnknownAppVisibilityController =
+            new UnknownAppVisibilityController(this);
+
     boolean mIsTouchDevice;
 
     final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
@@ -620,10 +620,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;
@@ -895,7 +891,7 @@
             = new WindowManagerInternal.AppTransitionListener() {
 
         @Override
-        public void onAppTransitionCancelledLocked() {
+        public void onAppTransitionCancelledLocked(int transit) {
             mH.sendEmptyMessage(H.NOTIFY_APP_TRANSITION_CANCELLED);
         }
 
@@ -1039,7 +1035,10 @@
         mWindowAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),
                 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
         mTransitionAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),
-                Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScaleSetting);
+                Settings.Global.TRANSITION_ANIMATION_SCALE,
+                context.getResources().getFloat(
+                        R.dimen.config_appTransitionAnimationDurationScaleDefault));
+
         setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
                 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting));
 
@@ -1167,8 +1166,8 @@
             final boolean hasParent = parentWindow != null;
             // Use existing parent window token for child windows since they go in the same token
             // as there parent window so we can apply the same policy on them.
-            WindowToken token = mRoot.getWindowToken(
-                    hasParent ? parentWindow.mAttrs.token : attrs.token, displayContent);
+            WindowToken token = displayContent.getWindowToken(
+                    hasParent ? parentWindow.mAttrs.token : attrs.token);
             // If this is a child window, we want to apply the same type checking rules as the
             // parent window type.
             final int rootType = hasParent ? parentWindow.mAttrs.type : type;
@@ -1220,7 +1219,7 @@
                         return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                     }
                 }
-                token = new WindowToken(this, attrs.token, -1, false, displayContent);
+                token = new WindowToken(this, attrs.token, type, false, displayContent);
             } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
                 atoken = token.asAppWindowToken();
                 if (atoken == null) {
@@ -1288,7 +1287,7 @@
                 // It is not valid to use an app token with other system types; we will
                 // instead make a new token for it (as if null had been passed in for the token).
                 attrs.token = null;
-                token = new WindowToken(this, null, -1, false, displayContent);
+                token = new WindowToken(this, null, type, false, displayContent);
             }
 
             WindowState win = new WindowState(this, session, client, token, parentWindow,
@@ -1413,7 +1412,7 @@
             win.applyAdjustForImeIfNeeded();
 
             if (type == TYPE_DOCK_DIVIDER) {
-                getDefaultDisplayContentLocked().getDockedDividerController().setWindow(win);
+                mRoot.getDisplayContent(displayId).getDockedDividerController().setWindow(win);
             }
 
             final WindowStateAnimator winAnimator = win.mWinAnimator;
@@ -1480,13 +1479,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);
@@ -1881,11 +1880,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) {
@@ -1927,6 +1928,10 @@
                         | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
                     win.mLayoutNeeded = true;
                 }
+                if (win.mAppToken != null && ((flagChanges & FLAG_SHOW_WHEN_LOCKED) != 0
+                        || (flagChanges & FLAG_DISMISS_KEYGUARD) != 0)) {
+                    win.mAppToken.checkKeyguardFlagsChanged();
+                }
             }
 
             if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility
@@ -2066,16 +2071,20 @@
             }
 
             if (wallpaperMayMove) {
-                getDefaultDisplayContentLocked().pendingLayoutChanges |=
+                win.getDisplayContent().pendingLayoutChanges |=
                         WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
             }
 
+            if (win.mAppToken != null) {
+                mUnknownAppVisibilityController.notifyRelayouted(win.mAppToken);
+            }
+
             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();
+                DisplayInfo displayInfo = win.getDisplayContent().getDisplayInfo();
                 dc.mWallpaperController.updateWallpaperOffset(
                         win, displayInfo.logicalWidth, displayInfo.logicalHeight, false);
             }
@@ -2121,7 +2130,7 @@
         }
 
         if (configChanged) {
-            sendNewConfiguration();
+            sendNewConfiguration(displayId);
         }
         Binder.restoreCallingIdentity(origId);
         return result;
@@ -2156,9 +2165,8 @@
             }
             win.destroyOrSaveSurface();
         }
-        //TODO (multidisplay): Magnification is supported only for the default
-        if (mAccessibilityController != null
-                && win.getDisplayId() == 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;
@@ -2278,7 +2286,7 @@
         }
     }
 
-    public void finishDrawingWindow(Session session, IWindow client) {
+    void finishDrawingWindow(Session session, IWindow client) {
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mWindowMap) {
@@ -2287,7 +2295,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();
@@ -2353,8 +2361,10 @@
                 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + atoken);
                 final int containingWidth = frame.width();
                 final int containingHeight = frame.height();
-                atoken.mAppAnimator.setAnimation(a, containingWidth, containingHeight,
-                        mAppTransition.canSkipFirstFrame(), mAppTransition.getAppStackClipMode());
+                atoken.mAppAnimator.setAnimation(a, containingWidth, containingHeight, width,
+                        height, mAppTransition.canSkipFirstFrame(),
+                        mAppTransition.getAppStackClipMode(),
+                        transit, mAppTransition.getTransitFlags());
             }
         } else {
             atoken.mAppAnimator.clearAnimation();
@@ -2385,18 +2395,29 @@
     }
 
     @Override
-    public void addWindowToken(IBinder token, int type) {
+    public void addWindowToken(IBinder binder, int type, int displayId) {
         if (!checkCallingPermission(MANAGE_APP_TOKENS, "addWindowToken()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         synchronized(mWindowMap) {
-            mRoot.addWindowToken(token, type);
+            final DisplayContent dc = mRoot.getDisplayContentOrCreate(displayId);
+            WindowToken token = dc.getWindowToken(binder);
+            if (token != null) {
+                Slog.w(TAG_WM, "addWindowToken: Attempted to add binder token: " + binder
+                        + " for already created window token: " + token
+                        + " displayId=" + displayId);
+                return;
+            }
+            token = new WindowToken(this, binder, type, true, dc);
+            if (type == TYPE_WALLPAPER) {
+                dc.mWallpaperController.addWallpaperToken(token);
+            }
         }
     }
 
     @Override
-    public void removeWindowToken(IBinder token) {
+    public void removeWindowToken(IBinder binder, int displayId) {
         if (!checkCallingPermission(MANAGE_APP_TOKENS, "removeWindowToken()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
@@ -2404,22 +2425,26 @@
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mWindowMap) {
-                final ArrayList<WindowToken> removedTokens = mRoot.removeWindowToken(token);
-                if (removedTokens == null || removedTokens.isEmpty()) {
-                    Slog.w(TAG_WM,
-                            "removeWindowToken: Attempted to remove non-existing token: " + token);
+                final DisplayContent dc = mRoot.getDisplayContent(displayId);
+                if (dc == null) {
+                    Slog.w(TAG_WM, "removeWindowToken: Attempted to remove token: " + binder
+                            + " for non-exiting displayId=" + displayId);
                     return;
                 }
 
-                for (int i = removedTokens.size() - 1; i >= 0; --i) {
-                    final WindowToken wtoken = removedTokens.get(i);
-                    wtoken.setExiting();
-                    if (wtoken.windowType == TYPE_WALLPAPER) {
-                        wtoken.getDisplayContent().mWallpaperController.removeWallpaperToken(wtoken);
-                    }
-
-                    mInputMonitor.updateInputWindowsLw(true /*force*/);
+                final WindowToken token = dc.removeWindowToken(binder);
+                if (token == null) {
+                    Slog.w(TAG_WM,
+                            "removeWindowToken: Attempted to remove non-existing token: " + binder);
+                    return;
                 }
+
+                token.setExiting();
+                if (token.windowType == TYPE_WALLPAPER) {
+                    dc.mWallpaperController.removeWallpaperToken(token);
+                }
+
+                mInputMonitor.updateInputWindowsLw(true /*force*/);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -2530,32 +2555,34 @@
     }
 
     @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) {
@@ -2564,7 +2591,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
@@ -2574,10 +2601,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()) {
@@ -2593,31 +2620,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 {
-            // TODO: multi-display
-            int req = getDefaultDisplayContentLocked().getOrientation();
+            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;
                 }
@@ -2643,8 +2667,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");
         }
 
@@ -2653,7 +2677,7 @@
                 mWaitingForConfig = false;
                 mLastFinishedFreezeSource = "new-config";
             }
-            return mRoot.setGlobalConfigurationIfNeeded(config);
+            return mRoot.setDisplayOverrideConfigurationIfNeeded(overrideConfig, displayId);
         }
     }
 
@@ -2697,11 +2721,11 @@
     }
 
     void setFocusTaskRegionLocked() {
-        if (mFocusedApp != null) {
-            final Task task = mFocusedApp.mTask;
-            final DisplayContent displayContent = task.getDisplayContent();
+        final Task focusedTask = mFocusedApp != null ? mFocusedApp.mTask : null;
+        if (focusedTask != null) {
+            final DisplayContent displayContent = focusedTask.getDisplayContent();
             if (displayContent != null) {
-                displayContent.setTouchExcludeRegion(task);
+                displayContent.setTouchExcludeRegion(focusedTask);
             }
         }
     }
@@ -2741,20 +2765,28 @@
         }
     }
 
+    @Override
+    public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
+        prepareAppTransition(transit, alwaysKeepCurrent, 0 /* flags */, false /* forceOverride */);
+    }
+
     /**
      * @param transit What kind of transition is happening. Use one of the constants
      *                AppTransition.TRANSIT_*.
      * @param alwaysKeepCurrent If true and a transition is already set, new transition will NOT
      *                          be set.
+     * @param flags Additional flags for the app transition, Use a combination of the constants
+     *              AppTransition.TRANSIT_FLAG_*.
+     * @param forceOverride Always override the transit, not matter what was set previously.
      */
-    @Override
-    public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
+    public void prepareAppTransition(int transit, boolean alwaysKeepCurrent, int flags,
+            boolean forceOverride) {
         if (!checkCallingPermission(MANAGE_APP_TOKENS, "prepareAppTransition()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
         synchronized(mWindowMap) {
-            boolean prepared = mAppTransition.prepareAppTransitionLocked(
-                    transit, alwaysKeepCurrent);
+            boolean prepared = mAppTransition.prepareAppTransitionLocked(transit, alwaysKeepCurrent,
+                    flags, forceOverride);
             if (prepared && okToDisplay()) {
                 mSkipAppTransitionAnimation = false;
             }
@@ -3189,6 +3221,19 @@
         }
     }
 
+    /**
+     * Notifies that we launched an app that might be visible or not visible depending on what kind
+     * of Keyguard flags it's going to set on its windows.
+     */
+    public void notifyUnknownAppVisibilityLaunched(IBinder token) {
+        synchronized(mWindowMap) {
+            AppWindowToken appWindow = mRoot.getAppWindowToken(token);
+            if (appWindow != null) {
+                mUnknownAppVisibilityController.notifyLaunched(appWindow);
+            }
+        }
+    }
+
     @Override
     public void startAppFreezingScreen(IBinder token, int configChanges) {
         if (!checkCallingPermission(MANAGE_APP_TOKENS, "setAppFreezingScreen()")) {
@@ -3232,7 +3277,7 @@
     }
 
     @Override
-    public void removeAppToken(IBinder token) {
+    public void removeAppToken(IBinder binder, int displayId) {
         if (!checkCallingPermission(MANAGE_APP_TOKENS, "removeAppToken()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
@@ -3240,7 +3285,13 @@
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized(mWindowMap) {
-                mRoot.removeAppToken(token);
+                final DisplayContent dc = mRoot.getDisplayContent(displayId);
+                if (dc == null) {
+                    Slog.w(TAG_WM, "removeAppToken: Attempted to remove binder token: " + binder
+                            + " from non-existing displayId=" + displayId);
+                    return;
+                }
+                dc.removeAppToken(binder);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -3274,51 +3325,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 {
@@ -3343,7 +3349,7 @@
                 if (mAppTransition.isTransitionSet()) {
                     task.setSendingToBottom(false);
                 }
-                rebuildAppWindowsAndLayoutIfNeededLocked(displayContent);
+                displayContent.rebuildAppWindowsAndLayoutIfNeeded();
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -3365,7 +3371,7 @@
                 if (mAppTransition.isTransitionSet()) {
                     task.setSendingToBottom(true);
                 }
-                rebuildAppWindowsAndLayoutIfNeededLocked(stack.getDisplayContent());
+                stack.getDisplayContent().rebuildAppWindowsAndLayoutIfNeeded();
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -3388,40 +3394,104 @@
         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.
+     * Place a TaskStack on a DisplayContent. Will create a new TaskStack if none is found with
+     * specified stackId.
      * @param stackId The unique identifier of the new stack.
      * @param displayId The unique identifier of the DisplayContent.
      * @param onTop If true the stack will be place at the top of the display,
-     *              else at the bottom
-     * @return The initial bounds the stack was created with. null means fullscreen.
+     *              else at the bottom.
+     * @return The bounds that the stack has after adding. null means fullscreen.
      */
-    public Rect attachStack(int stackId, int displayId, boolean onTop) {
+    public Rect addStackToDisplay(int stackId, int displayId, boolean onTop) {
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mWindowMap) {
-                return mRoot.addStackToDisplay(stackId, displayId, onTop);
+                final DisplayContent dc = mRoot.getDisplayContent(displayId);
+                if (dc == null) {
+                    throw new IllegalArgumentException("Trying to add stackId=" + stackId
+                            + " to unknown displayId=" + displayId);
+                }
+
+                return dc.addStackToDisplay(stackId, onTop);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
     }
 
-    public void detachStack(int stackId) {
+    /**
+     * Move a TaskStack from current DisplayContent to specified one.
+     * @param stackId The unique identifier of the new stack.
+     * @param displayId The unique identifier of the new display.
+     */
+    public Rect moveStackToDisplay(int stackId, int displayId) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mWindowMap) {
+                TaskStack stack = mStackIdToStack.get(stackId);
+                if (stack == null) {
+                    throw new IllegalArgumentException("Trying to move unknown stackId=" + stackId
+                            + " to displayId=" + displayId);
+                }
+
+                final DisplayContent targetDisplayContent = mRoot.getDisplayContent(displayId);
+                if (targetDisplayContent == null) {
+                    throw new IllegalArgumentException("Trying to move stackId=" + stackId
+                            + " to unknown displayId=" + displayId);
+                }
+
+                return targetDisplayContent.moveStackToDisplay(stack);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    /**
+     * Remove a TaskStack completely.
+     * @param stackId The unique identifier of the stack.
+     */
+    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);
@@ -3498,8 +3568,8 @@
     }
 
     @Override
-    public void overridePlayingAppAnimationsLw(Animation a) {
-        getDefaultDisplayContentLocked().overridePlayingAppAnimations(a);
+    public void notifyShowingDreamChanged() {
+        notifyKeyguardFlagsChanged(null /* callback */);
     }
 
     /**
@@ -3639,6 +3709,46 @@
         }
     }
 
+    /**
+     * @return true if the activity contains windows that have
+     *         {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set
+     */
+    public boolean containsShowWhenLockedWindow(IBinder token) {
+        synchronized (mWindowMap) {
+            final AppWindowToken wtoken = mRoot.getAppWindowToken(token);
+            return wtoken != null && wtoken.containsShowWhenLockedWindow();
+        }
+    }
+
+    /**
+     * @return true if the activity contains windows that have
+     *         {@link LayoutParams#FLAG_DISMISS_KEYGUARD} set
+     */
+    public boolean containsDismissKeyguardWindow(IBinder token) {
+        synchronized (mWindowMap) {
+            final AppWindowToken wtoken = mRoot.getAppWindowToken(token);
+            return wtoken != null && wtoken.containsDismissKeyguardWindow();
+        }
+    }
+
+    /**
+     * Notifies activity manager that some Keyguard flags have changed and that it needs to
+     * reevaluate the visibilities of the activities.
+     * @param callback Runnable to be called when activity manager is done reevaluating visibilities
+     */
+    void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
+        final Runnable wrappedCallback = callback != null
+                ? () -> { synchronized (mWindowMap) { callback.run(); } }
+                : null;
+        mH.obtainMessage(H.NOTIFY_KEYGUARD_FLAGS_CHANGED, wrappedCallback).sendToTarget();
+    }
+
+    public boolean isKeyguardTrusted() {
+        synchronized (mWindowMap) {
+            return mPolicy.isKeyguardTrustedLw();
+        }
+    }
+
     // -------------------------------------------------------------
     // Misc IWindowSession methods
     // -------------------------------------------------------------
@@ -3775,6 +3885,12 @@
         }
     }
 
+    public boolean isShowingDream() {
+        synchronized (mWindowMap) {
+            return mPolicy.isShowingDreamLw();
+        }
+    }
+
     @Override
     public void dismissKeyguard() {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
@@ -3788,51 +3904,11 @@
 
     @Override
     public void keyguardGoingAway(int flags) {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
-                != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("Requires DISABLE_KEYGUARD permission");
-        }
-        if (DEBUG_KEYGUARD) Slog.d(TAG_WM,
-                "keyguardGoingAway: flags=0x" + Integer.toHexString(flags));
-        synchronized (mWindowMap) {
-            mAnimator.mKeyguardGoingAway = true;
-            mAnimator.mKeyguardGoingAwayFlags = flags;
-            mWindowPlacerLocked.requestTraversal();
-        }
     }
 
-    public void keyguardWaitingForActivityDrawn() {
-        if (DEBUG_KEYGUARD) Slog.d(TAG_WM, "keyguardWaitingForActivityDrawn");
+    public void onKeyguardOccludedChanged(boolean occluded) {
         synchronized (mWindowMap) {
-            mKeyguardWaitingForActivityDrawn = true;
-        }
-    }
-
-    public void notifyActivityDrawnForKeyguard() {
-        if (DEBUG_KEYGUARD) Slog.d(TAG_WM, "notifyActivityDrawnForKeyguard: waiting="
-                + mKeyguardWaitingForActivityDrawn + " Callers=" + Debug.getCallers(5));
-        synchronized (mWindowMap) {
-            if (mKeyguardWaitingForActivityDrawn) {
-                mPolicy.notifyActivityDrawnForKeyguardLw();
-                mKeyguardWaitingForActivityDrawn = false;
-            }
-        }
-    }
-
-    @Override
-    public void setKeyguardAnimatingIn(boolean animating) {
-        if (!checkCallingPermission(Manifest.permission.CONTROL_KEYGUARD,
-                "keyguardAnimatingIn()")) {
-            throw new SecurityException("Requires CONTROL_KEYGUARD permission");
-        }
-        synchronized (mWindowMap) {
-            mAnimator.mKeyguardAnimatingIn = animating;
-        }
-    }
-
-    public boolean isKeyguardAnimatingIn() {
-        synchronized (mWindowMap) {
-            return mAnimator.mKeyguardAnimatingIn;
+            mPolicy.onKeyguardOccludedChangedLw(occluded);
         }
     }
 
@@ -4405,29 +4481,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,
@@ -4436,8 +4489,9 @@
         }
         try {
             Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenshotWallpaper");
-            return screenshotApplicationsInner(null, 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);
         }
@@ -4455,15 +4509,13 @@
             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
         }
 
-        FgThread.getHandler().post(new Runnable() {
-            @Override
-            public void run() {
-                Bitmap bm = screenshotApplicationsInner(null, 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) {
             }
         });
 
@@ -4507,8 +4559,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) {
@@ -4519,263 +4571,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(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);
     }
 
     /**
@@ -4864,16 +4661,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);
@@ -4882,8 +4680,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();
@@ -4891,7 +4691,7 @@
             }
 
             if (rotationChanged || alwaysSendConfiguration) {
-                sendNewConfiguration();
+                sendNewConfiguration(displayId);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -4899,14 +4699,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.
@@ -4915,7 +4715,7 @@
         }
 
         ScreenRotationAnimation screenRotationAnimation =
-                mAnimator.getScreenRotationAnimationLocked(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
@@ -4927,7 +4727,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;
         }
 
@@ -4937,8 +4738,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);
@@ -4978,24 +4779,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;
@@ -5017,7 +4812,7 @@
             startFreezingDisplayLocked(inTransaction, anim[0], anim[1]);
             // startFreezingDisplayLocked can reset the ScreenRotationAnimation.
             screenRotationAnimation =
-                mAnimator.getScreenRotationAnimationLocked(DEFAULT_DISPLAY);
+                mAnimator.getScreenRotationAnimationLocked(displayId);
         } else {
             // The screen rotation animation uses a screenshot to freeze the screen
             // while windows resize underneath.
@@ -5035,7 +4830,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) {
@@ -5087,6 +4882,7 @@
                 w.mLastFreezeDuration = 0;
             }
         }
+
         if (rotateSeamlessly) {
             mH.removeMessages(H.SEAMLESS_ROTATION_TIMEOUT);
             mH.sendEmptyMessageDelayed(H.SEAMLESS_ROTATION_TIMEOUT, SEAMLESS_ROTATION_TIMEOUT_DURATION);
@@ -5568,13 +5364,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
@@ -5584,7 +5381,7 @@
                     if (mWaitingForConfig) {
                         mWaitingForConfig = false;
                         mLastFinishedFreezeSource = "config-unchanged";
-                        getDefaultDisplayContentLocked().setLayoutNeeded();
+                        mRoot.getDisplayContent(displayId).setLayoutNeeded();
                         mWindowPlacerLocked.performSurfacePlacement();
                     }
                 }
@@ -5593,18 +5390,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;
     }
 
@@ -5713,9 +5510,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
@@ -5776,9 +5572,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;
@@ -6055,33 +5850,29 @@
     private boolean mEventDispatchingEnabled;
 
     @Override
-    public void pauseKeyDispatching(IBinder _token) {
+    public void pauseKeyDispatching(IBinder binder) {
         if (!checkCallingPermission(MANAGE_APP_TOKENS, "pauseKeyDispatching()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         synchronized (mWindowMap) {
-            final ArrayList<WindowToken> tokens = mRoot.getWindowTokens(_token);
-            if (tokens != null && !tokens.isEmpty()) {
-                for (int i = tokens.size() - 1; i >= 0; --i) {
-                    mInputMonitor.pauseDispatchingLw(tokens.get(i));
-                }
+            WindowToken token = mRoot.getAppWindowToken(binder);
+            if (token != null) {
+                mInputMonitor.pauseDispatchingLw(token);
             }
         }
     }
 
     @Override
-    public void resumeKeyDispatching(IBinder _token) {
+    public void resumeKeyDispatching(IBinder binder) {
         if (!checkCallingPermission(MANAGE_APP_TOKENS, "resumeKeyDispatching()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
         synchronized (mWindowMap) {
-            final ArrayList<WindowToken> tokens = mRoot.getWindowTokens(_token);
-            if (tokens != null && !tokens.isEmpty()) {
-                for (int i = tokens.size() - 1; i >= 0; --i) {
-                    mInputMonitor.resumeDispatchingLw(tokens.get(i));
-                }
+            WindowToken token = mRoot.getAppWindowToken(binder);
+            if (token != null) {
+                mInputMonitor.resumeDispatchingLw(token);
             }
         }
     }
@@ -6318,7 +6109,7 @@
         public static final int NOTIFY_DOCKED_STACK_MINIMIZED_CHANGED = 53;
         public static final int SEAMLESS_ROTATION_TIMEOUT = 54;
         public static final int RESTORE_POINTER_ICON = 55;
-
+        public static final int NOTIFY_KEYGUARD_FLAGS_CHANGED = 56;
 
         /**
          * Used to denote that an integer field in a message will not be used.
@@ -6417,11 +6208,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);
                     }
@@ -6668,8 +6457,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;
                 }
 
@@ -6950,23 +6740,14 @@
                     // 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;
+                case NOTIFY_KEYGUARD_FLAGS_CHANGED: {
+                    mAmInternal.notifyKeyguardFlagsChanged((Runnable) msg.obj);
+                }
             }
             if (DEBUG_WINDOW_TRACE) {
                 Slog.v(TAG_WM, "handleMessage: exit");
@@ -7317,16 +7098,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();
@@ -7455,7 +7239,7 @@
 
         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);
@@ -7540,6 +7324,7 @@
         }
     }
 
+    // TODO: Move to DisplayContent
     boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
         WindowState newFocus = mRoot.computeFocusedWindow();
         if (mCurrentFocus != newFocus) {
@@ -7569,9 +7354,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.
@@ -7579,12 +7363,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);
                 }
             }
 
@@ -7596,11 +7379,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;
@@ -7744,7 +7526,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
@@ -7758,11 +7540,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();
         }
     }
 
@@ -8004,6 +7786,15 @@
         }
     }
 
+    public void notifyAppResumedFinished(IBinder token) {
+        synchronized (mWindowMap) {
+            final AppWindowToken appWindow = mRoot.getAppWindowToken(token);
+            if (appWindow != null) {
+                mUnknownAppVisibilityController.notifyAppResumedFinished(appWindow);
+            }
+        }
+    }
+
     @Override
     public int getDockedDividerInsetsLw() {
         return getDefaultDisplayContentLocked().getDockedDividerController().getContentInsets();
@@ -8194,6 +7985,7 @@
                 pw.println();
 
         mInputMonitor.dump(pw, "  ");
+        mUnknownAppVisibilityController.dump(pw, "  ");
 
         if (dumpAll) {
             pw.print("  mSystemDecorLayer="); pw.print(mSystemDecorLayer);
@@ -8233,8 +8025,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");
@@ -8261,7 +8054,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>");
@@ -8279,8 +8072,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()));
@@ -8478,6 +8270,8 @@
     }
 
     // There is an inherent assumption that this will never return null.
+    // 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);
     }
@@ -8617,7 +8411,7 @@
     public int getDockedStackSide() {
         synchronized (mWindowMap) {
             final TaskStack dockedStack = getDefaultDisplayContentLocked()
-                    .getDockedStackVisibleForUserLocked();
+                    .getDockedStackIgnoringVisibility();
             return dockedStack == null ? DOCKED_INVALID : dockedStack.getDockSide();
         }
     }
@@ -8681,13 +8475,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;
         }
@@ -8697,6 +8497,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();
@@ -8708,15 +8523,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) {
@@ -8732,7 +8551,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);
@@ -8865,8 +8684,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");
         }
@@ -8887,8 +8705,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();
             }
         }
     }
@@ -9031,23 +8850,31 @@
         }
 
         @Override
-        public void addWindowToken(IBinder token, int type) {
-            WindowManagerService.this.addWindowToken(token, type);
+        public void addWindowToken(IBinder token, int type, int displayId) {
+            WindowManagerService.this.addWindowToken(token, type, displayId);
         }
 
         @Override
-        public void removeWindowToken(IBinder token, boolean removeWindows) {
+        public void removeWindowToken(IBinder binder, boolean removeWindows, int displayId) {
             synchronized(mWindowMap) {
                 if (removeWindows) {
-                    final ArrayList<WindowToken> removedTokens = mRoot.removeWindowToken(token);
-                    if (removedTokens != null && !removedTokens.isEmpty()) {
-                        for (int i = removedTokens.size() - 1; i >= 0; --i) {
-                            final WindowToken wtoken = removedTokens.get(i);
-                            wtoken.removeAllWindows();
-                        }
+                    final DisplayContent dc = mRoot.getDisplayContent(displayId);
+                    if (dc == null) {
+                        Slog.w(TAG_WM, "removeWindowToken: Attempted to remove token: " + binder
+                                + " for non-exiting displayId=" + displayId);
+                        return;
                     }
+
+                    final WindowToken token = dc.removeWindowToken(binder);
+                    if (token == null) {
+                        Slog.w(TAG_WM, "removeWindowToken: Attempted to remove non-existing token: "
+                                + binder);
+                        return;
+                    }
+
+                    token.removeAllWindows();
                 }
-                WindowManagerService.this.removeWindowToken(token);
+                WindowManagerService.this.removeWindowToken(binder, displayId);
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index f80e085..972c359 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;
@@ -88,6 +87,7 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
@@ -137,9 +137,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 +732,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 +770,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 +789,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 +806,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 +814,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 +838,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();
@@ -988,6 +1031,10 @@
         return mVisibleFrame;
     }
 
+    Rect getStableFrameLw() {
+        return mStableFrame;
+    }
+
     @Override
     public boolean getGivenInsetsPendingLw() {
         return mGivenInsetsPending;
@@ -1165,7 +1212,8 @@
         return displayContent != null ? displayContent.getDisplayInfo() : null;
     }
 
-    int getDisplayId() {
+    @Override
+    public int getDisplayId() {
         final DisplayContent displayContent = getDisplayContent();
         if (displayContent == null) {
             return -1;
@@ -1305,25 +1353,6 @@
     }
 
     /**
-     * Like {@link #isVisibleLw}, but also counts a window that is currently "hidden" behind the
-     * keyguard as visible.  This allows us to apply things like window flags that impact the
-     * keyguard. XXX I am starting to think we need to have ANOTHER visibility flag for this
-     * "hidden behind keyguard" state rather than overloading mPolicyVisibility.  Ungh.
-     */
-    @Override
-    public boolean isVisibleOrBehindKeyguardLw() {
-        if (mToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
-            return false;
-        }
-        final AppWindowToken atoken = mAppToken;
-        final boolean animating = atoken != null && atoken.mAppAnimator.animation != null;
-        return mHasSurface && !mDestroying && !mAnimatingExit
-                && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
-                && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mToken.hidden)
-                        || mWinAnimator.mAnimation != null || animating);
-    }
-
-    /**
      * Is this window visible, ignoring its app token? It is not visible if there is no surface,
      * or we are in the process of running an exit animation that will remove the surface.
      */
@@ -1370,14 +1399,6 @@
      * being visible.
      */
     boolean isOnScreen() {
-        return mPolicyVisibility && isOnScreenIgnoringKeyguard();
-    }
-
-    /**
-     * Like isOnScreen(), but ignores any force hiding of the window due
-     * to the keyguard.
-     */
-    private boolean isOnScreenIgnoringKeyguard() {
         if (!mHasSurface || mDestroying) {
             return false;
         }
@@ -1401,7 +1422,7 @@
     boolean mightAffectAllDrawn(boolean visibleOnly) {
         final boolean isViewVisible = (mAppToken == null || !mAppToken.clientHidden)
                 && (mViewVisibility == View.VISIBLE) && !mWindowRemovalAllowed;
-        return (isOnScreenIgnoringKeyguard() && (!visibleOnly || isViewVisible)
+        return (isOnScreen() && (!visibleOnly || isViewVisible)
                 || mWinAnimator.mAttrType == TYPE_BASE_APPLICATION
                 || mWinAnimator.mAttrType == TYPE_DRAWN_APPLICATION)
                 && !mAnimatingExit && !mDestroying;
@@ -1431,28 +1452,6 @@
     }
 
     /**
-     * Like isReadyForDisplay(), but ignores any force hiding of the window due
-     * to the keyguard.
-     */
-    boolean isReadyForDisplayIgnoringKeyguard() {
-        if (mToken.waitingToShow && mService.mAppTransition.isTransitionSet()) {
-            return false;
-        }
-        final AppWindowToken atoken = mAppToken;
-        if (atoken == null && !mPolicyVisibility) {
-            // If this is not an app window, and the policy has asked to force
-            // hide, then we really do want to hide.
-            return false;
-        }
-        return mHasSurface && !mDestroying
-                && ((!isParentWindowHidden() && mViewVisibility == View.VISIBLE && !mToken.hidden)
-                        || mWinAnimator.mAnimation != null
-                        || ((atoken != null) && (atoken.mAppAnimator.animation != null)
-                                && !mWinAnimator.isDummyAnimation())
-                        || isAnimatingWithSavedSurface());
-    }
-
-    /**
      * Like isOnScreen, but returns false if the surface hasn't yet
      * been drawn.
      */
@@ -1670,7 +1669,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();
         }
 
@@ -1831,6 +1830,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.
@@ -1891,8 +1892,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);
                 }
             }
@@ -1922,8 +1922,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);
@@ -2664,13 +2664,7 @@
             return false;
         }
 
-        Task task = getTask();
-        if (task == null || task.inHomeStack()) {
-            // Don't save surfaces for home stack apps. These usually resume and draw
-            // first frame very fast. Saving surfaces are mostly a waste of memory.
-            return false;
-        }
-
+        final Task task = getTask();
         final AppWindowToken taskTop = task.getTopVisibleAppToken();
         if (taskTop != null && taskTop != mAppToken) {
             // Don't save if the window is not the topmost window.
@@ -3037,8 +3031,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();
             }
 
@@ -3705,6 +3698,7 @@
         return null;
     }
 
+    @Override
     public int getRotationAnimationHint() {
         if (mAppToken != null) {
             return mAppToken.mRotationAnimationHint;
@@ -3713,6 +3707,11 @@
         }
     }
 
+    @Override
+    public boolean isInputMethodWindow() {
+        return mIsImWindow;
+    }
+
     // This must be called while inside a transaction.
     boolean performShowLocked() {
         if (isHiddenFromUserLocked()) {
@@ -3723,7 +3722,7 @@
 
         logPerformShow("performShow on ");
 
-        if (mWinAnimator.mDrawState != READY_TO_SHOW || !isReadyForDisplayIgnoringKeyguard()) {
+        if (mWinAnimator.mDrawState != READY_TO_SHOW || !isReadyForDisplay()) {
             return false;
         }
 
@@ -3773,7 +3772,7 @@
                 || (DEBUG_STARTING_WINDOW && mAttrs.type == TYPE_APPLICATION_STARTING)) {
             Slog.v(TAG, prefix + this
                     + ": mDrawState=" + mWinAnimator.drawStateToString()
-                    + " readyForDisplay=" + isReadyForDisplayIgnoringKeyguard()
+                    + " readyForDisplay=" + isReadyForDisplay()
                     + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING)
                     + " during animation: policyVis=" + mPolicyVisibility
                     + " parentHidden=" + isParentWindowHidden()
@@ -3874,7 +3873,6 @@
             dc.addToWindowList(this, index);
             index++;
         }
-        mService.mWindowsChanged = true;
         return index;
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 2aeb50b..a428cce 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -187,9 +187,6 @@
 
     private boolean mAnimationStartDelayed;
 
-    boolean mKeyguardGoingAwayAnimation;
-    boolean mKeyguardGoingAwayWithWallpaper;
-
     /** The pixel format of the underlying SurfaceControl */
     int mSurfaceFormat;
 
@@ -294,8 +291,6 @@
             mLocalAnimating = false;
             mAnimation.cancel();
             mAnimation = null;
-            mKeyguardGoingAwayAnimation = false;
-            mKeyguardGoingAwayWithWallpaper = false;
             mStackClip = STACK_CLIP_BEFORE_ANIM;
         }
     }
@@ -451,8 +446,6 @@
             + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
 
         mAnimating = false;
-        mKeyguardGoingAwayAnimation = false;
-        mKeyguardGoingAwayWithWallpaper = false;
         mLocalAnimating = false;
         if (mAnimation != null) {
             mAnimation.cancel();
@@ -1268,11 +1261,6 @@
             return;
         }
 
-        final WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw();
-        if (w == winShowWhenLocked && mPolicy.isKeyguardShowingOrOccluded()) {
-            return;
-        }
-
         final TaskStack stack = task.mStack;
         stack.getDimBounds(mTmpStackBounds);
         final Rect surfaceInsets = w.getAttrs().surfaceInsets;
@@ -1688,17 +1676,9 @@
      * @return true if an animation has been loaded.
      */
     boolean applyAnimationLocked(int transit, boolean isEntrance) {
-        if ((mLocalAnimating && mAnimationIsEntrance == isEntrance)
-                || mKeyguardGoingAwayAnimation) {
+        if (mLocalAnimating && mAnimationIsEntrance == isEntrance) {
             // If we are trying to apply an animation, but already running
             // an animation of the same type, then just leave that one alone.
-
-            // If we are in a keyguard exit animation, and the window should animate away, modify
-            // keyguard exit animation such that it also fades out.
-            if (mAnimation != null && mKeyguardGoingAwayAnimation
-                    && transit == WindowManagerPolicy.TRANSIT_PREVIEW_DONE) {
-                applyFadeoutDuringKeyguardExitAnimation();
-            }
             return true;
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 04e00c4..f2682ba 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -11,6 +11,11 @@
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_CLOSE;
 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
+import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
+import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
+import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
+import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_GOING_AWAY;
+import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
 import static com.android.server.wm.AppTransition.TRANSIT_TASK_CLOSE;
 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
@@ -213,175 +218,6 @@
         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);
-    }
-
     /**
      * @return bitmap indicating if another pass through layout must be made.
      */
@@ -516,13 +352,16 @@
         final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
                 topClosingApp.mAppAnimator;
 
-        mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator,
-                mService.mOpeningApps, mService.mClosingApps);
+        final int flags = mService.mAppTransition.getTransitFlags();
+        int layoutRedo = mService.mAppTransition.goodToGo(transit, openingAppAnimator,
+                closingAppAnimator, mService.mOpeningApps, mService.mClosingApps);
+        handleNonAppWindowsInTransition(transit, flags);
         mService.mAppTransition.postAnimationCallback();
         mService.mAppTransition.clear();
 
         mService.mOpeningApps.clear();
         mService.mClosingApps.clear();
+        mService.mUnknownAppVisibilityController.clear();
 
         // This has changed the visibility of windows, so perform
         // a new layout to get them all up-to-date.
@@ -538,11 +377,10 @@
         mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
                 true /*updateInputWindows*/);
         mService.mFocusMayChange = false;
-        mService.notifyActivityDrawnForKeyguard();
 
         Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
 
-        return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
+        return layoutRedo | FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
     }
 
     private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
@@ -641,6 +479,26 @@
         }
     }
 
+    private void handleNonAppWindowsInTransition(int transit, int flags) {
+        if (transit == TRANSIT_KEYGUARD_GOING_AWAY) {
+            if ((flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0
+                    && (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) == 0) {
+                Animation anim = mService.mPolicy.createKeyguardWallpaperExit(
+                        (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0);
+                if (anim != null) {
+                    mService.getDefaultDisplayContentLocked().mWallpaperController
+                            .startWallpaperAnimation(anim);
+                }
+            }
+        }
+        if (transit == TRANSIT_KEYGUARD_GOING_AWAY
+                || transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER) {
+            mService.getDefaultDisplayContentLocked().startKeyguardExitOnNonAppWindows(
+                    transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
+                    (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0);
+        }
+    }
+
     private boolean transitionGoodToGo(int appsCount) {
         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                 "Checking " + appsCount + " opening apps (frozen="
@@ -698,6 +556,14 @@
                 return false;
             }
 
+            if (!mService.mUnknownAppVisibilityController.allResolved()) {
+                if (DEBUG_APP_TRANSITIONS) {
+                    Slog.v(TAG, "unknownApps is not empty: "
+                            + mService.mUnknownAppVisibilityController.getDebugMessage());
+                }
+                return false;
+            }
+
             // If the wallpaper is visible, we need to check it's ready too.
             boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
                     mWallpaperControllerLocked.wallpaperTransitionReady();
@@ -720,6 +586,7 @@
                 ? null : wallpaperTarget;
         final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
         final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
+        boolean openingCanBeWallpaperTarget = canBeWallpaperTarget(openingApps);
         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                 "New wallpaper target=" + wallpaperTarget
                         + ", oldWallpaper=" + oldWallpaper
@@ -744,6 +611,10 @@
             }
             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                     "New transit: " + AppTransition.appTransitionToString(transit));
+        } else if (openingCanBeWallpaperTarget && transit == TRANSIT_KEYGUARD_GOING_AWAY) {
+            transit = TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
+            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+                    "New transit: " + AppTransition.appTransitionToString(transit));
         } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
                 && !openingApps.contains(oldWallpaper.mAppToken)
                 && closingApps.contains(oldWallpaper.mAppToken)) {
@@ -764,6 +635,15 @@
         return transit;
     }
 
+    private boolean canBeWallpaperTarget(ArraySet<AppWindowToken> apps) {
+        for (int i = apps.size() - 1; i >= 0; i--) {
+            if (apps.valueAt(i).windowsCanBeWallpaperTarget()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void processApplicationsAnimatingInPlace(int transit) {
         if (transit == TRANSIT_TASK_IN_PLACE) {
             // Find the focused window
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index afcdc41..b821f09 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -16,19 +16,11 @@
 
 package com.android.server.wm;
 
-import android.os.Bundle;
-import android.os.Debug;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Slog;
-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;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
+
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
@@ -38,6 +30,16 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
+import android.view.DisplayInfo;
+import android.view.animation.Animation;
+
+import java.io.PrintWriter;
+
 /**
  * Container of a set of related windows in the window manager. Often this is an AppWindowToken,
  * which is the handle for an Activity that it uses to display windows. For nested windows, there is
@@ -82,6 +84,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 +190,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 +236,6 @@
         if (!mChildren.contains(win)) {
             addChild(win, null);
         }
-        mService.mWindowsChanged = true;
         mDisplayContent.moveInputMethodDialogs(pos + 1);
     }
 
@@ -305,8 +338,19 @@
         }
     }
 
-    boolean updateWallpaperWindowsPlacement(WindowList windowList, WindowState wallpaperTarget,
-            int wallpaperTargetIndex, boolean visible, int dw, int dh, int wallpaperAnimLayerAdj) {
+    /**
+     * Starts {@param anim} on all children.
+     */
+    void startAnimation(Animation anim) {
+        for (int ndx = mChildren.size() - 1; ndx >= 0; ndx--) {
+            final WindowState windowState = mChildren.get(ndx);
+            windowState.mWinAnimator.setAnimation(anim);
+        }
+    }
+
+    boolean updateWallpaperWindowsPlacement(ReadOnlyWindowList windowList,
+            WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible, int dw, int dh,
+            int wallpaperAnimLayerAdj) {
 
         boolean changed = false;
         if (hidden == visible) {
@@ -346,8 +390,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--;
                 }
@@ -358,10 +401,8 @@
             // is currently on screen, i.e. not hidden by policy.
             int insertionIndex = 0;
             if (visible && wallpaperTarget != null) {
-                final int type = wallpaperTarget.mAttrs.type;
                 final int privateFlags = wallpaperTarget.mAttrs.privateFlags;
-                if (((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 || type == TYPE_KEYGUARD_SCRIM)
-                        && !mService.isKeyguardAnimatingIn()) {
+                if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                     insertionIndex = Math.min(windowList.indexOf(wallpaperTarget),
                             findLowestWindowOnScreen(windowList));
                 }
@@ -370,8 +411,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 +422,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);
@@ -429,7 +469,6 @@
     void removeImmediately() {
         if (mDisplayContent != null) {
             mDisplayContent.removeWindowToken(token);
-            mService.mRoot.removeWindowTokenIfPossible(token);
         }
         // Needs to occur after the token is removed from the display above to avoid attempt at
         // duplicate removal of this window container from it's parent.
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index 121067a..2c46413 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -71,3 +71,5 @@
     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/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index eb85e89..0ea8d4e 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.NetworkEvent;
 import android.app.admin.PasswordMetrics;
 import android.app.admin.SecurityLog;
 import android.app.admin.SecurityLog.SecurityEvent;
@@ -78,8 +79,10 @@
 import android.media.AudioManager;
 import android.media.IAudioService;
 import android.net.ConnectivityManager;
+import android.net.IIpConnectivityMetrics;
 import android.net.ProxyInfo;
 import android.net.Uri;
+import android.net.metrics.IpConnectivityLog;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.AsyncTask;
@@ -179,7 +182,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
 
@@ -361,6 +364,7 @@
     boolean mIsWatch;
 
     private final SecurityLogMonitor mSecurityLogMonitor;
+    private NetworkLogger mNetworkLogger;
 
     private final AtomicBoolean mRemoteBugreportServiceIsActive = new AtomicBoolean();
     private final AtomicBoolean mRemoteBugreportSharingAccepted = new AtomicBoolean();
@@ -480,6 +484,16 @@
             final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
                     getSendingUserId());
 
+            /*
+             * Network logging would ideally be started in setDeviceOwnerSystemPropertyLocked(),
+             * however it's too early in the boot process to register with IIpConnectivityMetrics
+             * to listen for events.
+             */
+            if (Intent.ACTION_USER_STARTED.equals(action)
+                    && userHandle == mOwners.getDeviceOwnerUserId()
+                    && isNetworkLoggingEnabledInternal()) {
+                setNetworkLoggingActiveInternal(true);
+            }
             if (Intent.ACTION_BOOT_COMPLETED.equals(action)
                     && userHandle == mOwners.getDeviceOwnerUserId()
                     && getDeviceOwnerRemoteBugreportUri() != null) {
@@ -551,6 +565,7 @@
         private static final String TAG_DISABLE_ACCOUNT_MANAGEMENT = "disable-account-management";
         private static final String TAG_REQUIRE_AUTO_TIME = "require_auto_time";
         private static final String TAG_FORCE_EPHEMERAL_USERS = "force_ephemeral_users";
+        private static final String TAG_IS_NETWORK_LOGGING_ENABLED = "is_network_logging_enabled";
         private static final String TAG_ACCOUNT_TYPE = "account-type";
         private static final String TAG_PERMITTED_ACCESSIBILITY_SERVICES
                 = "permitted-accessiblity-services";
@@ -637,6 +652,7 @@
         boolean disableScreenCapture = false; // Can only be set by a device/profile owner.
         boolean requireAutoTime = false; // Can only be set by a device owner.
         boolean forceEphemeralUsers = false; // Can only be set by a device owner.
+        boolean isNetworkLoggingEnabled = false; // Can only be set by a device owner.
 
         ActiveAdmin parentAdmin;
         final boolean isParent;
@@ -853,6 +869,11 @@
                 out.attribute(null, ATTR_VALUE, Boolean.toString(forceEphemeralUsers));
                 out.endTag(null, TAG_FORCE_EPHEMERAL_USERS);
             }
+            if (isNetworkLoggingEnabled) {
+                out.startTag(null, TAG_IS_NETWORK_LOGGING_ENABLED);
+                out.attribute(null, ATTR_VALUE, Boolean.toString(isNetworkLoggingEnabled));
+                out.endTag(null, TAG_IS_NETWORK_LOGGING_ENABLED);
+            }
             if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) {
                 out.startTag(null, TAG_DISABLE_KEYGUARD_FEATURES);
                 out.attribute(null, ATTR_VALUE, Integer.toString(disabledKeyguardFeatures));
@@ -1039,6 +1060,9 @@
                 } else if (TAG_FORCE_EPHEMERAL_USERS.equals(tag)) {
                     forceEphemeralUsers = Boolean.parseBoolean(
                             parser.getAttributeValue(null, ATTR_VALUE));
+                } else if (TAG_IS_NETWORK_LOGGING_ENABLED.equals(tag)) {
+                    isNetworkLoggingEnabled = Boolean.parseBoolean(
+                            parser.getAttributeValue(null, ATTR_VALUE));
                 } else if (TAG_DISABLE_KEYGUARD_FEATURES.equals(tag)) {
                     disabledKeyguardFeatures = Integer.parseInt(
                             parser.getAttributeValue(null, ATTR_VALUE));
@@ -1279,6 +1303,8 @@
                     pw.println(requireAutoTime);
             pw.print(prefix); pw.print("forceEphemeralUsers=");
                     pw.println(forceEphemeralUsers);
+            pw.print(prefix); pw.print("isNetworkLoggingEnabled=");
+                    pw.println(isNetworkLoggingEnabled);
             pw.print(prefix); pw.print("disabledKeyguardFeatures=");
                     pw.println(disabledKeyguardFeatures);
             pw.print(prefix); pw.print("crossProfileWidgetProviders=");
@@ -1405,6 +1431,11 @@
             return mContext.getSystemService(NotificationManager.class);
         }
 
+        IIpConnectivityMetrics getIIpConnectivityMetrics() {
+            return (IIpConnectivityMetrics) IIpConnectivityMetrics.Stub.asInterface(
+                ServiceManager.getService(IpConnectivityLog.SERVICE_NAME));
+        }
+
         PowerManagerInternal getPowerManagerInternal() {
             return LocalServices.getService(PowerManagerInternal.class);
         }
@@ -6131,6 +6162,9 @@
         return hasUserSetupCompleted(UserHandle.getCallingUserId());
     }
 
+    // This checks only if the Setup Wizard has run.  Since Wear devices pair before
+    // completing Setup Wizard, and pairing involves transferring user data, calling
+    // logic may want to check mIsWatch or mPaired in addition to hasUserSetupCompleted().
     private boolean hasUserSetupCompleted(int userHandle) {
         if (!mHasFeature) {
             return true;
@@ -6379,7 +6413,7 @@
                     + "already has a device owner.");
         }
         if (isAdb()) {
-            if (hasUserSetupCompleted(userHandle)
+            if ((mIsWatch || hasUserSetupCompleted(userHandle))
                     && hasIncompatibleAccountsLocked(userHandle, owner)) {
                 throw new IllegalStateException("Not allowed to set the profile owner because "
                         + "there are already some accounts on the profile");
@@ -6387,7 +6421,7 @@
             return;
         }
         enforceCanManageProfileAndDeviceOwners();
-        if (hasUserSetupCompleted(userHandle) && !isCallerWithSystemUid()) {
+        if ((mIsWatch || hasUserSetupCompleted(userHandle)) && !isCallerWithSystemUid()) {
             throw new IllegalStateException("Cannot set the profile owner on a user which is "
                     + "already set-up");
         }
@@ -7340,15 +7374,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);
         }
     }
 
@@ -8668,6 +8712,9 @@
             if (hasUserSetupCompleted(callingUserId)) {
                 return false;
             }
+            if (mIsWatch && hasPaired(UserHandle.USER_SYSTEM)) {
+                return false;
+            }
             return true;
         } else if (DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE.equals(action)) {
             if (!mInjector.userManagerIsSplitSystemUser()) {
@@ -8699,7 +8746,7 @@
         }
         if (isAdb) {
             // if shell command runs after user setup completed check device status. Otherwise, OK.
-            if (hasUserSetupCompleted(UserHandle.USER_SYSTEM)) {
+            if (mIsWatch || hasUserSetupCompleted(UserHandle.USER_SYSTEM)) {
                 if (!mInjector.userManagerIsSplitSystemUser()) {
                     if (mUserManager.getUserCount() > 1) {
                         return CODE_NONSYSTEM_USER_EXISTS;
@@ -9066,13 +9113,19 @@
     }
 
     private synchronized void disableDeviceOwnerManagedSingleUserFeaturesIfNeeded() {
+        if (!mOwners.hasDeviceOwner()) {
+            return;
+        }
         if (!isDeviceOwnerManagedSingleUserDevice()) {
             mInjector.securityLogSetLoggingEnabledProperty(false);
-            Slog.w(LOG_TAG, "Security logging turned off as it's no longer a single user device.");
-            if (mOwners.hasDeviceOwner()) {
-                setBackupServiceEnabledInternal(false);
-                Slog.w(LOG_TAG, "Backup is off as it's a managed device that has more that one user.");
-            }
+
+            getDeviceOwnerAdminLocked().isNetworkLoggingEnabled = false;
+            saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+            setNetworkLoggingActiveInternal(false);
+
+            setBackupServiceEnabledInternal(false);
+            Slog.w(LOG_TAG, "Security logging, network logging and backup service turned off as"
+                    + " it's not a single user device.");
         }
     }
 
@@ -9453,4 +9506,81 @@
         final int callingUid = mInjector.binderGetCallingUid();
         return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID;
     }
+
+    @Override
+    public synchronized void setNetworkLoggingEnabled(ComponentName admin, boolean enabled) {
+        if (!mHasFeature) {
+            return;
+        }
+        Preconditions.checkNotNull(admin);
+        ensureDeviceOwnerManagingSingleUser(admin);
+
+        if (enabled == isNetworkLoggingEnabledInternal()) {
+            // already in the requested state
+            return;
+        }
+        getDeviceOwnerAdminLocked().isNetworkLoggingEnabled = enabled;
+        saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+
+        setNetworkLoggingActiveInternal(enabled);
+    }
+
+    private synchronized void setNetworkLoggingActiveInternal(boolean active) {
+        final long callingIdentity = mInjector.binderClearCallingIdentity();
+        try {
+            if (active) {
+                mNetworkLogger = new NetworkLogger(this, mInjector.getPackageManagerInternal());
+                if (!mNetworkLogger.startNetworkLogging()) {
+                    mNetworkLogger = null;
+                    Slog.wtf(LOG_TAG, "Network logging could not be started due to the logging"
+                            + " service not being available yet.");
+                }
+            } else {
+                if (mNetworkLogger != null && !mNetworkLogger.stopNetworkLogging()) {
+                    mNetworkLogger = null;
+                    Slog.wtf(LOG_TAG, "Network logging could not be stopped due to the logging"
+                            + " service not being available yet.");
+                }
+                mNetworkLogger = null;
+            }
+        } finally {
+            mInjector.binderRestoreCallingIdentity(callingIdentity);
+        }
+    }
+
+    @Override
+    public boolean isNetworkLoggingEnabled(ComponentName admin) {
+        if (!mHasFeature) {
+            return false;
+        }
+        Preconditions.checkNotNull(admin);
+        synchronized (this) {
+            getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+            return isNetworkLoggingEnabledInternal();
+        }
+    }
+
+    private synchronized boolean isNetworkLoggingEnabledInternal() {
+        ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
+        return (deviceOwner != null) && deviceOwner.isNetworkLoggingEnabled;
+    }
+
+    /*
+     * A maximum of 1200 events are returned, and the total marshalled size is in the order of
+     * 100kB, so returning a List instead of ParceledListSlice is acceptable.
+     * Ideally this would be done with ParceledList, however it only supports homogeneous types.
+     */
+    @Override
+    public synchronized List<NetworkEvent> retrieveNetworkLogs(ComponentName admin) {
+        if (!mHasFeature) {
+            return null;
+        }
+        Preconditions.checkNotNull(admin);
+        ensureDeviceOwnerManagingSingleUser(admin);
+
+        if (mNetworkLogger == null) {
+            return null;
+        }
+        return isNetworkLoggingEnabledInternal() ? mNetworkLogger.retrieveLogs() : null;
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java
new file mode 100644
index 0000000..185ccc2
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLogger.java
@@ -0,0 +1,153 @@
+/*
+ * 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.devicepolicy;
+
+import android.app.admin.ConnectEvent;
+import android.app.admin.DnsEvent;
+import android.app.admin.NetworkEvent;
+import android.content.pm.PackageManagerInternal;
+import android.net.IIpConnectivityMetrics;
+import android.net.INetdEventCallback;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.server.ServiceThread;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A class for managing network logging.
+ * This class is not thread-safe, callers should synchronize access.
+ */
+final class NetworkLogger {
+
+    private static final String TAG = NetworkLogger.class.getSimpleName();
+
+    private final DevicePolicyManagerService mDpm;
+    private final PackageManagerInternal mPm;
+
+    private IIpConnectivityMetrics mIpConnectivityMetrics;
+    private ServiceThread mHandlerThread;
+    private NetworkLoggingHandler mNetworkLoggingHandler;
+    private boolean mIsLoggingEnabled;
+
+    private final INetdEventCallback mNetdEventCallback = new INetdEventCallback.Stub() {
+        @Override
+        public void onDnsEvent(String hostname, String[] ipAddresses, int ipAddressesCount,
+                long timestamp, int uid) {
+            if (!mIsLoggingEnabled) {
+                return;
+            }
+            DnsEvent dnsEvent = new DnsEvent(hostname, ipAddresses, ipAddressesCount,
+                    mPm.getNameForUid(uid), timestamp);
+            sendNetworkEvent(dnsEvent);
+        }
+
+        @Override
+        public void onConnectEvent(String ipAddr, int port, long timestamp, int uid) {
+            if (!mIsLoggingEnabled) {
+                return;
+            }
+            ConnectEvent connectEvent = new ConnectEvent(ipAddr, port, mPm.getNameForUid(uid),
+                    timestamp);
+            sendNetworkEvent(connectEvent);
+        }
+
+        private void sendNetworkEvent(NetworkEvent event) {
+            Message msg = mNetworkLoggingHandler.obtainMessage(
+                    NetworkLoggingHandler.LOG_NETWORK_EVENT_MSG);
+            Bundle bundle = new Bundle();
+            bundle.putParcelable(NetworkLoggingHandler.NETWORK_EVENT_KEY, event);
+            msg.setData(bundle);
+            mNetworkLoggingHandler.sendMessage(msg);
+        }
+    };
+
+    NetworkLogger(DevicePolicyManagerService dpm, PackageManagerInternal pm) {
+        mDpm = dpm;
+        mPm = pm;
+    }
+
+    private boolean checkIpConnectivityMetricsService() {
+        if (mIpConnectivityMetrics != null) {
+            return true;
+        }
+        final IIpConnectivityMetrics service = mDpm.mInjector.getIIpConnectivityMetrics();
+        if (service == null) {
+            return false;
+        }
+        mIpConnectivityMetrics = service;
+        return true;
+    }
+
+    boolean startNetworkLogging() {
+        Log.d(TAG, "Starting network logging.");
+        if (!checkIpConnectivityMetricsService()) {
+            // the IIpConnectivityMetrics service should have been present at this point
+            Slog.wtf(TAG, "Failed to register callback with IIpConnectivityMetrics.");
+            return false;
+        }
+        try {
+           if (mIpConnectivityMetrics.registerNetdEventCallback(mNetdEventCallback)) {
+                mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND,
+                        /* allowIo */ false);
+                mHandlerThread.start();
+                mNetworkLoggingHandler = new NetworkLoggingHandler(mHandlerThread.getLooper(),
+                        mDpm);
+                mNetworkLoggingHandler.scheduleBatchFinalization(
+                        NetworkLoggingHandler.BATCH_FINALIZATION_TIMEOUT_MS);
+                mIsLoggingEnabled = true;
+                return true;
+            } else {
+                return false;
+            }
+        } catch (RemoteException re) {
+            Slog.wtf(TAG, "Failed to make remote calls to register the callback", re);
+            return false;
+        }
+    }
+
+    boolean stopNetworkLogging() {
+        Log.d(TAG, "Stopping network logging");
+        // stop the logging regardless of whether we fail to unregister listener
+        mIsLoggingEnabled = false;
+        try {
+            if (!checkIpConnectivityMetricsService()) {
+                // the IIpConnectivityMetrics service should have been present at this point
+                Slog.wtf(TAG, "Failed to unregister callback with IIpConnectivityMetrics.");
+                // logging is forcefully disabled even if unregistering fails
+                return true;
+            }
+            return mIpConnectivityMetrics.unregisterNetdEventCallback();
+        } catch (RemoteException re) {
+            Slog.wtf(TAG, "Failed to make remote calls to unregister the callback", re);
+        } finally {
+            mHandlerThread.quitSafely();
+            return true;
+        }
+    }
+
+    List<NetworkEvent> retrieveLogs() {
+        return mNetworkLoggingHandler.retrieveFullLogBatch();
+    }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
new file mode 100644
index 0000000..96884e6
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
@@ -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.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.app.admin.ConnectEvent;
+import android.app.admin.DnsEvent;
+import android.app.admin.NetworkEvent;
+import android.net.IIpConnectivityMetrics;
+import android.net.INetdEventCallback;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A Handler class for managing network logging on a background thread.
+ */
+final class NetworkLoggingHandler extends Handler {
+
+    private static final String TAG = NetworkLoggingHandler.class.getSimpleName();
+
+    static final String NETWORK_EVENT_KEY = "network_event";
+
+    // est. ~128kB of memory usage per full batch TODO(mkarpinski): fine tune based on testing data
+    // If this value changes, update DevicePolicyManager#retrieveNetworkLogs() javadoc
+    private static final int MAX_EVENTS_PER_BATCH = 1200;
+    static final long BATCH_FINALIZATION_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(90);
+
+    static final int LOG_NETWORK_EVENT_MSG = 1;
+    static final int FINALIZE_BATCH_MSG = 2;
+
+    private final DevicePolicyManagerService mDpm;
+
+    // threadsafe as it's Handler's thread confined
+    private ArrayList<NetworkEvent> mNetworkEvents = new ArrayList<NetworkEvent>();
+
+    @GuardedBy("this")
+    private ArrayList<NetworkEvent> mFullBatch;
+
+    NetworkLoggingHandler(Looper looper, DevicePolicyManagerService dpm) {
+        super(looper);
+        mDpm = dpm;
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        switch (msg.what) {
+            case LOG_NETWORK_EVENT_MSG: {
+                NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY);
+                if (networkEvent != null) {
+                    mNetworkEvents.add(networkEvent);
+                    if (mNetworkEvents.size() >= MAX_EVENTS_PER_BATCH) {
+                        finalizeBatchAndNotifyDeviceOwner();
+                    }
+                }
+                break;
+            }
+            case FINALIZE_BATCH_MSG: {
+                finalizeBatchAndNotifyDeviceOwner();
+                break;
+            }
+        }
+    }
+
+    void scheduleBatchFinalization(long delay) {
+        removeMessages(FINALIZE_BATCH_MSG);
+        sendMessageDelayed(obtainMessage(FINALIZE_BATCH_MSG), delay);
+    }
+
+    private synchronized void finalizeBatchAndNotifyDeviceOwner() {
+        mFullBatch = mNetworkEvents;
+        // start a new batch from scratch
+        mNetworkEvents = new ArrayList<NetworkEvent>();
+        scheduleBatchFinalization(BATCH_FINALIZATION_TIMEOUT_MS);
+        // notify DO that there's a new non-empty batch waiting
+        if (mFullBatch.size() > 0) {
+            mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE,
+                    /* extras */ null);
+        } else {
+            mFullBatch = null;
+        }
+    }
+
+    synchronized List<NetworkEvent> retrieveFullLogBatch() {
+        List<NetworkEvent> ret = mFullBatch;
+        mFullBatch = null;
+        return ret;
+    }
+}
+
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 85b0d96..cc96f56 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";
 
@@ -154,8 +156,8 @@
             "com.android.server.midi.MidiService$Lifecycle";
     private static final String WIFI_SERVICE_CLASS =
             "com.android.server.wifi.WifiService";
-    private static final String WIFI_NAN_SERVICE_CLASS =
-            "com.android.server.wifi.nan.WifiNanService";
+    private static final String WIFI_AWARE_SERVICE_CLASS =
+            "com.android.server.wifi.aware.WifiAwareService";
     private static final String WIFI_P2P_SERVICE_CLASS =
             "com.android.server.wifi.p2p.WifiP2pService";
     private static final String ETHERNET_SERVICE_CLASS =
@@ -908,12 +910,13 @@
                 }
                 traceEnd();
 
-                if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_NAN)) {
-                    traceBeginAndSlog("StartWifiNan");
-                    mSystemServiceManager.startService(WIFI_NAN_SERVICE_CLASS);
+                if (context.getPackageManager().hasSystemFeature(
+                        PackageManager.FEATURE_WIFI_AWARE)) {
+                    traceBeginAndSlog("StartWifiAware");
+                    mSystemServiceManager.startService(WIFI_AWARE_SERVICE_CLASS);
                     traceEnd();
                 } else {
-                    Slog.i(TAG, "No Wi-Fi NAN Service (NAN support Not Present)");
+                    Slog.i(TAG, "No Wi-Fi Aware Service (Aware support Not Present)");
                 }
 
                 if (context.getPackageManager().hasSystemFeature(
@@ -1403,7 +1406,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/tests/notification/Android.mk b/services/tests/notification/Android.mk
new file mode 100644
index 0000000..8aded60
--- /dev/null
+++ b/services/tests/notification/Android.mk
@@ -0,0 +1,56 @@
+#########################################################################
+# Build FrameworksNotificationTests package
+#########################################################################
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+# Include test java files and source from notifications package.
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+	$(call all-java-files-under, ../../core/java/com/android/server/notification)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    frameworks-base-testutils \
+    services.accessibility \
+    services.core \
+    services.devicepolicy \
+    services.net \
+    services.retaildemo \
+    services.usage \
+    guava \
+    android-support-test \
+    mockito-target-minus-junit4 \
+    platform-test-annotations
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := FrameworksNotificationTests
+
+LOCAL_CERTIFICATE := platform
+
+# These are not normally accessible from apps so they must be explicitly included.
+LOCAL_JNI_SHARED_LIBRARIES := libservicestestsjni \
+    libbacktrace \
+    libbase \
+    libbinder \
+    libc++ \
+    libcutils \
+    liblog \
+    liblzma \
+    libnativehelper \
+    libnetdaidl \
+    libui \
+    libunwind \
+    libutils
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+# Code coverage puts us over the dex limit, so enable multi-dex for coverage-enabled builds
+ifeq (true,$(EMMA_INSTRUMENT))
+LOCAL_JACK_FLAGS := --multi-dex native
+endif # EMMA_INSTRUMENT_STATIC
+
+include $(BUILD_PACKAGE)
diff --git a/services/tests/notification/AndroidManifest.xml b/services/tests/notification/AndroidManifest.xml
new file mode 100644
index 0000000..087806e
--- /dev/null
+++ b/services/tests/notification/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?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.notification">
+
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+    <uses-permission android:name="android.permission.MANAGE_USERS" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.frameworks.tests.notification"
+        android:label="Notification Tests" />
+</manifest>
diff --git a/services/tests/servicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
similarity index 98%
rename from services/tests/servicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
rename to services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 5fe000a..4570a4b 100644
--- a/services/tests/servicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -229,7 +229,8 @@
         StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid, mPid,
                 mScore, n, mUser, System.currentTimeMillis());
         NotificationRecord r = new NotificationRecord(getContext(), sbn,
-                new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "misc"));
+                new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "misc",
+                        NotificationManager.IMPORTANCE_DEFAULT));
         mService.addNotification(r);
         return r;
     }
@@ -334,7 +335,7 @@
     @Test
     public void testBeepFromChannel() throws Exception {
         NotificationRecord r = getQuietNotification();
-        r.getChannel().setDefaultRingtone(Settings.System.DEFAULT_NOTIFICATION_URI);
+        r.getChannel().setRingtone(Settings.System.DEFAULT_NOTIFICATION_URI);
         r.setImportance(NotificationManager.IMPORTANCE_DEFAULT, "for testing");
 
         mService.buzzBeepBlinkLocked(r);
@@ -388,7 +389,7 @@
     @Test
     public void testChannelNoOverwriteCustomBeep() throws Exception {
         NotificationRecord r = getCustomBeepyNotification();
-        r.getChannel().setDefaultRingtone(Settings.System.DEFAULT_RINGTONE_URI);
+        r.getChannel().setRingtone(Settings.System.DEFAULT_RINGTONE_URI);
 
         mService.buzzBeepBlinkLocked(r);
 
@@ -408,7 +409,7 @@
     @Test
     public void testNoInterruptionForMin() throws Exception {
         NotificationRecord r = getBeepyNotification();
-        r.setImportance(Ranking.IMPORTANCE_MIN, "foo");
+        r.setImportance(NotificationManager.IMPORTANCE_MIN, "foo");
 
         mService.buzzBeepBlinkLocked(r);
 
diff --git a/services/tests/servicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/notification/src/com/android/server/notification/GroupHelperTest.java
similarity index 100%
rename from services/tests/servicestests/src/com/android/server/notification/GroupHelperTest.java
rename to services/tests/notification/src/com/android/server/notification/GroupHelperTest.java
diff --git a/services/tests/servicestests/src/com/android/server/notification/ImportanceExtractorTest.java b/services/tests/notification/src/com/android/server/notification/ImportanceExtractorTest.java
similarity index 87%
rename from services/tests/servicestests/src/com/android/server/notification/ImportanceExtractorTest.java
rename to services/tests/notification/src/com/android/server/notification/ImportanceExtractorTest.java
index 3cbde1d..305b5e0 100644
--- a/services/tests/servicestests/src/com/android/server/notification/ImportanceExtractorTest.java
+++ b/services/tests/notification/src/com/android/server/notification/ImportanceExtractorTest.java
@@ -90,8 +90,8 @@
 
         when(mConfig.getImportance(anyString(), anyInt())).thenReturn(
           NotificationManager.IMPORTANCE_MIN);
-        NotificationChannel channel = new NotificationChannel("a", "a");
-        channel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
+        NotificationChannel channel =
+                new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_UNSPECIFIED);
 
         NotificationRecord r = getNotificationRecord(channel);
 
@@ -107,8 +107,8 @@
 
         when(mConfig.getImportance(anyString(), anyInt())).thenReturn(
           NotificationManager.IMPORTANCE_MIN);
-        NotificationChannel channel = new NotificationChannel("a", "a");
-        channel.setImportance(NotificationManager.IMPORTANCE_HIGH);
+        NotificationChannel channel =
+                new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_HIGH);
 
         NotificationRecord r = getNotificationRecord(channel);
 
@@ -124,8 +124,8 @@
 
         when(mConfig.getImportance(anyString(), anyInt())).thenReturn(
           NotificationManager.IMPORTANCE_HIGH);
-        NotificationChannel channel = new NotificationChannel("a", "a");
-        channel.setImportance(NotificationManager.IMPORTANCE_MIN);
+        NotificationChannel channel =
+                new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_MIN);
 
         NotificationRecord r = getNotificationRecord(channel);
 
@@ -141,8 +141,8 @@
 
         when(mConfig.getImportance(anyString(), anyInt())).thenReturn(
           NotificationManager.IMPORTANCE_UNSPECIFIED);
-        NotificationChannel channel = new NotificationChannel("a", "a");
-        channel.setImportance(NotificationManager.IMPORTANCE_MIN);
+        NotificationChannel channel =
+                new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_MIN);
 
         NotificationRecord r = getNotificationRecord(channel);
 
@@ -158,8 +158,8 @@
 
         when(mConfig.getImportance(anyString(), anyInt())).thenReturn(
           NotificationManager.IMPORTANCE_UNSPECIFIED);
-        NotificationChannel channel = new NotificationChannel("a", "a");
-        channel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
+        NotificationChannel channel =
+                new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_UNSPECIFIED);
 
         NotificationRecord r = getNotificationRecord(channel);
 
diff --git a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
new file mode 100644
index 0000000..629146f
--- /dev/null
+++ b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
@@ -0,0 +1,492 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.notification;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.android.internal.util.FastXmlSerializer;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
+
+import android.app.Notification;
+import android.content.Context;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Build;
+import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Xml;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.when;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RankingHelperTest {
+    @Mock NotificationUsageStats mUsageStats;
+    @Mock RankingHandler handler;
+    @Mock PackageManager mPm;
+
+    private Notification mNotiGroupGSortA;
+    private Notification mNotiGroupGSortB;
+    private Notification mNotiNoGroup;
+    private Notification mNotiNoGroup2;
+    private Notification mNotiNoGroupSortA;
+    private NotificationRecord mRecordGroupGSortA;
+    private NotificationRecord mRecordGroupGSortB;
+    private NotificationRecord mRecordNoGroup;
+    private NotificationRecord mRecordNoGroup2;
+    private NotificationRecord mRecordNoGroupSortA;
+    private RankingHelper mHelper;
+    private final String pkg = "com.android.server.notification";
+    private final int uid = 0;
+    private final String pkg2 = "pkg2";
+    private final int uid2 = 1111111;
+
+    private Context getContext() {
+        return InstrumentationRegistry.getTargetContext();
+    }
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        UserHandle user = UserHandle.ALL;
+
+        mHelper = new RankingHelper(getContext(), mPm, handler, mUsageStats,
+                new String[] {ImportanceExtractor.class.getName()});
+
+        mNotiGroupGSortA = new Notification.Builder(getContext())
+                .setContentTitle("A")
+                .setGroup("G")
+                .setSortKey("A")
+                .setWhen(1205)
+                .build();
+        mRecordGroupGSortA = new NotificationRecord(getContext(), new StatusBarNotification(
+                "package", "package", 1, null, 0, 0, 0, mNotiGroupGSortA, user), 
+                getDefaultChannel());
+
+        mNotiGroupGSortB = new Notification.Builder(getContext())
+                .setContentTitle("B")
+                .setGroup("G")
+                .setSortKey("B")
+                .setWhen(1200)
+                .build();
+        mRecordGroupGSortB = new NotificationRecord(getContext(), new StatusBarNotification(
+                "package", "package", 1, null, 0, 0, 0, mNotiGroupGSortB, user), 
+                getDefaultChannel());
+
+        mNotiNoGroup = new Notification.Builder(getContext())
+                .setContentTitle("C")
+                .setWhen(1201)
+                .build();
+        mRecordNoGroup = new NotificationRecord(getContext(), new StatusBarNotification(
+                "package", "package", 1, null, 0, 0, 0, mNotiNoGroup, user), 
+                getDefaultChannel());
+
+        mNotiNoGroup2 = new Notification.Builder(getContext())
+                .setContentTitle("D")
+                .setWhen(1202)
+                .build();
+        mRecordNoGroup2 = new NotificationRecord(getContext(), new StatusBarNotification(
+                "package", "package", 1, null, 0, 0, 0, mNotiNoGroup2, user), 
+                getDefaultChannel());
+
+        mNotiNoGroupSortA = new Notification.Builder(getContext())
+                .setContentTitle("E")
+                .setWhen(1201)
+                .setSortKey("A")
+                .build();
+        mRecordNoGroupSortA = new NotificationRecord(getContext(), new StatusBarNotification(
+                "package", "package", 1, null, 0, 0, 0, mNotiNoGroupSortA, user), 
+                getDefaultChannel());
+
+        final ApplicationInfo legacy = new ApplicationInfo();
+        legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
+        final ApplicationInfo upgrade = new ApplicationInfo();
+        upgrade.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
+        try {
+            when(mPm.getApplicationInfoAsUser(eq(pkg), anyInt(), anyInt())).thenReturn(legacy);
+            when(mPm.getApplicationInfoAsUser(eq(pkg2), anyInt(), anyInt())).thenReturn(upgrade);
+        } catch (PackageManager.NameNotFoundException e) {}
+    }
+
+    private NotificationChannel getDefaultChannel() {
+        return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
+                NotificationManager.IMPORTANCE_LOW);
+    }
+
+    private ByteArrayOutputStream writeXmlAndPurge(String pkg, int uid, String... channelIds)
+            throws Exception {
+        XmlSerializer serializer = new FastXmlSerializer();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
+        serializer.startDocument(null, true);
+        serializer.startTag(null, "ranking");
+        mHelper.writeXml(serializer, false);
+        serializer.endTag(null, "ranking");
+        serializer.endDocument();
+        serializer.flush();
+
+        for (String channelId : channelIds) {
+            mHelper.deleteNotificationChannel(pkg, uid, channelId);
+        }
+        return baos;
+    }
+
+    @Test
+    public void testFindAfterRankingWithASplitGroup() throws Exception {
+        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(3);
+        notificationList.add(mRecordGroupGSortA);
+        notificationList.add(mRecordGroupGSortB);
+        notificationList.add(mRecordNoGroup);
+        notificationList.add(mRecordNoGroupSortA);
+        mHelper.sort(notificationList);
+        assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortA) >= 0);
+        assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortB) >= 0);
+        assertTrue(mHelper.indexOf(notificationList, mRecordNoGroup) >= 0);
+        assertTrue(mHelper.indexOf(notificationList, mRecordNoGroupSortA) >= 0);
+    }
+
+    @Test
+    public void testSortShouldNotThrowWithPlainNotifications() throws Exception {
+        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
+        notificationList.add(mRecordNoGroup);
+        notificationList.add(mRecordNoGroup2);
+        mHelper.sort(notificationList);
+    }
+
+    @Test
+    public void testSortShouldNotThrowOneSorted() throws Exception {
+        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
+        notificationList.add(mRecordNoGroup);
+        notificationList.add(mRecordNoGroupSortA);
+        mHelper.sort(notificationList);
+    }
+
+    @Test
+    public void testSortShouldNotThrowOneNotification() throws Exception {
+        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
+        notificationList.add(mRecordNoGroup);
+        mHelper.sort(notificationList);
+    }
+
+    @Test
+    public void testSortShouldNotThrowOneSortKey() throws Exception {
+        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
+        notificationList.add(mRecordGroupGSortB);
+        mHelper.sort(notificationList);
+    }
+
+    @Test
+    public void testSortShouldNotThrowOnEmptyList() throws Exception {
+        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>();
+        mHelper.sort(notificationList);
+    }
+
+    @Test
+    public void testChannelXml() throws Exception {
+        NotificationChannel channel1 =
+                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
+        NotificationChannel channel2 =
+                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+        channel2.setRingtone(new Uri.Builder().scheme("test").build());
+        channel2.setLights(true);
+        channel2.setBypassDnd(true);
+        channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+
+        mHelper.createNotificationChannel(pkg, uid, channel1);
+        mHelper.createNotificationChannel(pkg, uid, channel2);
+
+        ByteArrayOutputStream baos = writeXmlAndPurge(pkg, uid, channel1.getId(), channel2.getId(),
+                NotificationChannel.DEFAULT_CHANNEL_ID);
+
+        mHelper.deleteNotificationChannel(pkg, uid, channel1.getId());
+        mHelper.deleteNotificationChannel(pkg, uid, channel2.getId());
+        mHelper.deleteNotificationChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID);
+
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
+                null);
+        parser.nextTag();
+        mHelper.readXml(parser, false);
+
+        assertEquals(channel1, mHelper.getNotificationChannel(pkg, uid, channel1.getId()));
+        assertEquals(channel2, mHelper.getNotificationChannel(pkg, uid, channel2.getId()));
+        assertNotNull(
+                mHelper.getNotificationChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID));
+    }
+
+    @Test
+    public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception {
+        NotificationChannel channel1 =
+                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_DEFAULT);
+
+        mHelper.createNotificationChannel(pkg, uid, channel1);
+
+        ByteArrayOutputStream baos = writeXmlAndPurge(pkg, uid, channel1.getId(),
+                NotificationChannel.DEFAULT_CHANNEL_ID);
+
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
+                null);
+        parser.nextTag();
+        mHelper.readXml(parser, false);
+
+        final NotificationChannel updated =
+                mHelper.getNotificationChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID);
+        assertEquals(NotificationManager.IMPORTANCE_UNSPECIFIED, updated.getImportance());
+        assertFalse(updated.canBypassDnd());
+        assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,updated.getLockscreenVisibility());
+        assertEquals(0, updated.getUserLockedFields());
+    }
+
+    @Test
+    public void testChannelXml_defaultChannelUpdatedApp_userSettings() throws Exception {
+         NotificationChannel channel1 =
+                new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_MIN);
+        mHelper.createNotificationChannel(pkg, uid, channel1);
+
+        final NotificationChannel defaultChannel =
+                mHelper.getNotificationChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID);
+        defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+        mHelper.updateNotificationChannel(pkg, uid, defaultChannel);
+
+        ByteArrayOutputStream baos = writeXmlAndPurge(pkg, uid, channel1.getId(),
+                NotificationChannel.DEFAULT_CHANNEL_ID);
+
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())),
+                null);
+        parser.nextTag();
+        mHelper.readXml(parser, false);
+
+        assertEquals(NotificationManager.IMPORTANCE_LOW, mHelper.getNotificationChannel(
+                pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID).getImportance());
+    }
+
+    @Test
+    public void testChannelXml_upgradeCreateDefaultChannel() throws Exception {
+        final String preupgradeXml = "<ranking version=\"1\">\n"
+             + "<package name=\"" + pkg + "\" importance=\"" + NotificationManager.IMPORTANCE_HIGH
+            + "\" priority=\"" + Notification.PRIORITY_MAX + "\" visibility=\""
+            + Notification.VISIBILITY_SECRET + "\"" +" uid=\"" + uid + "\" />\n"
+            + "<package name=\"" + pkg2 + "\" uid=\"" + uid2 + "\" visibility=\""
+            + Notification.VISIBILITY_PRIVATE + "\" />\n"
+            + "</ranking>";
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())),
+            null);
+        parser.nextTag();
+        mHelper.readXml(parser, false);
+
+        final NotificationChannel updated1 =
+            mHelper.getNotificationChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID);
+        assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance());
+        assertTrue(updated1.canBypassDnd());
+        assertEquals(Notification.VISIBILITY_SECRET, updated1.getLockscreenVisibility());
+        assertEquals(NotificationChannel.USER_LOCKED_IMPORTANCE
+            | NotificationChannel.USER_LOCKED_PRIORITY
+            | NotificationChannel.USER_LOCKED_VISIBILITY, updated1.getUserLockedFields());
+
+        final NotificationChannel updated2 =
+            mHelper.getNotificationChannel(pkg2, uid2, NotificationChannel.DEFAULT_CHANNEL_ID);
+        // clamped
+        assertEquals(NotificationManager.IMPORTANCE_LOW, updated2.getImportance());
+        assertFalse(updated2.canBypassDnd());
+        assertEquals(Notification.VISIBILITY_PRIVATE, updated2.getLockscreenVisibility());
+        assertEquals(NotificationChannel.USER_LOCKED_VISIBILITY, updated2.getUserLockedFields());
+    }
+
+    @Test
+    public void testUpdate_userLockedImportance() throws Exception {
+        // all fields locked by user
+        final NotificationChannel channel =
+            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+        channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+
+        mHelper.createNotificationChannel(pkg, uid, channel);
+
+        // same id, try to update
+        final NotificationChannel channel2 =
+            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
+
+        mHelper.updateNotificationChannelFromRanker(pkg, uid, channel2);
+
+        // no fields should be changed
+        assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
+    }
+
+    @Test
+    public void testUpdate_userLockedVisibility() throws Exception {
+        // all fields locked by user
+        final NotificationChannel channel =
+            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+        channel.lockFields(NotificationChannel.USER_LOCKED_VISIBILITY);
+
+        mHelper.createNotificationChannel(pkg, uid, channel);
+
+        // same id, try to update
+        final NotificationChannel channel2 =
+            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
+        channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
+
+        mHelper.updateNotificationChannelFromRanker(pkg, uid, channel2);
+
+        // no fields should be changed
+        assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
+    }
+
+    @Test
+    public void testUpdate_userLockedVibration() throws Exception {
+        // all fields locked by user
+        final NotificationChannel channel =
+            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+        channel.setLights(false);
+        channel.lockFields(NotificationChannel.USER_LOCKED_VIBRATION);
+
+        mHelper.createNotificationChannel(pkg, uid, channel);
+
+        // same id, try to update
+        final NotificationChannel channel2 =
+            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
+        channel2.setVibration(true);
+
+        mHelper.updateNotificationChannelFromRanker(pkg, uid, channel2);
+
+        // no fields should be changed
+        assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
+    }
+
+    @Test
+    public void testUpdate_userLockedLights() throws Exception {
+        // all fields locked by user
+        final NotificationChannel channel =
+            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+        channel.setLights(false);
+        channel.lockFields(NotificationChannel.USER_LOCKED_LIGHTS);
+
+        mHelper.createNotificationChannel(pkg, uid, channel);
+
+        // same id, try to update
+        final NotificationChannel channel2 =
+            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
+        channel2.setLights(true);
+
+        mHelper.updateNotificationChannelFromRanker(pkg, uid, channel2);
+
+        // no fields should be changed
+        assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
+    }
+
+    @Test
+    public void testUpdate_userLockedPriority() throws Exception {
+        // all fields locked by user
+        final NotificationChannel channel =
+            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+        channel.setBypassDnd(true);
+        channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
+
+        mHelper.createNotificationChannel(pkg, uid, channel);
+
+        // same id, try to update all fields
+        final NotificationChannel channel2 =
+            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
+        channel2.setBypassDnd(false);
+
+        mHelper.updateNotificationChannelFromRanker(pkg, uid, channel2);
+
+        // no fields should be changed
+        assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
+    }
+
+    @Test
+    public void testUpdate_userLockedRingtone() throws Exception {
+        // all fields locked by user
+        final NotificationChannel channel =
+            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+        channel.setRingtone(new Uri.Builder().scheme("test").build());
+        channel.lockFields(NotificationChannel.USER_LOCKED_RINGTONE);
+
+        mHelper.createNotificationChannel(pkg, uid, channel);
+
+        // same id, try to update all fields
+        final NotificationChannel channel2 =
+            new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
+        channel2.setRingtone(new Uri.Builder().scheme("test2").build());
+
+        mHelper.updateNotificationChannelFromRanker(pkg, uid, channel2);
+
+        // no fields should be changed
+        assertEquals(channel, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
+    }
+
+    @Test
+    public void testUpdate() throws Exception {
+        // no fields locked by user
+        final NotificationChannel channel =
+                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_LOW);
+        channel.setRingtone(new Uri.Builder().scheme("test").build());
+        channel.setLights(true);
+        channel.setBypassDnd(true);
+        channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
+
+        mHelper.createNotificationChannel(pkg, uid, channel);
+
+        // same id, try to update all fields
+        final NotificationChannel channel2 =
+                new NotificationChannel("id2", "name2", NotificationManager.IMPORTANCE_HIGH);
+        channel2.setRingtone(new Uri.Builder().scheme("test2").build());
+        channel2.setLights(false);
+        channel2.setBypassDnd(false);
+        channel2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
+
+        mHelper.updateNotificationChannel(pkg, uid, channel2);
+
+        // all fields should be changed
+        assertEquals(channel2, mHelper.getNotificationChannel(pkg, uid, channel.getId()));
+    }
+
+    @Test
+    public void testGetChannelWithFallback() throws Exception {
+        NotificationChannel channel =
+                mHelper.getNotificationChannelWithFallback(pkg, uid, "garbage");
+        assertEquals(NotificationChannel.DEFAULT_CHANNEL_ID, channel.getId());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/notification/RateEstimatorTest.java b/services/tests/notification/src/com/android/server/notification/RateEstimatorTest.java
similarity index 100%
rename from services/tests/servicestests/src/com/android/server/notification/RateEstimatorTest.java
rename to services/tests/notification/src/com/android/server/notification/RateEstimatorTest.java
diff --git a/services/tests/servicestests/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java
similarity index 98%
rename from services/tests/servicestests/src/com/android/server/notification/SnoozeHelperTest.java
rename to services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java
index ec1fdad..ffc45ea 100644
--- a/services/tests/servicestests/src/com/android/server/notification/SnoozeHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java
@@ -24,6 +24,7 @@
 import android.app.AlarmManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
+import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.os.UserHandle;
@@ -178,7 +179,8 @@
                 .build();
         return new NotificationRecord(getContext(), new StatusBarNotification(
                 pkg, pkg, id, tag, 0, 0, 0, n, user),
-                new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name"));
+                new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
+                        NotificationManager.IMPORTANCE_HIGH));
     }
 
 }
diff --git a/services/tests/servicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java b/services/tests/notification/src/com/android/server/notification/ValidateNotificationPeopleTest.java
similarity index 100%
rename from services/tests/servicestests/src/com/android/server/notification/ValidateNotificationPeopleTest.java
rename to services/tests/notification/src/com/android/server/notification/ValidateNotificationPeopleTest.java
diff --git a/services/tests/runtests.py b/services/tests/runtests.py
new file mode 100755
index 0000000..7980dc2
--- /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"' %
+            (' '.join(sys.argv[1:]), INSTRUMENTED_PACKAGE_RUNNER))
+        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..42d9412 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;
 
@@ -245,7 +246,7 @@
                 Log.d(TAG, "set mUidObserver to " + mUidObserver);
                 return null;
             }
-        }).when(mActivityManager).registerUidObserver(any(), anyInt());
+        }).when(mActivityManager).registerUidObserver(any(), anyInt(), null);
 
         mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager, mStatsService,
                 mNetworkManager, mIpm, mTime, mPolicyDir, true);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
new file mode 100644
index 0000000..cb5e8bb
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
@@ -0,0 +1,827 @@
+/*
+ * 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.accessibility;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.animation.ValueAnimator;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.MagnificationSpec;
+import android.view.WindowManagerInternal;
+import android.view.WindowManagerInternal.MagnificationCallbacks;
+
+import com.android.internal.R;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.Locale;
+
+@RunWith(AndroidJUnit4.class)
+public class MagnificationControllerTest {
+    static final Rect INITIAL_MAGNIFICATION_BOUNDS = new Rect(0, 0, 100, 200);
+    static final PointF INITIAL_MAGNIFICATION_BOUNDS_CENTER = new PointF(
+            INITIAL_MAGNIFICATION_BOUNDS.centerX(), INITIAL_MAGNIFICATION_BOUNDS.centerY());
+    static final PointF INITIAL_BOUNDS_UPPER_LEFT_2X_CENTER = new PointF(25, 50);
+    static final PointF INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER = new PointF(75, 150);
+    static final Rect OTHER_MAGNIFICATION_BOUNDS = new Rect(100, 200, 500, 600);
+    static final PointF OTHER_BOUNDS_LOWER_RIGHT_2X_CENTER = new PointF(400, 500);
+    static final Region INITIAL_MAGNIFICATION_REGION = new Region(INITIAL_MAGNIFICATION_BOUNDS);
+    static final Region OTHER_REGION = new Region(OTHER_MAGNIFICATION_BOUNDS);
+    static final int SERVICE_ID_1 = 1;
+    static final int SERVICE_ID_2 = 2;
+
+    final Context mMockContext = mock(Context.class);
+    final AccessibilityManagerService mMockAms = mock(AccessibilityManagerService.class);
+    final WindowManagerInternal mMockWindowManager = mock(WindowManagerInternal.class);
+    final MessageCapturingHandler mMessageCapturingHandler =
+            new MessageCapturingHandler(new Handler.Callback() {
+        @Override
+        public boolean handleMessage(Message msg) {
+            return mMagnificationController.handleMessage(msg);
+        }
+    });
+    final ArgumentCaptor<MagnificationSpec> mMagnificationSpecCaptor =
+            ArgumentCaptor.forClass(MagnificationSpec.class);
+    final ValueAnimator mMockValueAnimator = mock(ValueAnimator.class);
+    MagnificationController.SettingsBridge mMockSettingsBridge;
+
+
+    MagnificationController mMagnificationController;
+    ValueAnimator.AnimatorUpdateListener mTargetAnimationListener;
+
+    @BeforeClass
+    public static void oneTimeInitialization() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+    }
+
+    @Before
+    public void setUp() {
+        when(mMockContext.getMainLooper()).thenReturn(Looper.myLooper());
+        Resources mockResources = mock(Resources.class);
+        when(mMockContext.getResources()).thenReturn(mockResources);
+        when(mockResources.getInteger(R.integer.config_longAnimTime))
+                .thenReturn(1000);
+        mMockSettingsBridge = mock(MagnificationController.SettingsBridge.class);
+        mMagnificationController = new MagnificationController(mMockContext, mMockAms, new Object(),
+                mMessageCapturingHandler, mMockWindowManager, mMockValueAnimator,
+                mMockSettingsBridge);
+
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
+                Object[] args = invocationOnMock.getArguments();
+                Region regionArg = (Region) args[0];
+                regionArg.set(INITIAL_MAGNIFICATION_REGION);
+                return null;
+            }
+        }).when(mMockWindowManager).getMagnificationRegion((Region) anyObject());
+
+        ArgumentCaptor<ValueAnimator.AnimatorUpdateListener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(ValueAnimator.AnimatorUpdateListener.class);
+        verify(mMockValueAnimator).addUpdateListener(listenerArgumentCaptor.capture());
+        mTargetAnimationListener = listenerArgumentCaptor.getValue();
+        Mockito.reset(mMockValueAnimator); // Ignore other initialization
+    }
+
+    @Test
+    public void testRegister_WindowManagerAndContextRegisterListeners() {
+        mMagnificationController.register();
+        verify(mMockContext).registerReceiver(
+                (BroadcastReceiver) anyObject(), (IntentFilter) anyObject());
+        verify(mMockWindowManager).setMagnificationCallbacks((MagnificationCallbacks) anyObject());
+        assertTrue(mMagnificationController.isRegisteredLocked());
+    }
+
+    @Test
+    public void testRegister_WindowManagerAndContextUnregisterListeners() {
+        mMagnificationController.register();
+        mMagnificationController.unregister();
+
+        verify(mMockContext).unregisterReceiver((BroadcastReceiver) anyObject());
+        verify(mMockWindowManager).setMagnificationCallbacks(null);
+        assertFalse(mMagnificationController.isRegisteredLocked());
+    }
+
+    @Test
+    public void testInitialState_noMagnificationAndMagnificationRegionReadFromWindowManager() {
+        mMagnificationController.register();
+        MagnificationSpec expectedInitialSpec = getMagnificationSpec(1.0f, 0.0f, 0.0f);
+        Region initialMagRegion = new Region();
+        Rect initialBounds = new Rect();
+
+        assertEquals(expectedInitialSpec, getCurrentMagnificationSpec());
+        mMagnificationController.getMagnificationRegion(initialMagRegion);
+        mMagnificationController.getMagnificationBounds(initialBounds);
+        assertEquals(INITIAL_MAGNIFICATION_REGION, initialMagRegion);
+        assertEquals(INITIAL_MAGNIFICATION_BOUNDS, initialBounds);
+        assertEquals(INITIAL_MAGNIFICATION_BOUNDS.centerX(),
+                mMagnificationController.getCenterX(), 0.0f);
+        assertEquals(INITIAL_MAGNIFICATION_BOUNDS.centerY(),
+                mMagnificationController.getCenterY(), 0.0f);
+    }
+
+    @Test
+    public void testNotRegistered_publicMethodsShouldBeBenign() {
+        assertFalse(mMagnificationController.isMagnifying());
+        assertFalse(mMagnificationController.magnificationRegionContains(100, 100));
+        assertFalse(mMagnificationController.reset(true));
+        assertFalse(mMagnificationController.setScale(2, 100, 100, true, 0));
+        assertFalse(mMagnificationController.setCenter(100, 100, false, 1));
+        assertFalse(mMagnificationController.setScaleAndCenter(1.5f, 100, 100, false, 2));
+        assertTrue(mMagnificationController.getIdOfLastServiceToMagnify() < 0);
+
+        mMagnificationController.getMagnificationRegion(new Region());
+        mMagnificationController.getMagnificationBounds(new Rect());
+        mMagnificationController.getScale();
+        mMagnificationController.getOffsetX();
+        mMagnificationController.getOffsetY();
+        mMagnificationController.getCenterX();
+        mMagnificationController.getCenterY();
+        mMagnificationController.offsetMagnifiedRegion(50, 50, 1);
+        mMagnificationController.unregister();
+    }
+
+    @Test
+    public void testSetScale_noAnimation_shouldGoStraightToWindowManagerAndUpdateState() {
+        mMagnificationController.register();
+        final float scale = 2.0f;
+        final PointF center = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
+        final PointF offsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, center, scale);
+        assertTrue(mMagnificationController
+                .setScale(scale, center.x, center.y, false, SERVICE_ID_1));
+
+        final MagnificationSpec expectedSpec = getMagnificationSpec(scale, offsets);
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(expectedSpec)));
+        assertThat(getCurrentMagnificationSpec(), closeTo(expectedSpec));
+        assertEquals(center.x, mMagnificationController.getCenterX(), 0.0);
+        assertEquals(center.y, mMagnificationController.getCenterY(), 0.0);
+        verify(mMockValueAnimator, times(0)).start();
+    }
+
+    @Test
+    public void testSetScale_withPivotAndAnimation_stateChangesAndAnimationHappens() {
+        mMagnificationController.register();
+        MagnificationSpec startSpec = getCurrentMagnificationSpec();
+        float scale = 2.0f;
+        PointF pivotPoint = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
+        assertTrue(mMagnificationController
+                .setScale(scale, pivotPoint.x, pivotPoint.y, true, SERVICE_ID_1));
+
+        // New center should be halfway between original center and pivot
+        PointF newCenter = new PointF((pivotPoint.x + INITIAL_MAGNIFICATION_BOUNDS.centerX()) / 2,
+                (pivotPoint.y + INITIAL_MAGNIFICATION_BOUNDS.centerY()) / 2);
+        PointF offsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale);
+        MagnificationSpec endSpec = getMagnificationSpec(scale, offsets);
+
+        assertEquals(newCenter.x, mMagnificationController.getCenterX(), 0.5);
+        assertEquals(newCenter.y, mMagnificationController.getCenterY(), 0.5);
+        assertThat(getCurrentMagnificationSpec(), closeTo(endSpec));
+        verify(mMockValueAnimator).start();
+
+        // Initial value
+        when(mMockValueAnimator.getAnimatedFraction()).thenReturn(0.0f);
+        mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
+        verify(mMockWindowManager).setMagnificationSpec(startSpec);
+
+        // Intermediate point
+        Mockito.reset(mMockWindowManager);
+        float fraction = 0.5f;
+        when(mMockValueAnimator.getAnimatedFraction()).thenReturn(fraction);
+        mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
+        verify(mMockWindowManager).setMagnificationSpec(
+                argThat(closeTo(getInterpolatedMagSpec(startSpec, endSpec, fraction))));
+
+        // Final value
+        Mockito.reset(mMockWindowManager);
+        when(mMockValueAnimator.getAnimatedFraction()).thenReturn(1.0f);
+        mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(endSpec)));
+    }
+
+    @Test
+    public void testSetCenter_whileMagnifying_noAnimation_centerMoves() {
+        mMagnificationController.register();
+        // First zoom in
+        float scale = 2.0f;
+        assertTrue(mMagnificationController.setScale(scale,
+                INITIAL_MAGNIFICATION_BOUNDS.centerX(), INITIAL_MAGNIFICATION_BOUNDS.centerY(),
+                false, SERVICE_ID_1));
+        Mockito.reset(mMockWindowManager);
+
+        PointF newCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
+        assertTrue(mMagnificationController
+                .setCenter(newCenter.x, newCenter.y, false, SERVICE_ID_1));
+        PointF expectedOffsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale);
+        MagnificationSpec expectedSpec = getMagnificationSpec(scale, expectedOffsets);
+
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(expectedSpec)));
+        assertEquals(newCenter.x, mMagnificationController.getCenterX(), 0.0);
+        assertEquals(newCenter.y, mMagnificationController.getCenterY(), 0.0);
+        verify(mMockValueAnimator, times(0)).start();
+    }
+
+    @Test
+    public void testSetScaleAndCenter_animated_stateChangesAndAnimationHappens() {
+        mMagnificationController.register();
+        MagnificationSpec startSpec = getCurrentMagnificationSpec();
+        float scale = 2.5f;
+        PointF newCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
+        PointF offsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale);
+        MagnificationSpec endSpec = getMagnificationSpec(scale, offsets);
+
+        assertTrue(mMagnificationController.setScaleAndCenter(scale, newCenter.x, newCenter.y,
+                true, SERVICE_ID_1));
+
+        assertEquals(newCenter.x, mMagnificationController.getCenterX(), 0.5);
+        assertEquals(newCenter.y, mMagnificationController.getCenterY(), 0.5);
+        assertThat(getCurrentMagnificationSpec(), closeTo(endSpec));
+        verify(mMockAms).notifyMagnificationChanged(
+                INITIAL_MAGNIFICATION_REGION, scale, newCenter.x, newCenter.y);
+        verify(mMockValueAnimator).start();
+
+        // Initial value
+        when(mMockValueAnimator.getAnimatedFraction()).thenReturn(0.0f);
+        mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
+        verify(mMockWindowManager).setMagnificationSpec(startSpec);
+
+        // Intermediate point
+        Mockito.reset(mMockWindowManager);
+        float fraction = 0.33f;
+        when(mMockValueAnimator.getAnimatedFraction()).thenReturn(fraction);
+        mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
+        verify(mMockWindowManager).setMagnificationSpec(
+                argThat(closeTo(getInterpolatedMagSpec(startSpec, endSpec, fraction))));
+
+        // Final value
+        Mockito.reset(mMockWindowManager);
+        when(mMockValueAnimator.getAnimatedFraction()).thenReturn(1.0f);
+        mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(endSpec)));
+    }
+
+    @Test
+    public void testSetScaleAndCenter_scaleOutOfBounds_cappedAtLimits() {
+        mMagnificationController.register();
+        MagnificationSpec startSpec = getCurrentMagnificationSpec();
+        PointF newCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
+        PointF offsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter,
+                MagnificationController.MAX_SCALE);
+        MagnificationSpec endSpec = getMagnificationSpec(
+                MagnificationController.MAX_SCALE, offsets);
+
+        assertTrue(mMagnificationController.setScaleAndCenter(
+                MagnificationController.MAX_SCALE + 1.0f,
+                newCenter.x, newCenter.y, false, SERVICE_ID_1));
+
+        assertEquals(newCenter.x, mMagnificationController.getCenterX(), 0.5);
+        assertEquals(newCenter.y, mMagnificationController.getCenterY(), 0.5);
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(endSpec)));
+        Mockito.reset(mMockWindowManager);
+
+        // Verify that we can't zoom below 1x
+        assertTrue(mMagnificationController.setScaleAndCenter(0.5f,
+                INITIAL_MAGNIFICATION_BOUNDS_CENTER.x, INITIAL_MAGNIFICATION_BOUNDS_CENTER.y,
+                false, SERVICE_ID_1));
+
+        assertEquals(INITIAL_MAGNIFICATION_BOUNDS_CENTER.x,
+                mMagnificationController.getCenterX(), 0.5);
+        assertEquals(INITIAL_MAGNIFICATION_BOUNDS_CENTER.y,
+                mMagnificationController.getCenterY(), 0.5);
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(startSpec)));
+    }
+
+    @Test
+    public void testSetScaleAndCenter_centerOutOfBounds_cappedAtLimits() {
+        mMagnificationController.register();
+        float scale = 2.0f;
+
+        // Off the edge to the top and left
+        assertTrue(mMagnificationController.setScaleAndCenter(
+                scale, -100f, -200f, false, SERVICE_ID_1));
+
+        PointF newCenter = INITIAL_BOUNDS_UPPER_LEFT_2X_CENTER;
+        PointF newOffsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale);
+        assertEquals(newCenter.x, mMagnificationController.getCenterX(), 0.5);
+        assertEquals(newCenter.y, mMagnificationController.getCenterY(), 0.5);
+        verify(mMockWindowManager).setMagnificationSpec(
+                argThat(closeTo(getMagnificationSpec(scale, newOffsets))));
+        Mockito.reset(mMockWindowManager);
+
+        // Off the edge to the bottom and right
+        assertTrue(mMagnificationController.setScaleAndCenter(scale,
+                INITIAL_MAGNIFICATION_BOUNDS.right + 1, INITIAL_MAGNIFICATION_BOUNDS.bottom + 1,
+                false, SERVICE_ID_1));
+        newCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
+        newOffsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale);
+        assertEquals(newCenter.x, mMagnificationController.getCenterX(), 0.5);
+        assertEquals(newCenter.y, mMagnificationController.getCenterY(), 0.5);
+        verify(mMockWindowManager).setMagnificationSpec(
+                argThat(closeTo(getMagnificationSpec(scale, newOffsets))));
+    }
+
+    @Test
+    public void testMagnificationRegionChanged_serviceNotified() {
+        mMagnificationController.register();
+        MagnificationCallbacks callbacks = getMagnificationCallbacks();
+        callbacks.onMagnificationRegionChanged(OTHER_REGION);
+        mMessageCapturingHandler.sendAllMessages();
+        verify(mMockAms).notifyMagnificationChanged(OTHER_REGION, 1.0f,
+                OTHER_MAGNIFICATION_BOUNDS.centerX(), OTHER_MAGNIFICATION_BOUNDS.centerY());
+    }
+
+    @Test
+    public void testOffsetMagnifiedRegion_whileMagnifying_offsetsMove() {
+        mMagnificationController.register();
+        PointF startCenter = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
+        float scale = 2.0f;
+        PointF startOffsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, startCenter, scale);
+        // First zoom in
+        assertTrue(mMagnificationController
+                .setScaleAndCenter(scale, startCenter.x, startCenter.y, false, SERVICE_ID_1));
+        Mockito.reset(mMockWindowManager);
+
+        PointF newCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
+        PointF newOffsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale);
+        mMagnificationController.offsetMagnifiedRegion(
+                startOffsets.x - newOffsets.x, startOffsets.y - newOffsets.y, SERVICE_ID_1);
+
+        MagnificationSpec expectedSpec = getMagnificationSpec(scale, newOffsets);
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(expectedSpec)));
+        assertEquals(newCenter.x, mMagnificationController.getCenterX(), 0.0);
+        assertEquals(newCenter.y, mMagnificationController.getCenterY(), 0.0);
+        verify(mMockValueAnimator, times(0)).start();
+    }
+
+    @Test
+    public void testOffsetMagnifiedRegion_whileNotMagnifying_hasNoEffect() {
+        mMagnificationController.register();
+        Mockito.reset(mMockWindowManager);
+        MagnificationSpec startSpec = getCurrentMagnificationSpec();
+        mMagnificationController.offsetMagnifiedRegion(10, 10, SERVICE_ID_1);
+        assertThat(getCurrentMagnificationSpec(), closeTo(startSpec));
+        mMagnificationController.offsetMagnifiedRegion(-10, -10, SERVICE_ID_1);
+        assertThat(getCurrentMagnificationSpec(), closeTo(startSpec));
+        verifyNoMoreInteractions(mMockWindowManager);
+    }
+
+    @Test
+    public void testOffsetMagnifiedRegion_whileMagnifyingButAtEdge_hasNoEffect() {
+        mMagnificationController.register();
+        float scale = 2.0f;
+
+        // Upper left edges
+        PointF ulCenter = INITIAL_BOUNDS_UPPER_LEFT_2X_CENTER;
+        assertTrue(mMagnificationController
+                .setScaleAndCenter(scale, ulCenter.x, ulCenter.y, false, SERVICE_ID_1));
+        Mockito.reset(mMockWindowManager);
+        MagnificationSpec ulSpec = getCurrentMagnificationSpec();
+        mMagnificationController.offsetMagnifiedRegion(-10, -10, SERVICE_ID_1);
+        assertThat(getCurrentMagnificationSpec(), closeTo(ulSpec));
+        verifyNoMoreInteractions(mMockWindowManager);
+
+        // Lower right edges
+        PointF lrCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
+        assertTrue(mMagnificationController
+                .setScaleAndCenter(scale, lrCenter.x, lrCenter.y, false, SERVICE_ID_1));
+        Mockito.reset(mMockWindowManager);
+        MagnificationSpec lrSpec = getCurrentMagnificationSpec();
+        mMagnificationController.offsetMagnifiedRegion(10, 10, SERVICE_ID_1);
+        assertThat(getCurrentMagnificationSpec(), closeTo(lrSpec));
+        verifyNoMoreInteractions(mMockWindowManager);
+    }
+
+    @Test
+    public void testGetIdOfLastServiceToChange_returnsCorrectValue() {
+        mMagnificationController.register();
+        PointF startCenter = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
+        assertTrue(mMagnificationController
+                .setScale(2.0f, startCenter.x, startCenter.y, false, SERVICE_ID_1));
+        assertEquals(SERVICE_ID_1, mMagnificationController.getIdOfLastServiceToMagnify());
+        assertTrue(mMagnificationController
+                .setScale(1.5f, startCenter.x, startCenter.y, false, SERVICE_ID_2));
+        assertEquals(SERVICE_ID_2, mMagnificationController.getIdOfLastServiceToMagnify());
+    }
+
+    @Test
+    public void testSetUserId_resetsOnlyIfIdChanges() {
+        final int userId1 = 1;
+        final int userId2 = 2;
+
+        mMagnificationController.register();
+        mMagnificationController.setUserId(userId1);
+        PointF startCenter = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
+        float scale = 2.0f;
+        mMagnificationController.setScale(scale, startCenter.x, startCenter.y, false, SERVICE_ID_1);
+
+        mMagnificationController.setUserId(userId1);
+        assertTrue(mMagnificationController.isMagnifying());
+        mMagnificationController.setUserId(userId2);
+        assertFalse(mMagnificationController.isMagnifying());
+    }
+
+    @Test
+    public void testResetIfNeeded_doesWhatItSays() {
+        mMagnificationController.register();
+        zoomIn2xToMiddle();
+        assertTrue(mMagnificationController.resetIfNeeded(false));
+        verify(mMockAms).notifyMagnificationChanged(
+                eq(INITIAL_MAGNIFICATION_REGION), eq(1.0f), anyInt(), anyInt());
+        assertFalse(mMagnificationController.isMagnifying());
+        assertFalse(mMagnificationController.resetIfNeeded(false));
+    }
+
+    @Test
+    public void testTurnScreenOff_resetsMagnification() {
+        mMagnificationController.register();
+        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
+                ArgumentCaptor.forClass(BroadcastReceiver.class);
+        verify(mMockContext).registerReceiver(
+                broadcastReceiverCaptor.capture(), (IntentFilter) anyObject());
+        BroadcastReceiver br = broadcastReceiverCaptor.getValue();
+        zoomIn2xToMiddle();
+        br.onReceive(mMockContext, null);
+        mMessageCapturingHandler.sendAllMessages();
+        assertFalse(mMagnificationController.isMagnifying());
+    }
+
+    @Test
+    public void testUserContextChange_resetsMagnification() {
+        mMagnificationController.register();
+        MagnificationCallbacks callbacks = getMagnificationCallbacks();
+        zoomIn2xToMiddle();
+        callbacks.onUserContextChanged();
+        mMessageCapturingHandler.sendAllMessages();
+        assertFalse(mMagnificationController.isMagnifying());
+    }
+
+    @Test
+    public void testRotation_resetsMagnification() {
+        mMagnificationController.register();
+        MagnificationCallbacks callbacks = getMagnificationCallbacks();
+        zoomIn2xToMiddle();
+        mMessageCapturingHandler.sendAllMessages();
+        assertTrue(mMagnificationController.isMagnifying());
+        callbacks.onRotationChanged(0);
+        mMessageCapturingHandler.sendAllMessages();
+        assertFalse(mMagnificationController.isMagnifying());
+    }
+
+    @Test
+    public void testBoundsChange_whileMagnifyingWithCompatibleSpec_noSpecChange() {
+        // Going from a small region to a large one leads to no issues
+        mMagnificationController.register();
+        zoomIn2xToMiddle();
+        MagnificationSpec startSpec = getCurrentMagnificationSpec();
+        MagnificationCallbacks callbacks = getMagnificationCallbacks();
+        Mockito.reset(mMockWindowManager);
+        callbacks.onMagnificationRegionChanged(OTHER_REGION);
+        mMessageCapturingHandler.sendAllMessages();
+        assertThat(getCurrentMagnificationSpec(), closeTo(startSpec));
+        verifyNoMoreInteractions(mMockWindowManager);
+    }
+
+    @Test
+    public void testBoundsChange_whileZoomingWithCompatibleSpec_noSpecChange() {
+        mMagnificationController.register();
+        PointF startCenter = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
+        float scale = 2.0f;
+        mMagnificationController.setScale(scale, startCenter.x, startCenter.y, true, SERVICE_ID_1);
+        MagnificationSpec startSpec = getCurrentMagnificationSpec();
+        MagnificationCallbacks callbacks = getMagnificationCallbacks();
+        Mockito.reset(mMockWindowManager);
+        callbacks.onMagnificationRegionChanged(OTHER_REGION);
+        mMessageCapturingHandler.sendAllMessages();
+        assertThat(getCurrentMagnificationSpec(), closeTo(startSpec));
+        verifyNoMoreInteractions(mMockWindowManager);
+    }
+
+    @Test
+    public void testBoundsChange_whileMagnifyingWithIncompatibleSpec_offsetsConstrained() {
+        // In a large region, pan to the farthest point possible
+        mMagnificationController.register();
+        MagnificationCallbacks callbacks = getMagnificationCallbacks();
+        callbacks.onMagnificationRegionChanged(OTHER_REGION);
+        mMessageCapturingHandler.sendAllMessages();
+        PointF startCenter = OTHER_BOUNDS_LOWER_RIGHT_2X_CENTER;
+        float scale = 2.0f;
+        mMagnificationController.setScale(scale, startCenter.x, startCenter.y, false, SERVICE_ID_1);
+        MagnificationSpec startSpec = getCurrentMagnificationSpec();
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(startSpec)));
+        Mockito.reset(mMockWindowManager);
+
+        callbacks.onMagnificationRegionChanged(INITIAL_MAGNIFICATION_REGION);
+        mMessageCapturingHandler.sendAllMessages();
+
+        MagnificationSpec endSpec = getCurrentMagnificationSpec();
+        assertThat(endSpec, CoreMatchers.not(closeTo(startSpec)));
+        PointF expectedOffsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS,
+                INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER, scale);
+        assertThat(endSpec, closeTo(getMagnificationSpec(scale, expectedOffsets)));
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(endSpec)));
+    }
+
+    @Test
+    public void testBoundsChange_whileZoomingWithIncompatibleSpec_jumpsToCompatibleSpec() {
+        mMagnificationController.register();
+        MagnificationCallbacks callbacks = getMagnificationCallbacks();
+        callbacks.onMagnificationRegionChanged(OTHER_REGION);
+        mMessageCapturingHandler.sendAllMessages();
+        PointF startCenter = OTHER_BOUNDS_LOWER_RIGHT_2X_CENTER;
+        float scale = 2.0f;
+        mMagnificationController.setScale(scale, startCenter.x, startCenter.y, true, SERVICE_ID_1);
+        MagnificationSpec startSpec = getCurrentMagnificationSpec();
+        when (mMockValueAnimator.isRunning()).thenReturn(true);
+
+        callbacks.onMagnificationRegionChanged(INITIAL_MAGNIFICATION_REGION);
+        mMessageCapturingHandler.sendAllMessages();
+        verify(mMockValueAnimator).cancel();
+
+        MagnificationSpec endSpec = getCurrentMagnificationSpec();
+        assertThat(endSpec, CoreMatchers.not(closeTo(startSpec)));
+        PointF expectedOffsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS,
+                INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER, scale);
+        assertThat(endSpec, closeTo(getMagnificationSpec(scale, expectedOffsets)));
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(endSpec)));
+    }
+
+    @Test
+    public void testRequestRectOnScreen_rectAlreadyOnScreen_doesNothing() {
+        mMagnificationController.register();
+        zoomIn2xToMiddle();
+        MagnificationSpec startSpec = getCurrentMagnificationSpec();
+        MagnificationCallbacks callbacks = getMagnificationCallbacks();
+        Mockito.reset(mMockWindowManager);
+        int centerX = (int) INITIAL_MAGNIFICATION_BOUNDS_CENTER.x;
+        int centerY = (int) INITIAL_MAGNIFICATION_BOUNDS_CENTER.y;
+        callbacks.onRectangleOnScreenRequested(centerX - 1, centerY - 1, centerX + 1, centerY - 1);
+        mMessageCapturingHandler.sendAllMessages();
+        assertThat(getCurrentMagnificationSpec(), closeTo(startSpec));
+        verifyNoMoreInteractions(mMockWindowManager);
+    }
+
+    @Test
+    public void testRequestRectOnScreen_rectCanFitOnScreen_pansToGetRectOnScreen() {
+        mMagnificationController.register();
+        zoomIn2xToMiddle();
+        MagnificationCallbacks callbacks = getMagnificationCallbacks();
+        Mockito.reset(mMockWindowManager);
+        callbacks.onRectangleOnScreenRequested(0, 0, 1, 1);
+        mMessageCapturingHandler.sendAllMessages();
+        MagnificationSpec expectedEndSpec = getMagnificationSpec(2.0f, 0, 0);
+        assertThat(getCurrentMagnificationSpec(), closeTo(expectedEndSpec));
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(expectedEndSpec)));
+    }
+
+    @Test
+    public void testRequestRectOnScreen_garbageInput_doesNothing() {
+        mMagnificationController.register();
+        zoomIn2xToMiddle();
+        MagnificationSpec startSpec = getCurrentMagnificationSpec();
+        MagnificationCallbacks callbacks = getMagnificationCallbacks();
+        Mockito.reset(mMockWindowManager);
+        callbacks.onRectangleOnScreenRequested(0, 0, -50, -50);
+        mMessageCapturingHandler.sendAllMessages();
+        assertThat(getCurrentMagnificationSpec(), closeTo(startSpec));
+        verifyNoMoreInteractions(mMockWindowManager);
+    }
+
+
+    @Test
+    public void testRequestRectOnScreen_rectTooWide_pansToGetStartOnScreenBasedOnLocale() {
+        Locale.setDefault(new Locale("en", "us"));
+        mMagnificationController.register();
+        zoomIn2xToMiddle();
+        MagnificationCallbacks callbacks = getMagnificationCallbacks();
+        MagnificationSpec startSpec = getCurrentMagnificationSpec();
+        Mockito.reset(mMockWindowManager);
+        Rect wideRect = new Rect(0, 50, 100, 51);
+        callbacks.onRectangleOnScreenRequested(
+                wideRect.left, wideRect.top, wideRect.right, wideRect.bottom);
+        mMessageCapturingHandler.sendAllMessages();
+        MagnificationSpec expectedEndSpec = getMagnificationSpec(2.0f, 0, startSpec.offsetY);
+        assertThat(getCurrentMagnificationSpec(), closeTo(expectedEndSpec));
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(expectedEndSpec)));
+        Mockito.reset(mMockWindowManager);
+
+        // Repeat with RTL
+        Locale.setDefault(new Locale("he", "il"));
+        callbacks.onRectangleOnScreenRequested(
+                wideRect.left, wideRect.top, wideRect.right, wideRect.bottom);
+        mMessageCapturingHandler.sendAllMessages();
+        expectedEndSpec = getMagnificationSpec(2.0f, -100, startSpec.offsetY);
+        assertThat(getCurrentMagnificationSpec(), closeTo(expectedEndSpec));
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(expectedEndSpec)));
+    }
+
+    @Test
+    public void testRequestRectOnScreen_rectTooTall_pansMinimumToGetTopOnScreen() {
+        mMagnificationController.register();
+        zoomIn2xToMiddle();
+        MagnificationCallbacks callbacks = getMagnificationCallbacks();
+        MagnificationSpec startSpec = getCurrentMagnificationSpec();
+        Mockito.reset(mMockWindowManager);
+        Rect tallRect = new Rect(50, 0, 51, 100);
+        callbacks.onRectangleOnScreenRequested(
+                tallRect.left, tallRect.top, tallRect.right, tallRect.bottom);
+        mMessageCapturingHandler.sendAllMessages();
+        MagnificationSpec expectedEndSpec = getMagnificationSpec(2.0f, startSpec.offsetX, 0);
+        assertThat(getCurrentMagnificationSpec(), closeTo(expectedEndSpec));
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(expectedEndSpec)));
+    }
+
+    @Test
+    public void testChangeMagnification_duringAnimation_animatesToNewValue() {
+        mMagnificationController.register();
+        MagnificationSpec startSpec = getCurrentMagnificationSpec();
+        float scale = 2.5f;
+        PointF firstCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
+        MagnificationSpec firstEndSpec = getMagnificationSpec(
+                scale, computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, firstCenter, scale));
+
+        assertTrue(mMagnificationController.setScaleAndCenter(scale, firstCenter.x, firstCenter.y,
+                true, SERVICE_ID_1));
+
+        assertEquals(firstCenter.x, mMagnificationController.getCenterX(), 0.5);
+        assertEquals(firstCenter.y, mMagnificationController.getCenterY(), 0.5);
+        assertThat(getCurrentMagnificationSpec(), closeTo(firstEndSpec));
+        verify(mMockValueAnimator, times(1)).start();
+
+        // Initial value
+        when(mMockValueAnimator.getAnimatedFraction()).thenReturn(0.0f);
+        mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
+        verify(mMockWindowManager).setMagnificationSpec(startSpec);
+        verify(mMockAms).notifyMagnificationChanged(
+                INITIAL_MAGNIFICATION_REGION, scale, firstCenter.x, firstCenter.y);
+        Mockito.reset(mMockWindowManager);
+
+        // Intermediate point
+        float fraction = 0.33f;
+        when(mMockValueAnimator.getAnimatedFraction()).thenReturn(fraction);
+        mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
+        MagnificationSpec intermediateSpec1 =
+                getInterpolatedMagSpec(startSpec, firstEndSpec, fraction);
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(intermediateSpec1)));
+        Mockito.reset(mMockWindowManager);
+
+        PointF newCenter = INITIAL_BOUNDS_UPPER_LEFT_2X_CENTER;
+        MagnificationSpec newEndSpec = getMagnificationSpec(
+                scale, computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale));
+        assertTrue(mMagnificationController.setCenter(
+                newCenter.x, newCenter.y, true, SERVICE_ID_1));
+
+        // Animation should have been restarted
+        verify(mMockValueAnimator, times(2)).start();
+        verify(mMockAms).notifyMagnificationChanged(
+                INITIAL_MAGNIFICATION_REGION, scale, newCenter.x, newCenter.y);
+
+        // New starting point should be where we left off
+        when(mMockValueAnimator.getAnimatedFraction()).thenReturn(0.0f);
+        mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(intermediateSpec1)));
+        Mockito.reset(mMockWindowManager);
+
+        // Second intermediate point
+        fraction = 0.5f;
+        when(mMockValueAnimator.getAnimatedFraction()).thenReturn(fraction);
+        mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
+        verify(mMockWindowManager).setMagnificationSpec(
+                argThat(closeTo(getInterpolatedMagSpec(intermediateSpec1, newEndSpec, fraction))));
+        Mockito.reset(mMockWindowManager);
+
+        // Final value should be the new center
+        Mockito.reset(mMockWindowManager);
+        when(mMockValueAnimator.getAnimatedFraction()).thenReturn(1.0f);
+        mTargetAnimationListener.onAnimationUpdate(mMockValueAnimator);
+        verify(mMockWindowManager).setMagnificationSpec(argThat(closeTo(newEndSpec)));
+    }
+
+    private void zoomIn2xToMiddle() {
+        PointF startCenter = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
+        float scale = 2.0f;
+        mMagnificationController.setScale(scale, startCenter.x, startCenter.y, false, SERVICE_ID_1);
+        assertTrue(mMagnificationController.isMagnifying());
+    }
+
+    private MagnificationCallbacks getMagnificationCallbacks() {
+        ArgumentCaptor<MagnificationCallbacks> magnificationCallbacksCaptor =
+                ArgumentCaptor.forClass(MagnificationCallbacks.class);
+        verify(mMockWindowManager)
+                .setMagnificationCallbacks(magnificationCallbacksCaptor.capture());
+        return magnificationCallbacksCaptor.getValue();
+    }
+
+    private PointF computeOffsets(Rect magnifiedBounds, PointF center, float scale) {
+        return new PointF(
+                magnifiedBounds.centerX() - scale * center.x,
+                magnifiedBounds.centerY() - scale * center.y);
+    }
+
+    private MagnificationSpec getInterpolatedMagSpec(MagnificationSpec start, MagnificationSpec end,
+            float fraction) {
+        MagnificationSpec interpolatedSpec = MagnificationSpec.obtain();
+        interpolatedSpec.scale = start.scale + fraction * (end.scale - start.scale);
+        interpolatedSpec.offsetX = start.offsetX + fraction * (end.offsetX - start.offsetX);
+        interpolatedSpec.offsetY = start.offsetY + fraction * (end.offsetY - start.offsetY);
+        return interpolatedSpec;
+    }
+
+    private MagnificationSpec getMagnificationSpec(float scale, PointF offsets) {
+        return getMagnificationSpec(scale, offsets.x, offsets.y);
+    }
+
+    private MagnificationSpec getMagnificationSpec(float scale, float offsetX, float offsetY) {
+        MagnificationSpec spec = MagnificationSpec.obtain();
+        spec.scale = scale;
+        spec.offsetX = offsetX;
+        spec.offsetY = offsetY;
+        return spec;
+    }
+
+    private MagnificationSpec getCurrentMagnificationSpec() {
+        return getMagnificationSpec(mMagnificationController.getScale(),
+                mMagnificationController.getOffsetX(), mMagnificationController.getOffsetY());
+    }
+
+    private MagSpecMatcher closeTo(MagnificationSpec spec) {
+        return new MagSpecMatcher(spec, 0.01f, 0.5f);
+    }
+
+    private class MagSpecMatcher extends TypeSafeMatcher<MagnificationSpec> {
+        final MagnificationSpec mMagSpec;
+        final float mScaleTolerance;
+        final float mOffsetTolerance;
+
+        MagSpecMatcher(MagnificationSpec spec, float scaleTolerance, float offsetTolerance) {
+            mMagSpec = spec;
+            mScaleTolerance = scaleTolerance;
+            mOffsetTolerance = offsetTolerance;
+        }
+
+        @Override
+        protected boolean matchesSafely(MagnificationSpec magnificationSpec) {
+            if (Math.abs(mMagSpec.scale - magnificationSpec.scale) > mScaleTolerance) {
+                return false;
+            }
+            if (Math.abs(mMagSpec.offsetX - magnificationSpec.offsetX) > mOffsetTolerance) {
+                return false;
+            }
+            if (Math.abs(mMagSpec.offsetY - magnificationSpec.offsetY) > mOffsetTolerance) {
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText("Match spec: " + mMagSpec);
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MessageCapturingHandler.java b/services/tests/servicestests/src/com/android/server/accessibility/MessageCapturingHandler.java
new file mode 100644
index 0000000..003f7ab
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MessageCapturingHandler.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 com.android.server.accessibility;
+
+import android.os.Handler;
+import android.os.Message;
+import android.util.Pair;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility class to capture messages dispatched through a handler and control when they arrive
+ * at their target.
+ */
+public class MessageCapturingHandler extends Handler {
+    List<Pair<Message, Long>> timedMessages = new ArrayList<>();
+
+    Handler.Callback mCallback;
+
+    public MessageCapturingHandler(Handler.Callback callback) {
+        mCallback = callback;
+    }
+
+    @Override
+    public boolean sendMessageAtTime(Message message, long uptimeMillis) {
+        timedMessages.add(new Pair<>(Message.obtain(message), uptimeMillis));
+        return super.sendMessageAtTime(message, uptimeMillis);
+    }
+
+    public void sendOneMessage() {
+        Message message = timedMessages.remove(0).first;
+        removeMessages(message.what, message.obj);
+        mCallback.handleMessage(message);
+        removeStaleMessages();
+    }
+
+    public void sendAllMessages() {
+        while (!timedMessages.isEmpty()) {
+            sendOneMessage();
+        }
+    }
+
+    public void sendLastMessage() {
+        Message message = timedMessages.remove(timedMessages.size() - 1).first;
+        removeMessages(message.what, message.obj);
+        mCallback.handleMessage(message);
+        removeStaleMessages();
+    }
+
+    public boolean hasMessages() {
+        removeStaleMessages();
+        return !timedMessages.isEmpty();
+    }
+
+    private void removeStaleMessages() {
+        for (int i = 0; i < timedMessages.size(); i++) {
+            Message message = timedMessages.get(i).first;
+            if (!hasMessages(message.what, message.obj)) {
+                timedMessages.remove(i--);
+            }
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
index 5920fef..d5305d9 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
@@ -92,7 +92,12 @@
 
     @Before
     public void setUp() {
-        mMessageCapturingHandler = new MessageCapturingHandler();
+        mMessageCapturingHandler = new MessageCapturingHandler(new Handler.Callback() {
+            @Override
+            public boolean handleMessage(Message msg) {
+                return mMotionEventInjector.handleMessage(msg);
+            }
+        });
         mMotionEventInjector = new MotionEventInjector(mMessageCapturingHandler);
         mClickList.add(
                 MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, CLICK_X, CLICK_Y_START, 0));
@@ -501,48 +506,4 @@
             return false;
         }
     }
-
-    private class MessageCapturingHandler extends Handler {
-        List<Pair<Message, Long>> timedMessages = new ArrayList<>();
-
-        @Override
-        public boolean sendMessageAtTime(Message message, long uptimeMillis) {
-            timedMessages.add(new Pair<>(Message.obtain(message), uptimeMillis));
-            return super.sendMessageAtTime(message, uptimeMillis);
-        }
-
-        void sendOneMessage() {
-            Message message = timedMessages.remove(0).first;
-            removeMessages(message.what, message.obj);
-            mMotionEventInjector.handleMessage(message);
-            removeStaleMessages();
-        }
-
-        void sendAllMessages() {
-            while (!timedMessages.isEmpty()) {
-                sendOneMessage();
-            }
-        }
-
-        void sendLastMessage() {
-            Message message = timedMessages.remove(timedMessages.size() - 1).first;
-            removeMessages(message.what, message.obj);
-            mMotionEventInjector.handleMessage(message);
-            removeStaleMessages();
-        }
-
-        boolean hasMessages() {
-            removeStaleMessages();
-            return !timedMessages.isEmpty();
-        }
-
-        private void removeStaleMessages() {
-            for (int i = 0; i < timedMessages.size(); i++) {
-                Message message = timedMessages.get(i).first;
-                if (!hasMessages(message.what, message.obj)) {
-                    timedMessages.remove(i--);
-                }
-            }
-        }
-    }
 }
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/devicepolicy/NetworkEventTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.java
new file mode 100644
index 0000000..315d37c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/NetworkEventTest.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.server.devicepolicy;
+
+import android.app.admin.ConnectEvent;
+import android.app.admin.DnsEvent;
+import android.os.Parcel;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import static junit.framework.Assert.assertEquals;
+
+@SmallTest
+public class NetworkEventTest extends DpmTestBase {
+
+    /**
+     * Test parceling and unparceling of a ConnectEvent.
+     */
+    public void testConnectEventParceling() {
+        ConnectEvent event = new ConnectEvent("127.0.0.1", 80, "com.android.whateverdude", 100000);
+        Parcel p = Parcel.obtain();
+        p.writeParcelable(event, 0);
+        p.setDataPosition(0);
+        ConnectEvent unparceledEvent = p.readParcelable(NetworkEventTest.class.getClassLoader());
+        p.recycle();
+        assertEquals(event.getIpAddress(), unparceledEvent.getIpAddress());
+        assertEquals(event.getPort(), unparceledEvent.getPort());
+        assertEquals(event.getPackageName(), unparceledEvent.getPackageName());
+        assertEquals(event.getTimestamp(), unparceledEvent.getTimestamp());
+    }
+
+    /**
+     * Test parceling and unparceling of a DnsEvent.
+     */
+    public void testDnsEventParceling() {
+        DnsEvent event = new DnsEvent("d.android.com", new String[]{"192.168.0.1", "127.0.0.1"}, 2,
+                "com.android.whateverdude", 100000);
+        Parcel p = Parcel.obtain();
+        p.writeParcelable(event, 0);
+        p.setDataPosition(0);
+        DnsEvent unparceledEvent = p.readParcelable(NetworkEventTest.class.getClassLoader());
+        p.recycle();
+        assertEquals(event.getHostname(), unparceledEvent.getHostname());
+        assertEquals(event.getIpAddresses()[0], unparceledEvent.getIpAddresses()[0]);
+        assertEquals(event.getIpAddresses()[1], unparceledEvent.getIpAddresses()[1]);
+        assertEquals(event.getIpAddressesCount(), unparceledEvent.getIpAddressesCount());
+        assertEquals(event.getPackageName(), unparceledEvent.getPackageName());
+        assertEquals(event.getTimestamp(), unparceledEvent.getTimestamp());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java
index 21560ac..5eee7b9 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkStatsObserversTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.when;
 
 import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.METERED_NO;
 import static android.net.NetworkStats.ROAMING_NO;
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
@@ -336,7 +337,7 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -344,7 +345,7 @@
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -374,7 +375,7 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -382,7 +383,7 @@
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -412,7 +413,7 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -420,7 +421,7 @@
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO,
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -450,16 +451,17 @@
         // Baseline
         NetworkStats xtSnapshot = null;
         NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, ROAMING_NO,
-                        BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
+                .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
+                        ROAMING_NO, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
                 VPN_INFO, TEST_START);
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
-                .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, ROAMING_NO,
-                        BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
+                .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
+                        ROAMING_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES,
+                        2L, 0L);
         mStatsObservers.updateStats(
                 xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
                 VPN_INFO, TEST_START);
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..728eb73 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
@@ -22,6 +22,9 @@
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.ConnectivityManager.TYPE_WIMAX;
 import static android.net.NetworkStats.IFACE_ALL;
+import static android.net.NetworkStats.METERED_ALL;
+import static android.net.NetworkStats.METERED_NO;
+import static android.net.NetworkStats.METERED_YES;
 import static android.net.NetworkStats.ROAMING_ALL;
 import static android.net.NetworkStats.ROAMING_NO;
 import static android.net.NetworkStats.ROAMING_YES;
@@ -88,7 +91,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;
@@ -305,9 +308,10 @@
         // verify service recorded history
         assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
         assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
-        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, ROAMING_NO, 512L, 4L, 256L, 2L, 4);
-        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, ROAMING_NO, 512L, 4L, 256L, 2L,
-                6);
+        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, METERED_NO, ROAMING_NO, 512L, 4L, 256L,
+                2L, 4);
+        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, METERED_NO, ROAMING_NO, 512L, 4L,
+                256L, 2L, 6);
         assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
 
 
@@ -329,9 +333,10 @@
         // after systemReady(), we should have historical stats loaded again
         assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
         assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
-        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, ROAMING_NO, 512L, 4L, 256L, 2L, 4);
-        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, ROAMING_NO, 512L, 4L, 256L, 2L,
-                6);
+        assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, METERED_NO, ROAMING_NO, 512L, 4L, 256L,
+                2L, 4);
+        assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, METERED_NO, ROAMING_NO, 512L, 4L,
+                256L, 2L, 6);
         assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
 
     }
@@ -638,20 +643,20 @@
         NetworkStats stats = mSession.getSummaryForAllUid(
                 sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
         assertEquals(3, stats.size());
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 50L, 5L,
-                50L, 5L, 1);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO, 10L, 1L, 10L,
-                1L, 1);
-        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, ROAMING_NO, 2048L, 16L,
-                1024L, 8L, 0);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 50L,
+                5L, 50L, 5L, 1);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 10L,
+                1L, 10L, 1L, 1);
+        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                2048L, 16L, 1024L, 8L, 0);
 
         // now verify that recent history only contains one uid
         final long currentTime = currentTimeMillis();
         stats = mSession.getSummaryForAllUid(
                 sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true);
         assertEquals(1, stats.size());
-        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L,
-                512L, 4L, 0);
+        assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+                1024L, 8L, 512L, 4L, 0);
     }
 
     @Test
@@ -705,14 +710,56 @@
         final NetworkStats stats = mSession.getSummaryForAllUid(
                 sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
         assertEquals(4, stats.size());
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 2L,
-                128L, 2L, 1);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 1L, 64L,
-                1L, 1);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 32L, 2L,
-                32L, 2L, 1);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, ROAMING_NO, 1L, 1L, 1L,
-                1L, 1);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L,
+                2L, 128L, 2L, 1);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 64L,
+                1L, 64L, 1L, 1);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
+                32L, 2L, 32L, 2L, 1);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, METERED_NO, ROAMING_NO, 1L,
+                1L, 1L, 1L, 1);
+    }
+
+    @Test
+    public void testMetered() throws Exception {
+        // pretend that network comes online
+        expectCurrentTime();
+        expectDefaultSettings();
+        expectNetworkState(buildWifiState(true /* isMetered */));
+        expectNetworkStatsSummary(buildEmptyStats());
+        expectNetworkStatsUidDetail(buildEmptyStats());
+        expectBandwidthControlCheck();
+
+        mService.forceUpdateIfaces();
+
+
+        // create some initial traffic
+        incrementCurrentTime(HOUR_IN_MILLIS);
+        expectCurrentTime();
+        expectDefaultSettings();
+        expectNetworkStatsSummary(buildEmptyStats());
+        // Note that all traffic from NetworkManagementService is tagged as METERED_NO and
+        // ROAMING_NO, because metered and roaming isn't tracked at that layer. We layer it
+        // on top by inspecting the iface properties.
+        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L,
+                        2L, 128L, 2L, 0L)
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 64L,
+                        1L, 64L, 1L, 0L));
+        mService.incrementOperationCount(UID_RED, 0xF00D, 1);
+
+        forcePollAndWaitForIdle();
+
+        // verify service recorded history
+        assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1);
+        // verify entire history present
+        final NetworkStats stats = mSession.getSummaryForAllUid(
+                sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
+        assertEquals(2, stats.size());
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
+                128L, 2L, 128L, 2L, 1);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, 64L,
+                1L, 64L, 1L, 1);
     }
 
     @Test
@@ -733,14 +780,14 @@
         expectCurrentTime();
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
-        // Note that all traffic from NetworkManagementService is tagged as ROAMING_NO, because
-        // roaming isn't tracked at that layer. We layer it on top by inspecting the iface
-        // properties.
+        // Note that all traffic from NetworkManagementService is tagged as METERED_NO and
+        // ROAMING_NO, because metered and roaming isn't tracked at that layer. We layer it
+        // on top by inspecting the iface properties.
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 2L,
-                        128L, 2L, 0L)
-                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 1L, 64L,
-                        1L, 0L));
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO,
+                        128L, 2L, 128L, 2L, 0L)
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO, 64L,
+                        1L, 64L, 1L, 0L));
         forcePollAndWaitForIdle();
 
         // verify service recorded history
@@ -750,10 +797,10 @@
         final NetworkStats stats = mSession.getSummaryForAllUid(
                 sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true);
         assertEquals(2, stats.size());
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_YES, 128L, 2L,
-                128L, 2L, 0);
-        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_YES, 64L, 1L, 64L,
-                1L, 0);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_YES,
+                128L, 2L, 128L, 2L, 0);
+        assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_YES, 64L,
+                1L, 64L, 1L, 0);
     }
 
     @Test
@@ -780,7 +827,8 @@
                 .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
         final String[] tetherIfacePairs = new String[] { TEST_IFACE, "wlan0" };
         final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1)
-                .addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L);
+                .addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L,
+                        0L);
 
         expectNetworkStatsUidDetail(uidStats, tetherIfacePairs, tetherStats);
         forcePollAndWaitForIdle();
@@ -923,18 +971,18 @@
 
         // verify summary API
         final NetworkStats stats = mSession.getSummaryForNetwork(template, start, end);
-        assertValues(stats, IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, rxBytes,
-                rxPackets, txBytes, txPackets, operations);
+        assertValues(stats, IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO,
+                rxBytes, rxPackets, txBytes, txPackets, operations);
     }
 
     private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets,
             long txBytes, long txPackets, int operations) throws Exception {
-        assertUidTotal(template, uid, SET_ALL, ROAMING_ALL, rxBytes, rxPackets, txBytes, txPackets,
-                operations);
+        assertUidTotal(template, uid, SET_ALL, METERED_ALL, ROAMING_ALL, rxBytes, rxPackets,
+                txBytes, txPackets, operations);
     }
 
-    private void assertUidTotal(NetworkTemplate template, int uid, int set, int roaming,
-            long rxBytes, long rxPackets, long txBytes, long txPackets, int operations)
+    private void assertUidTotal(NetworkTemplate template, int uid, int set, int metered,
+            int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations)
             throws Exception {
         // verify history API
         final NetworkStatsHistory history = mSession.getHistoryForUid(
@@ -945,8 +993,8 @@
         // verify summary API
         final NetworkStats stats = mSession.getSummaryForAllUid(
                 template, Long.MIN_VALUE, Long.MAX_VALUE, false);
-        assertValues(stats, IFACE_ALL, uid, set, TAG_NONE, roaming, rxBytes, rxPackets, txBytes,
-                txPackets, operations);
+        assertValues(stats, IFACE_ALL, uid, set, TAG_NONE, metered, roaming, rxBytes, rxPackets,
+                txBytes, txPackets, operations);
     }
 
     private void expectSystemReady() throws Exception {
@@ -1034,8 +1082,8 @@
     }
 
     private static void assertValues(NetworkStats stats, String iface, int uid, int set,
-            int tag, int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets,
-            int operations) {
+            int tag, int metered, int roaming, long rxBytes, long rxPackets, long txBytes,
+            long txPackets, int operations) {
         final NetworkStats.Entry entry = new NetworkStats.Entry();
         List<Integer> sets = new ArrayList<>();
         if (set == SET_DEFAULT || set == SET_ALL) {
@@ -1053,11 +1101,21 @@
             roamings.add(ROAMING_YES);
         }
 
+        List<Integer> meterings = new ArrayList<>();
+        if (metered == METERED_NO || metered == METERED_ALL) {
+            meterings.add(METERED_NO);
+        }
+        if (metered == METERED_YES || metered == METERED_ALL) {
+            meterings.add(METERED_YES);
+        }
+
         for (int s : sets) {
             for (int r : roamings) {
-                final int i = stats.findIndex(iface, uid, s, tag, r);
-                if (i != -1) {
-                    entry.add(stats.getValues(i, null));
+                for (int m : meterings) {
+                    final int i = stats.findIndex(iface, uid, s, tag, m, r);
+                    if (i != -1) {
+                        entry.add(stats.getValues(i, null));
+                    }
                 }
             }
         }
@@ -1080,11 +1138,18 @@
     }
 
     private static NetworkState buildWifiState() {
+        return buildWifiState(false);
+    }
+
+    private static NetworkState buildWifiState(boolean isMetered) {
         final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
         info.setDetailedState(DetailedState.CONNECTED, null, null);
         final LinkProperties prop = new LinkProperties();
         prop.setInterfaceName(TEST_IFACE);
         final NetworkCapabilities capabilities = new NetworkCapabilities();
+        if (!isMetered) {
+            capabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+        }
         return new NetworkState(info, prop, capabilities, null, null, TEST_SSID);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java
deleted file mode 100644
index ee33dcc..0000000
--- a/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.server.notification;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import com.android.internal.util.FastXmlSerializer;
-
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlSerializer;
-
-import android.app.Notification;
-import android.content.Context;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.net.Uri;
-import android.os.UserHandle;
-import android.service.notification.StatusBarNotification;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Xml;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class RankingHelperTest {
-    @Mock NotificationUsageStats mUsageStats;
-    @Mock RankingHandler handler;
-
-    private Notification mNotiGroupGSortA;
-    private Notification mNotiGroupGSortB;
-    private Notification mNotiNoGroup;
-    private Notification mNotiNoGroup2;
-    private Notification mNotiNoGroupSortA;
-    private NotificationRecord mRecordGroupGSortA;
-    private NotificationRecord mRecordGroupGSortB;
-    private NotificationRecord mRecordNoGroup;
-    private NotificationRecord mRecordNoGroup2;
-    private NotificationRecord mRecordNoGroupSortA;
-    private RankingHelper mHelper;
-
-    private Context getContext() {
-        return InstrumentationRegistry.getTargetContext();
-    }
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        UserHandle user = UserHandle.ALL;
-
-        mHelper = new RankingHelper(getContext(), handler, mUsageStats,
-                new String[] {ImportanceExtractor.class.getName()});
-
-        mNotiGroupGSortA = new Notification.Builder(getContext())
-                .setContentTitle("A")
-                .setGroup("G")
-                .setSortKey("A")
-                .setWhen(1205)
-                .build();
-        mRecordGroupGSortA = new NotificationRecord(getContext(), new StatusBarNotification(
-                "package", "package", 1, null, 0, 0, 0, mNotiGroupGSortA, user), 
-                getDefaultChannel());
-
-        mNotiGroupGSortB = new Notification.Builder(getContext())
-                .setContentTitle("B")
-                .setGroup("G")
-                .setSortKey("B")
-                .setWhen(1200)
-                .build();
-        mRecordGroupGSortB = new NotificationRecord(getContext(), new StatusBarNotification(
-                "package", "package", 1, null, 0, 0, 0, mNotiGroupGSortB, user), 
-                getDefaultChannel());
-
-        mNotiNoGroup = new Notification.Builder(getContext())
-                .setContentTitle("C")
-                .setWhen(1201)
-                .build();
-        mRecordNoGroup = new NotificationRecord(getContext(), new StatusBarNotification(
-                "package", "package", 1, null, 0, 0, 0, mNotiNoGroup, user), 
-                getDefaultChannel());
-
-        mNotiNoGroup2 = new Notification.Builder(getContext())
-                .setContentTitle("D")
-                .setWhen(1202)
-                .build();
-        mRecordNoGroup2 = new NotificationRecord(getContext(), new StatusBarNotification(
-                "package", "package", 1, null, 0, 0, 0, mNotiNoGroup2, user), 
-                getDefaultChannel());
-
-        mNotiNoGroupSortA = new Notification.Builder(getContext())
-                .setContentTitle("E")
-                .setWhen(1201)
-                .setSortKey("A")
-                .build();
-        mRecordNoGroupSortA = new NotificationRecord(getContext(), new StatusBarNotification(
-                "package", "package", 1, null, 0, 0, 0, mNotiNoGroupSortA, user), 
-                getDefaultChannel());
-    }
-
-    private NotificationChannel getDefaultChannel() {
-        return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name");
-    }    
-
-    @Test
-    public void testFindAfterRankingWithASplitGroup() throws Exception {
-        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(3);
-        notificationList.add(mRecordGroupGSortA);
-        notificationList.add(mRecordGroupGSortB);
-        notificationList.add(mRecordNoGroup);
-        notificationList.add(mRecordNoGroupSortA);
-        mHelper.sort(notificationList);
-        assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortA) >= 0);
-        assertTrue(mHelper.indexOf(notificationList, mRecordGroupGSortB) >= 0);
-        assertTrue(mHelper.indexOf(notificationList, mRecordNoGroup) >= 0);
-        assertTrue(mHelper.indexOf(notificationList, mRecordNoGroupSortA) >= 0);
-    }
-
-    @Test
-    public void testSortShouldNotThrowWithPlainNotifications() throws Exception {
-        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
-        notificationList.add(mRecordNoGroup);
-        notificationList.add(mRecordNoGroup2);
-        mHelper.sort(notificationList);
-    }
-
-    @Test
-    public void testSortShouldNotThrowOneSorted() throws Exception {
-        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(2);
-        notificationList.add(mRecordNoGroup);
-        notificationList.add(mRecordNoGroupSortA);
-        mHelper.sort(notificationList);
-    }
-
-    @Test
-    public void testSortShouldNotThrowOneNotification() throws Exception {
-        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
-        notificationList.add(mRecordNoGroup);
-        mHelper.sort(notificationList);
-    }
-
-    @Test
-    public void testSortShouldNotThrowOneSortKey() throws Exception {
-        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(1);
-        notificationList.add(mRecordGroupGSortB);
-        mHelper.sort(notificationList);
-    }
-
-    @Test
-    public void testSortShouldNotThrowOnEmptyList() throws Exception {
-        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>();
-        mHelper.sort(notificationList);
-    }
-
-    @Test
-    public void testChannelXml() throws Exception {
-        String pkg = "com.android.server.notification";
-        int uid = 0;
-        NotificationChannel channel1 = new NotificationChannel("id1", "name1");
-        NotificationChannel channel2 = new NotificationChannel("id2", "name2");
-        channel2.setImportance(NotificationManager.IMPORTANCE_LOW);
-        channel2.setDefaultRingtone(new Uri.Builder().scheme("test").build());
-        channel2.setLights(true);
-        channel2.setBypassDnd(true);
-        channel2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
-
-        mHelper.createNotificationChannel(pkg, uid, channel1);
-        mHelper.createNotificationChannel(pkg, uid, channel2);
-
-        byte[] data;
-        XmlSerializer serializer = new FastXmlSerializer();
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
-        serializer.startDocument(null, true);
-        serializer.startTag(null, "ranking");
-        mHelper.writeXml(serializer, false);
-        serializer.endTag(null, "ranking");
-        serializer.endDocument();
-        serializer.flush();
-
-        mHelper.deleteNotificationChannel(pkg, uid, channel1.getId());
-        mHelper.deleteNotificationChannel(pkg, uid, channel2.getId());
-        mHelper.deleteNotificationChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID);
-
-        XmlPullParser parser = Xml.newPullParser();
-        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())), null);
-        parser.nextTag();
-        mHelper.readXml(parser, false);
-
-        assertEquals(channel1, mHelper.getNotificationChannel(pkg, uid, channel1.getId()));
-        assertEquals(channel2, mHelper.getNotificationChannel(pkg, uid, channel2.getId()));
-        assertNotNull(
-                mHelper.getNotificationChannel(pkg, uid, NotificationChannel.DEFAULT_CHANNEL_ID));
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 1f0422b..40d8ac0 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -37,6 +37,10 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /** Test {@link UserManager} functionality. */
 public class UserManagerTest extends AndroidTestCase {
@@ -441,6 +445,33 @@
         switchUser(startUser);
     }
 
+    @MediumTest
+    public void testConcurrentUserCreate() throws Exception {
+        int userCount = mUserManager.getUserCount();
+        int maxSupportedUsers = UserManager.getMaxSupportedUsers();
+        int canBeCreatedCount = maxSupportedUsers - userCount;
+        // Test exceeding the limit while running in parallel
+        int createUsersCount = canBeCreatedCount + 5;
+        ExecutorService es = Executors.newCachedThreadPool();
+        AtomicInteger created = new AtomicInteger();
+        for (int i = 0; i < createUsersCount; i++) {
+            final String userName = "testConcUser" + i;
+            es.submit(() -> {
+                UserInfo user = mUserManager.createUser(userName, 0);
+                if (user != null) {
+                    created.incrementAndGet();
+                    synchronized (mUserRemoveLock) {
+                        usersToRemove.add(user.id);
+                    }
+                }
+            });
+        }
+        es.shutdown();
+        es.awaitTermination(20, TimeUnit.SECONDS);
+        assertEquals(maxSupportedUsers, mUserManager.getUserCount());
+        assertEquals(canBeCreatedCount, created.get());
+    }
+
     private boolean isPackageInstalledForUser(String packageName, int userId) {
         try {
             return mPackageManager.getPackageInfoAsUser(packageName, 0, userId) != null;
@@ -523,4 +554,5 @@
         }
         return profile;
     }
+
 }
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 763c50b..d2512ac 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.ContentObserver;
 import android.webkit.WebViewProviderInfo;
 
 import java.util.HashMap;
@@ -120,5 +121,8 @@
     }
 
     @Override
-    public void setMultiprocessEnabled(boolean enabled) {}
+    public void setMultiProcessEnabledFromContext(Context context) {}
+
+    @Override
+    public void registerContentObserver(Context context, ContentObserver contentObserver) {}
 }
diff --git a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
index 0f898e5..0519448 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
@@ -16,27 +16,33 @@
 
 package com.android.server.webkit;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.Signature;
 import android.os.Bundle;
-import android.util.Base64;
-import android.test.AndroidTestCase;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.MediumTest;
-
+import android.util.Base64;
 import android.webkit.WebViewFactory;
 import android.webkit.WebViewProviderInfo;
 import android.webkit.WebViewProviderResponse;
 
-import java.util.concurrent.CountDownLatch;
-
 import org.hamcrest.Description;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import org.mockito.Mockito;
 import org.mockito.Matchers;
 import org.mockito.ArgumentMatcher;
 
+import java.util.concurrent.CountDownLatch;
+
 
 /**
  * Tests for WebViewUpdateService
@@ -45,8 +51,9 @@
  */
 // Use MediumTest instead of SmallTest as the implementation of WebViewUpdateService
 // is intended to work on several threads and uses at least one sleep/wait-statement.
+@RunWith(AndroidJUnit4.class)
 @MediumTest
-public class WebViewUpdateServiceTest extends AndroidTestCase {
+public class WebViewUpdateServiceTest {
     private final static String TAG = WebViewUpdateServiceTest.class.getSimpleName();
 
     private WebViewUpdateServiceImpl mWebViewUpdateServiceImpl;
@@ -54,11 +61,6 @@
 
     private static final String WEBVIEW_LIBRARY_FLAG = "com.android.webview.WebViewLibrary";
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
     /**
      * Creates a new instance.
      */
@@ -108,7 +110,7 @@
         // Add (enabled and valid) package infos for each provider
         setEnabledAndValidPackageInfos(webviewPackages);
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
                 Mockito.argThat(new IsPackageInfoWithName(expectedProviderName)));
@@ -205,12 +207,27 @@
         assertEquals(expectedPackage, response.packageInfo.packageName);
     }
 
+    /**
+     * The WebView preparation boot phase is run on the main thread (especially on a thread with a
+     * looper) so to avoid bugs where our tests fail because a looper hasn't been attached to the
+     * thread running prepareWebViewInSystemServer we run it on the main thread.
+     */
+    private void runWebViewBootPreparationOnMainSync() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+            }
+        });
+    }
+
 
     // ****************
     // Tests
     // ****************
 
 
+    @Test
     public void testWithSinglePackage() {
         String testPackageName = "test.package.name";
         checkCertainPackageUsedAfterWebViewBootPreparation(testPackageName,
@@ -219,6 +236,7 @@
                             true /*default available*/, false /* fallback */, null)});
     }
 
+    @Test
     public void testDefaultPackageUsedOverNonDefault() {
         String defaultPackage = "defaultPackage";
         String nonDefaultPackage = "nonDefaultPackage";
@@ -228,6 +246,7 @@
         checkCertainPackageUsedAfterWebViewBootPreparation(defaultPackage, packages);
     }
 
+    @Test
     public void testSeveralRelros() {
         String singlePackage = "singlePackage";
         checkCertainPackageUsedAfterWebViewBootPreparation(
@@ -239,6 +258,7 @@
 
     // Ensure that package with valid signatures is chosen rather than package with invalid
     // signatures.
+    @Test
     public void testWithSignatures() {
         String validPackage = "valid package";
         String invalidPackage = "invalid package";
@@ -264,7 +284,7 @@
                     true /* valid */, true /* installed */, new Signature[]{validSignature}
                     , 0 /* updateTime */));
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
 
         checkPreparationPhasesForPackage(validPackage, 1 /* first preparation for this package */);
@@ -274,13 +294,14 @@
         assertEquals(validPackage, validPackages[0].packageName);
     }
 
+    @Test
     public void testFailWaitingForRelro() {
         WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
             new WebViewProviderInfo("packagename", "", true, true, null)};
         setupWithPackages(packages);
         setEnabledAndValidPackageInfos(packages);
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
                 Mockito.argThat(new IsPackageInfoWithName(packages[0].packageName)));
@@ -291,12 +312,13 @@
         assertEquals(WebViewFactory.LIBLOAD_FAILED_WAITING_FOR_RELRO, response.status);
     }
 
+    @Test
     public void testFailListingEmptyWebviewPackages() {
         WebViewProviderInfo[] packages = new WebViewProviderInfo[0];
         setupWithPackages(packages);
         setEnabledAndValidPackageInfos(packages);
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         Mockito.verify(mTestSystemImpl, Mockito.never()).onWebViewProviderChanged(
                 Matchers.anyObject());
@@ -330,6 +352,7 @@
         assertEquals(null, mWebViewUpdateServiceImpl.getCurrentWebViewPackage());
     }
 
+    @Test
     public void testFailListingInvalidWebviewPackage() {
         WebViewProviderInfo wpi = new WebViewProviderInfo("package", "", true, true, null);
         WebViewProviderInfo[] packages = new WebViewProviderInfo[] {wpi};
@@ -338,7 +361,7 @@
                 createPackageInfo(wpi.packageName, true /* enabled */, false /* valid */,
                     true /* installed */));
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         Mockito.verify(mTestSystemImpl, Mockito.never()).onWebViewProviderChanged(
                 Matchers.anyObject());
@@ -357,6 +380,7 @@
     }
 
     // Test that switching provider using changeProviderAndSetting works.
+    @Test
     public void testSwitchingProvider() {
         String firstPackage = "first";
         String secondPackage = "second";
@@ -366,6 +390,7 @@
         checkSwitchingProvider(packages, firstPackage, secondPackage);
     }
 
+    @Test
     public void testSwitchingProviderToNonDefault() {
         String defaultPackage = "defaultPackage";
         String nonDefaultPackage = "nonDefaultPackage";
@@ -386,11 +411,13 @@
     }
 
     // Change provider during relro creation by using changeProviderAndSetting
+    @Test
     public void testSwitchingProviderDuringRelroCreation() {
         checkChangingProviderDuringRelroCreation(true);
     }
 
     // Change provider during relro creation by enabling a provider
+    @Test
     public void testChangingProviderThroughEnablingDuringRelroCreation() {
         checkChangingProviderDuringRelroCreation(false);
     }
@@ -415,7 +442,7 @@
 
         CountDownLatch countdown = new CountDownLatch(1);
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
                 Mockito.argThat(new IsPackageInfoWithName(firstPackage)));
@@ -463,10 +490,12 @@
         }
     }
 
+    @Test
     public void testRunFallbackLogicIfEnabled() {
         checkFallbackLogicBeingRun(true);
     }
 
+    @Test
     public void testDontRunFallbackLogicIfDisabled() {
         checkFallbackLogicBeingRun(false);
     }
@@ -482,7 +511,7 @@
         setupWithPackages(packages, fallbackLogicEnabled);
         setEnabledAndValidPackageInfos(packages);
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
         // Verify that we disable the fallback package if fallback logic enabled, and don't disable
         // the fallback package if that logic is disabled
         if (fallbackLogicEnabled) {
@@ -518,6 +547,7 @@
      * 2. Install non-fallback
      * 3. Fallback should be disabled
      */
+    @Test
     public void testInstallingNonFallbackPackage() {
         String primaryPackage = "primary";
         String fallbackPackage = "fallback";
@@ -531,7 +561,7 @@
                 createPackageInfo(fallbackPackage, true /* enabled */ , true /* valid */,
                     true /* installed */));
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
         Mockito.verify(mTestSystemImpl, Mockito.never()).uninstallAndDisablePackageForAllUsers(
                 Matchers.anyObject(), Matchers.anyObject());
 
@@ -552,6 +582,7 @@
         Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(fallbackPackage));
     }
 
+    @Test
     public void testFallbackChangesEnabledState() {
         String primaryPackage = "primary";
         String fallbackPackage = "fallback";
@@ -563,7 +594,7 @@
         setupWithPackages(packages, true /* fallbackLogicEnabled */);
         setEnabledAndValidPackageInfos(packages);
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         // Verify fallback disabled at boot when primary package enabled
         Mockito.verify(mTestSystemImpl).enablePackageForUser(
@@ -601,10 +632,12 @@
         checkPreparationPhasesForPackage(primaryPackage, 2);
     }
 
+    @Test
     public void testAddUserWhenFallbackLogicEnabled() {
         checkAddingNewUser(true);
     }
 
+    @Test
     public void testAddUserWhenFallbackLogicDisabled() {
         checkAddingNewUser(false);
     }
@@ -638,6 +671,7 @@
      * Timing dependent test where we verify that the list of valid webview packages becoming empty
      * at a certain point doesn't crash us or break our state.
      */
+    @Test
     public void testNotifyRelroDoesntCrashIfNoPackages() {
         String firstPackage = "first";
         String secondPackage = "second";
@@ -650,7 +684,7 @@
         // Add (enabled and valid) package infos for each provider
         setEnabledAndValidPackageInfos(packages);
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
                 Mockito.argThat(new IsPackageInfoWithName(firstPackage)));
@@ -689,6 +723,7 @@
      * Verify that even if a user-chosen package is removed temporarily we start using it again when
      * it is added back.
      */
+    @Test
     public void testTempRemovePackageDoesntSwitchProviderPermanently() {
         String firstPackage = "first";
         String secondPackage = "second";
@@ -722,6 +757,7 @@
      * Ensure that we update the user-chosen setting across boots if the chosen package is no
      * longer installed and valid.
      */
+    @Test
     public void testProviderSettingChangedDuringBootIfProviderNotAvailable() {
         String chosenPackage = "chosenPackage";
         String nonChosenPackage = "non-chosenPackage";
@@ -739,7 +775,7 @@
         // Set user-chosen package
         mTestSystemImpl.updateUserSetting(null, chosenPackage);
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         // Verify that we switch the setting to point to the current package
         Mockito.verify(mTestSystemImpl).updateUserSetting(
@@ -749,10 +785,12 @@
         checkPreparationPhasesForPackage(nonChosenPackage, 1);
     }
 
+    @Test
     public void testRecoverFailedListingWebViewPackagesSettingsChange() {
         checkRecoverAfterFailListingWebviewPackages(true);
     }
 
+    @Test
     public void testRecoverFailedListingWebViewPackagesAddedPackage() {
         checkRecoverAfterFailListingWebviewPackages(false);
     }
@@ -799,10 +837,12 @@
         checkPreparationPhasesForPackage(secondPackage, 1);
     }
 
+    @Test
     public void testDontKillIfPackageReplaced() {
         checkDontKillIfPackageRemoved(true);
     }
 
+    @Test
     public void testDontKillIfPackageRemoved() {
         checkDontKillIfPackageRemoved(false);
     }
@@ -836,6 +876,7 @@
                 Mockito.anyObject());
     }
 
+    @Test
     public void testKillIfSettingChanged() {
         String firstPackage = "first";
         String secondPackage = "second";
@@ -857,6 +898,7 @@
      * Test that we kill apps using an old provider when we change the provider setting, even if the
      * new provider is not the one we intended to change to.
      */
+    @Test
     public void testKillIfChangeProviderIncorrectly() {
         String firstPackage = "first";
         String secondPackage = "second";
@@ -874,7 +916,7 @@
         // Start with the setting pointing to the third package
         mTestSystemImpl.updateUserSetting(null, thirdPackage);
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
         checkPreparationPhasesForPackage(thirdPackage, 1);
 
         mTestSystemImpl.setPackageInfo(
@@ -890,52 +932,62 @@
         Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(thirdPackage));
     }
 
+    @Test
     public void testLowerPackageVersionNotValid() {
         checkPackageVersions(new int[]{200000} /* system version */, 100000/* candidate version */,
                 false /* expected validity */);
     }
 
+    @Test
     public void testEqualPackageVersionValid() {
         checkPackageVersions(new int[]{100000} /* system version */, 100000 /* candidate version */,
                 true /* expected validity */);
     }
 
+    @Test
     public void testGreaterPackageVersionValid() {
         checkPackageVersions(new int[]{100000} /* system versions */, 200000 /* candidate version */,
                 true /* expected validity */);
     }
 
+    @Test
     public void testLastFiveDigitsIgnored() {
         checkPackageVersions(new int[]{654321} /* system version */, 612345 /* candidate version */,
                 true /* expected validity */);
     }
 
+    @Test
     public void testMinimumSystemVersionUsedTwoDefaultsCandidateValid() {
         checkPackageVersions(new int[]{300000, 100000} /* system versions */,
                 200000 /* candidate version */, true /* expected validity */);
     }
 
+    @Test
     public void testMinimumSystemVersionUsedTwoDefaultsCandidateInvalid() {
         checkPackageVersions(new int[]{300000, 200000} /* system versions */,
                  100000 /* candidate version */, false /* expected validity */);
     }
 
+    @Test
     public void testMinimumSystemVersionUsedSeveralDefaultsCandidateValid() {
         checkPackageVersions(new int[]{100000, 200000, 300000, 400000, 500000} /* system versions */,
                 100000 /* candidate version */, true /* expected validity */);
     }
 
+    @Test
     public void testMinimumSystemVersionUsedSeveralDefaultsCandidateInvalid() {
         checkPackageVersions(new int[]{200000, 300000, 400000, 500000, 600000} /* system versions */,
                 100000 /* candidate version */, false /* expected validity */);
     }
 
+    @Test
     public void testMinimumSystemVersionUsedFallbackIgnored() {
         checkPackageVersions(new int[]{300000, 400000, 500000, 600000, 700000} /* system versions */,
                 200000 /* candidate version */, false /* expected validity */, true /* add fallback */,
                 100000 /* fallback version */, false /* expected validity of fallback */);
     }
 
+    @Test
     public void testFallbackValid() {
         checkPackageVersions(new int[]{300000, 400000, 500000, 600000, 700000} /* system versions */,
                 200000/* candidate version */, false /* expected validity */, true /* add fallback */,
@@ -1030,7 +1082,7 @@
 
         assertEquals(expectedNumValidPackages, validPackages.length);
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         // The non-system package is not available by default so it shouldn't be used here
         checkPreparationPhasesForPackage(systemPackage + "1", 1);
@@ -1048,6 +1100,7 @@
 
     // Ensure that the update service uses an uninstalled package if that is the only package
     // available.
+    @Test
     public void testWithSingleUninstalledPackage() {
         String testPackageName = "test.package.name";
         WebViewProviderInfo[] webviewPackages = new WebViewProviderInfo[] {
@@ -1057,15 +1110,17 @@
         mTestSystemImpl.setPackageInfo(createPackageInfo(testPackageName, true /* enabled */,
                     true /* valid */, false /* installed */));
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         checkPreparationPhasesForPackage(testPackageName, 1 /* first preparation phase */);
     }
 
+    @Test
     public void testNonhiddenPackageUserOverHidden() {
         checkVisiblePackageUserOverNonVisible(false /* true == uninstalled, false == hidden */);
     }
 
+    @Test
     public void testInstalledPackageUsedOverUninstalled() {
         checkVisiblePackageUserOverNonVisible(true /* true == uninstalled, false == hidden */);
     }
@@ -1088,16 +1143,18 @@
                     true /* valid */, (testUninstalled ? false : true) /* installed */,
                     null /* signatures */, 0 /* updateTime */, (testHidden ? true : false)));
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         checkPreparationPhasesForPackage(installedPackage, 1 /* first preparation phase */);
     }
 
+    @Test
     public void testCantSwitchToHiddenPackage () {
         checkCantSwitchToNonVisiblePackage(false /* true == uninstalled, false == hidden */);
     }
 
 
+    @Test
     public void testCantSwitchToUninstalledPackage () {
         checkCantSwitchToNonVisiblePackage(true /* true == uninstalled, false == hidden */);
     }
@@ -1126,7 +1183,7 @@
                     null /* signatures */, 0 /* updateTime */,
                     (testHidden ? true : false) /* hidden */));
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         checkPreparationPhasesForPackage(installedPackage, 1 /* first preparation phase */);
 
@@ -1146,11 +1203,13 @@
                 Mockito.argThat(new IsPackageInfoWithName(installedPackage)));
     }
 
+    @Test
     public void testHiddenPackageNotPrioritizedEvenIfChosen() {
         checkNonvisiblePackageNotPrioritizedEvenIfChosen(
                 false /* true == uninstalled, false == hidden */);
     }
 
+    @Test
     public void testUninstalledPackageNotPrioritizedEvenIfChosen() {
         checkNonvisiblePackageNotPrioritizedEvenIfChosen(
                 true /* true == uninstalled, false == hidden */);
@@ -1178,7 +1237,7 @@
         // Start with the setting pointing to the uninstalled package
         mTestSystemImpl.updateUserSetting(null, uninstalledPackage);
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         checkPreparationPhasesForPackage(installedPackage, 1 /* first preparation phase */);
     }
@@ -1187,6 +1246,7 @@
      * Ensures that fallback becomes enabled if the primary package is uninstalled for the current
      * user.
      */
+    @Test
     public void testFallbackEnabledIfPrimaryUninstalled() {
         String primaryPackage = "primary";
         String fallbackPackage = "fallback";
@@ -1201,7 +1261,7 @@
         mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, true /* enabled */,
                     true /* valid */, true /* installed */));
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
         // Verify that we enable the fallback package
         Mockito.verify(mTestSystemImpl).enablePackageForAllUsers(
                 Mockito.anyObject(), Mockito.eq(fallbackPackage), Mockito.eq(true) /* enable */);
@@ -1209,6 +1269,7 @@
         checkPreparationPhasesForPackage(fallbackPackage, 1 /* first preparation phase */);
     }
 
+    @Test
     public void testPreparationRunsIffNewPackage() {
         String primaryPackage = "primary";
         String fallbackPackage = "fallback";
@@ -1224,7 +1285,7 @@
         mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, true /* enabled */,
                     true /* valid */, true /* installed */));
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         checkPreparationPhasesForPackage(primaryPackage, 1 /* first preparation phase */);
         Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser(
@@ -1270,6 +1331,7 @@
         checkPreparationPhasesForPackage(primaryPackage, 3 /* third preparation phase */);
     }
 
+    @Test
     public void testGetCurrentWebViewPackage() {
         PackageInfo firstPackage = createPackageInfo("first", true /* enabled */,
                         true /* valid */, true /* installed */);
@@ -1280,7 +1342,7 @@
         setupWithPackages(packages, true);
         mTestSystemImpl.setPackageInfo(firstPackage);
 
-        mWebViewUpdateServiceImpl.prepareWebViewInSystemServer();
+        runWebViewBootPreparationOnMainSync();
 
         Mockito.verify(mTestSystemImpl).onWebViewProviderChanged(
                 Mockito.argThat(new IsPackageInfoWithName(firstPackage.packageName)));
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
new file mode 100644
index 0000000..77f96ca
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
@@ -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
+ */
+
+package com.android.server.wm;
+
+import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
+import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_GOING_AWAY;
+import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_UNOCCLUDE;
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for {@link AppTransition}.
+ *
+ * runtest frameworks-services -c com.android.server.wm.AppTransitionTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class AppTransitionTests {
+
+    private WindowManagerService mWm;
+
+    @Before
+    public void setUp() throws Exception {
+        final Context context = InstrumentationRegistry.getTargetContext();
+        mWm = TestWindowManagerPolicy.getWindowManagerService(context);
+    }
+
+    @Test
+    public void testKeyguardOverride() throws Exception {
+        mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
+        mWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
+        assertEquals(TRANSIT_KEYGUARD_GOING_AWAY, mWm.mAppTransition.getAppTransition());
+    }
+
+    @Test
+    public void testForceOverride() throws Exception {
+        mWm.prepareAppTransition(TRANSIT_KEYGUARD_UNOCCLUDE, false /* alwaysKeepCurrent */);
+        mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */,
+                0 /* flags */, true /* forceOverride */);
+        assertEquals(TRANSIT_ACTIVITY_OPEN, mWm.mAppTransition.getAppTransition());
+    }
+}
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/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 03cbb43..38a98b2 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -55,13 +55,13 @@
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
 import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
 import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
 import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
+import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
@@ -115,11 +115,6 @@
     }
 
     @Override
-    public boolean canShowDismissingWindowWhileLockedLw() {
-        return false;
-    }
-
-    @Override
     public void setInitialDisplaySize(Display display, int width, int height, int density) {
 
     }
@@ -157,6 +152,7 @@
             return 2;
         }
         switch (type) {
+            case TYPE_PRESENTATION:
             case TYPE_PRIVATE_PRESENTATION:
                 return 2;
             case TYPE_WALLPAPER:
@@ -196,9 +192,6 @@
             case TYPE_INPUT_METHOD_DIALOG:
                 // on-screen keyboards and other such input method user interfaces go here.
                 return 13;
-            case TYPE_KEYGUARD_SCRIM:
-                // the safety window that shows behind keyguard while keyguard is starting
-                return 14;
             case TYPE_STATUS_BAR_SUB_PANEL:
                 return 15;
             case TYPE_STATUS_BAR:
@@ -299,27 +292,16 @@
     }
 
     @Override
-    public boolean isForceHiding(WindowManager.LayoutParams attrs) {
-        return false;
-    }
-
-    @Override
     public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) {
         return false;
     }
 
     @Override
-    public boolean canBeForceHidden(WindowState win,
-            WindowManager.LayoutParams attrs) {
+    public boolean canBeHiddenByKeyguardLw(WindowState win) {
         return false;
     }
 
     @Override
-    public WindowState getWinShowWhenLockedLw() {
-        return null;
-    }
-
-    @Override
     public View addStartingWindow(IBinder appToken, String packageName, int theme,
             CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, int icon,
             int logo, int windowFlags, Configuration overrideConfig) {
@@ -359,13 +341,13 @@
     }
 
     @Override
-    public Animation createForceHideEnterAnimation(boolean onWallpaper,
+    public Animation createHiddenByKeyguardExit(boolean onWallpaper,
             boolean goingToNotificationShade) {
         return null;
     }
 
     @Override
-    public Animation createForceHideWallpaperExitAnimation(boolean goingToNotificationShade) {
+    public Animation createKeyguardWallpaperExit(boolean goingToNotificationShade) {
         return null;
     }
 
@@ -432,8 +414,7 @@
 
     @Override
     public void applyPostLayoutPolicyLw(WindowState win,
-            WindowManager.LayoutParams attrs, WindowState attached) {
-
+            WindowManager.LayoutParams attrs, WindowState attached, WindowState imeTarget) {
     }
 
     @Override
@@ -523,7 +504,12 @@
     }
 
     @Override
-    public boolean isKeyguardShowingOrOccluded() {
+    public boolean isKeyguardOccluded() {
+        return false;
+    }
+
+    @Override
+    public boolean isKeyguardTrustedLw() {
         return false;
     }
 
@@ -543,16 +529,20 @@
     }
 
     @Override
-    public void notifyActivityDrawnForKeyguardLw() {
-
+    public boolean isKeyguardDrawnLw() {
+        return false;
     }
 
     @Override
-    public boolean isKeyguardDrawnLw() {
+    public boolean isShowingDreamLw() {
         return false;
     }
 
     @Override
+    public void onKeyguardOccludedChangedLw(boolean occluded) {
+    }
+
+    @Override
     public int rotationForOrientationLw(int orientation,
             int lastRotation) {
         return 0;
diff --git a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
new file mode 100644
index 0000000..36bd13a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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 junit.framework.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+
+import android.app.ActivityManagerInternal;
+import android.content.Context;
+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.IApplicationToken;
+
+import com.android.server.LocalServices;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+
+/**
+ * Test class for {@link AppTransition}.
+ *
+ * runtest frameworks-services -c com.android.server.wm.UnknownVisibilityControllerTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class UnknownAppVisibilityControllerTest {
+
+    private WindowManagerService mWm;
+    private @Mock ActivityManagerInternal mAm;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        final Context context = InstrumentationRegistry.getTargetContext();
+        LocalServices.addService(ActivityManagerInternal.class, mAm);
+        doAnswer((InvocationOnMock invocationOnMock) -> {
+            invocationOnMock.getArgumentAt(0, Runnable.class).run();
+            return null;
+        }).when(mAm).notifyKeyguardFlagsChanged(any());
+        mWm = TestWindowManagerPolicy.getWindowManagerService(context);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+    }
+
+    @Test
+    public void testFlow() throws Exception {
+        AppWindowToken token = createAppToken();
+        mWm.mUnknownAppVisibilityController.notifyLaunched(token);
+        mWm.mUnknownAppVisibilityController.notifyAppResumedFinished(token);
+        mWm.mUnknownAppVisibilityController.notifyRelayouted(token);
+
+        // Make sure our handler processed the message.
+        Thread.sleep(100);
+        assertTrue(mWm.mUnknownAppVisibilityController.allResolved());
+    }
+
+    @Test
+    public void testMultiple() throws Exception {
+        AppWindowToken token1 = createAppToken();
+        AppWindowToken token2 = createAppToken();
+        mWm.mUnknownAppVisibilityController.notifyLaunched(token1);
+        mWm.mUnknownAppVisibilityController.notifyAppResumedFinished(token1);
+        mWm.mUnknownAppVisibilityController.notifyLaunched(token2);
+        mWm.mUnknownAppVisibilityController.notifyRelayouted(token1);
+        mWm.mUnknownAppVisibilityController.notifyAppResumedFinished(token2);
+        mWm.mUnknownAppVisibilityController.notifyRelayouted(token2);
+
+        // Make sure our handler processed the message.
+        Thread.sleep(100);
+        assertTrue(mWm.mUnknownAppVisibilityController.allResolved());
+    }
+
+    @Test
+    public void testClear() throws Exception {
+        AppWindowToken token = createAppToken();
+        mWm.mUnknownAppVisibilityController.notifyLaunched(token);
+        mWm.mUnknownAppVisibilityController.clear();;
+        assertTrue(mWm.mUnknownAppVisibilityController.allResolved());
+    }
+
+    @Test
+    public void testAppRemoved() throws Exception {
+        AppWindowToken token = createAppToken();
+        mWm.mUnknownAppVisibilityController.notifyLaunched(token);
+        mWm.mUnknownAppVisibilityController.appRemoved(token);
+        assertTrue(mWm.mUnknownAppVisibilityController.allResolved());
+    }
+
+    private AppWindowToken createAppToken() {
+        return new AppWindowToken(mWm, mock(IApplicationToken.class), false,
+                mWm.getDefaultDisplayContentLocked());
+    }
+}
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 128317c..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
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..19b4186
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -0,0 +1,247 @@
+/*
+ * 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;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * 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 testLayoutInFullscreenTaskInsets() 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;
+
+        final int bottomContentInset = 100;
+        final int topContentInset = 50;
+        final int bottomVisibleInset = 30;
+        final int topVisibleInset = 70;
+        final int leftStableInset = 20;
+        final int rightStableInset = 90;
+
+        // With no insets or system decor all the frames incoming from PhoneWindowManager
+        // are identical.
+        final Rect pf = new Rect(0, 0, 1000, 1000);
+        final Rect df = pf;
+        final Rect of = df;
+        final Rect cf = new Rect(pf);
+        // Produce some insets
+        cf.top += 50;
+        cf.bottom -= 100;
+        final Rect vf = new Rect(pf);
+        vf.top += topVisibleInset;
+        vf.bottom -= bottomVisibleInset;
+        final Rect sf = new Rect(pf);
+        sf.left += leftStableInset;
+        sf.right -= rightStableInset;
+
+        final Rect dcf = pf;
+        // When mFrame extends past cf, the content insets are
+        // the difference between mFrame and ContentFrame. Visible
+        // and stable frames work the same way.
+        w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null);
+        assertRect(w.mFrame,0, 0, 1000, 1000);
+        assertRect(w.mContentInsets, 0, topContentInset, 0, bottomContentInset);
+        assertRect(w.mVisibleInsets, 0, topVisibleInset, 0, bottomVisibleInset);
+        assertRect(w.mStableInsets, leftStableInset, 0, rightStableInset, 0);
+        // The frames remain as passed in shrunk to the window frame
+        assertTrue(cf.equals(w.getContentFrameLw()));
+        assertTrue(vf.equals(w.getVisibleFrameLw()));
+        assertTrue(sf.equals(w.getStableFrameLw()));
+        // On the other hand mFrame doesn't extend past cf we won't get any insets
+        w.mAttrs.x = 100;
+        w.mAttrs.y = 100;
+        w.mAttrs.width = 100; w.mAttrs.height = 100; //have to clear MATCH_PARENT
+        w.mRequestedWidth = 100;
+        w.mRequestedHeight = 100;
+        w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null);
+        assertRect(w.mFrame, 100, 100, 200, 200);
+        assertRect(w.mContentInsets, 0, 0, 0, 0);
+        // In this case the frames are shrunk to the window frame.
+        assertTrue(w.mFrame.equals(w.getContentFrameLw()));
+        assertTrue(w.mFrame.equals(w.getVisibleFrameLw()));
+        assertTrue(w.mFrame.equals(w.getStableFrameLw()));
+    }
+
+    @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/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index af8c314..3daa87c 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -597,7 +597,6 @@
                             mAccessoryModeRequestTime + ACCESSORY_REQUEST_TIMEOUT;
 
             if (mConfigured && enteringAccessoryMode) {
-                mAccessoryModeRequestTime = 0;
                 // successfully entered accessory mode
 
                 if (mAccessoryStrings != null) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index e58fe70..7dacf16 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -59,6 +59,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
+
 final class VoiceInteractionSessionConnection implements ServiceConnection {
 
     final static String TAG = "VoiceInteractionServiceManager";
@@ -198,8 +201,7 @@
                         | Context.BIND_ALLOW_OOM_MANAGEMENT, new UserHandle(mUser));
         if (mBound) {
             try {
-                mIWindowManager.addWindowToken(mToken,
-                        WindowManager.LayoutParams.TYPE_VOICE_INTERACTION);
+                mIWindowManager.addWindowToken(mToken, TYPE_VOICE_INTERACTION, DEFAULT_DISPLAY);
             } catch (RemoteException e) {
                 Slog.w(TAG, "Failed adding window token", e);
             }
@@ -254,8 +256,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);
@@ -502,7 +503,7 @@
             }
             mContext.unbindService(this);
             try {
-                mIWindowManager.removeWindowToken(mToken);
+                mIWindowManager.removeWindowToken(mToken, DEFAULT_DISPLAY);
             } catch (RemoteException e) {
                 Slog.w(TAG, "Failed removing window token", e);
             }
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/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index df7d539..f3fada9 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -93,7 +93,8 @@
             ParcelableConnection connection) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.handleCreateConnectionComplete(id, request, connection);
+                adapter.handleCreateConnectionComplete(id, request, connection,
+                        Log.getExternalSession());
             } catch (RemoteException e) {
             }
         }
@@ -108,7 +109,7 @@
     void setActive(String callId) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setActive(callId);
+                adapter.setActive(callId, Log.getExternalSession());
             } catch (RemoteException e) {
             }
         }
@@ -122,7 +123,7 @@
     void setRinging(String callId) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setRinging(callId);
+                adapter.setRinging(callId, Log.getExternalSession());
             } catch (RemoteException e) {
             }
         }
@@ -136,7 +137,7 @@
     void setDialing(String callId) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setDialing(callId);
+                adapter.setDialing(callId, Log.getExternalSession());
             } catch (RemoteException e) {
             }
         }
@@ -151,7 +152,7 @@
     void setPulling(String callId) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setPulling(callId);
+                adapter.setPulling(callId, Log.getExternalSession());
             } catch (RemoteException e) {
             }
         }
@@ -167,7 +168,7 @@
     void setDisconnected(String callId, DisconnectCause disconnectCause) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setDisconnected(callId, disconnectCause);
+                adapter.setDisconnected(callId, disconnectCause, Log.getExternalSession());
             } catch (RemoteException e) {
             }
         }
@@ -181,7 +182,7 @@
     void setOnHold(String callId) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setOnHold(callId);
+                adapter.setOnHold(callId, Log.getExternalSession());
             } catch (RemoteException e) {
             }
         }
@@ -196,7 +197,7 @@
     void setRingbackRequested(String callId, boolean ringback) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setRingbackRequested(callId, ringback);
+                adapter.setRingbackRequested(callId, ringback, Log.getExternalSession());
             } catch (RemoteException e) {
             }
         }
@@ -205,7 +206,7 @@
     void setConnectionCapabilities(String callId, int capabilities) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setConnectionCapabilities(callId, capabilities);
+                adapter.setConnectionCapabilities(callId, capabilities, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -214,7 +215,7 @@
     void setConnectionProperties(String callId, int properties) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setConnectionProperties(callId, properties);
+                adapter.setConnectionProperties(callId, properties, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -232,7 +233,7 @@
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
                 Log.d(this, "sending connection %s with conference %s", callId, conferenceCallId);
-                adapter.setIsConferenced(callId, conferenceCallId);
+                adapter.setIsConferenced(callId, conferenceCallId, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -247,7 +248,7 @@
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
                 Log.d(this, "merge failed for call %s", callId);
-                adapter.setConferenceMergeFailed(callId);
+                adapter.setConferenceMergeFailed(callId, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -262,7 +263,7 @@
     void removeCall(String callId) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.removeCall(callId);
+                adapter.removeCall(callId, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -271,7 +272,7 @@
     void onPostDialWait(String callId, String remaining) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.onPostDialWait(callId, remaining);
+                adapter.onPostDialWait(callId, remaining, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -280,7 +281,7 @@
     void onPostDialChar(String callId, char nextChar) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.onPostDialChar(callId, nextChar);
+                adapter.onPostDialChar(callId, nextChar, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -294,7 +295,7 @@
     void addConferenceCall(String callId, ParcelableConference parcelableConference) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.addConferenceCall(callId, parcelableConference);
+                adapter.addConferenceCall(callId, parcelableConference, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -307,7 +308,8 @@
         // Only supported when there is only one adapter.
         if (mAdapters.size() == 1) {
             try {
-                mAdapters.iterator().next().queryRemoteConnectionServices(callback);
+                mAdapters.iterator().next().queryRemoteConnectionServices(callback,
+                        Log.getExternalSession());
             } catch (RemoteException e) {
                 Log.e(this, e, "Exception trying to query for remote CSs");
             }
@@ -326,7 +328,8 @@
             try {
                 adapter.setVideoProvider(
                         callId,
-                        videoProvider == null ? null : videoProvider.getInterface());
+                        videoProvider == null ? null : videoProvider.getInterface(),
+                        Log.getExternalSession());
             } catch (RemoteException e) {
             }
         }
@@ -341,7 +344,7 @@
     void setIsVoipAudioMode(String callId, boolean isVoip) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setIsVoipAudioMode(callId, isVoip);
+                adapter.setIsVoipAudioMode(callId, isVoip, Log.getExternalSession());
             } catch (RemoteException e) {
             }
         }
@@ -350,7 +353,7 @@
     void setStatusHints(String callId, StatusHints statusHints) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setStatusHints(callId, statusHints);
+                adapter.setStatusHints(callId, statusHints, Log.getExternalSession());
             } catch (RemoteException e) {
             }
         }
@@ -359,7 +362,7 @@
     void setAddress(String callId, Uri address, int presentation) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setAddress(callId, address, presentation);
+                adapter.setAddress(callId, address, presentation, Log.getExternalSession());
             } catch (RemoteException e) {
             }
         }
@@ -368,7 +371,8 @@
     void setCallerDisplayName(String callId, String callerDisplayName, int presentation) {
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setCallerDisplayName(callId, callerDisplayName, presentation);
+                adapter.setCallerDisplayName(callId, callerDisplayName, presentation,
+                        Log.getExternalSession());
             } catch (RemoteException e) {
             }
         }
@@ -389,7 +393,7 @@
         Log.v(this, "setVideoState: %d", videoState);
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setVideoState(callId, videoState);
+                adapter.setVideoState(callId, videoState, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -399,7 +403,8 @@
         Log.v(this, "setConferenceableConnections: %s, %s", callId, conferenceableCallIds);
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.setConferenceableConnections(callId, conferenceableCallIds);
+                adapter.setConferenceableConnections(callId, conferenceableCallIds,
+                        Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -415,7 +420,7 @@
         Log.v(this, "addExistingConnection: %s", callId);
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.addExistingConnection(callId, connection);
+                adapter.addExistingConnection(callId, connection, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -431,7 +436,7 @@
         Log.v(this, "putExtras: %s", callId);
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.putExtras(callId, extras);
+                adapter.putExtras(callId, extras, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -450,7 +455,7 @@
             try {
                 Bundle bundle = new Bundle();
                 bundle.putBoolean(key, value);
-                adapter.putExtras(callId, bundle);
+                adapter.putExtras(callId, bundle, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -469,7 +474,7 @@
             try {
                 Bundle bundle = new Bundle();
                 bundle.putInt(key, value);
-                adapter.putExtras(callId, bundle);
+                adapter.putExtras(callId, bundle, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -488,7 +493,7 @@
             try {
                 Bundle bundle = new Bundle();
                 bundle.putString(key, value);
-                adapter.putExtras(callId, bundle);
+                adapter.putExtras(callId, bundle, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -503,7 +508,7 @@
         Log.v(this, "removeExtras: %s %s", callId, keys);
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.removeExtras(callId, keys);
+                adapter.removeExtras(callId, keys, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
@@ -520,7 +525,7 @@
         Log.v(this, "onConnectionEvent: %s", event);
         for (IConnectionServiceAdapter adapter : mAdapters) {
             try {
-                adapter.onConnectionEvent(callId, event, extras);
+                adapter.onConnectionEvent(callId, event, extras, Log.getExternalSession());
             } catch (RemoteException ignored) {
             }
         }
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index 486f9d5..afe5e33 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -21,6 +21,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.RemoteException;
+import android.telecom.Logging.Session;
 
 import com.android.internal.os.SomeArgs;
 import com.android.internal.telecom.IConnectionServiceAdapter;
@@ -87,49 +88,55 @@
                         mDelegate.handleCreateConnectionComplete(
                                 (String) args.arg1,
                                 (ConnectionRequest) args.arg2,
-                                (ParcelableConnection) args.arg3);
+                                (ParcelableConnection) args.arg3,
+                                null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
                     break;
                 }
                 case MSG_SET_ACTIVE:
-                    mDelegate.setActive((String) msg.obj);
+                    mDelegate.setActive((String) msg.obj, null /*Session.Info*/);
                     break;
                 case MSG_SET_RINGING:
-                    mDelegate.setRinging((String) msg.obj);
+                    mDelegate.setRinging((String) msg.obj, null /*Session.Info*/);
                     break;
                 case MSG_SET_DIALING:
-                    mDelegate.setDialing((String) msg.obj);
+                    mDelegate.setDialing((String) msg.obj, null /*Session.Info*/);
                     break;
                 case MSG_SET_PULLING:
-                    mDelegate.setPulling((String) msg.obj);
+                    mDelegate.setPulling((String) msg.obj, null /*Session.Info*/);
                     break;
                 case MSG_SET_DISCONNECTED: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.setDisconnected((String) args.arg1, (DisconnectCause) args.arg2);
+                        mDelegate.setDisconnected((String) args.arg1, (DisconnectCause) args.arg2,
+                                null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
                     break;
                 }
                 case MSG_SET_ON_HOLD:
-                    mDelegate.setOnHold((String) msg.obj);
+                    mDelegate.setOnHold((String) msg.obj, null /*Session.Info*/);
                     break;
                 case MSG_SET_RINGBACK_REQUESTED:
-                    mDelegate.setRingbackRequested((String) msg.obj, msg.arg1 == 1);
+                    mDelegate.setRingbackRequested((String) msg.obj, msg.arg1 == 1,
+                            null /*Session.Info*/);
                     break;
                 case MSG_SET_CONNECTION_CAPABILITIES:
-                    mDelegate.setConnectionCapabilities((String) msg.obj, msg.arg1);
+                    mDelegate.setConnectionCapabilities((String) msg.obj, msg.arg1,
+                            null /*Session.Info*/);
                     break;
                 case MSG_SET_CONNECTION_PROPERTIES:
-                    mDelegate.setConnectionProperties((String) msg.obj, msg.arg1);
+                    mDelegate.setConnectionProperties((String) msg.obj, msg.arg1,
+                            null /*Session.Info*/);
                     break;
                 case MSG_SET_IS_CONFERENCED: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.setIsConferenced((String) args.arg1, (String) args.arg2);
+                        mDelegate.setIsConferenced((String) args.arg1, (String) args.arg2,
+                                null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
@@ -139,19 +146,22 @@
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
                         mDelegate.addConferenceCall(
-                                (String) args.arg1, (ParcelableConference) args.arg2);
+                                (String) args.arg1, (ParcelableConference) args.arg2,
+                                null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
                     break;
                 }
                 case MSG_REMOVE_CALL:
-                    mDelegate.removeCall((String) msg.obj);
+                    mDelegate.removeCall((String) msg.obj,
+                            null /*Session.Info*/);
                     break;
                 case MSG_ON_POST_DIAL_WAIT: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.onPostDialWait((String) args.arg1, (String) args.arg2);
+                        mDelegate.onPostDialWait((String) args.arg1, (String) args.arg2,
+                                null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
@@ -160,35 +170,39 @@
                 case MSG_ON_POST_DIAL_CHAR: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.onPostDialChar((String) args.arg1, (char) args.argi1);
+                        mDelegate.onPostDialChar((String) args.arg1, (char) args.argi1,
+                                null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
                     break;
                 }
                 case MSG_QUERY_REMOTE_CALL_SERVICES:
-                    mDelegate.queryRemoteConnectionServices((RemoteServiceCallback) msg.obj);
+                    mDelegate.queryRemoteConnectionServices((RemoteServiceCallback) msg.obj,
+                            null /*Session.Info*/);
                     break;
                 case MSG_SET_VIDEO_STATE:
-                    mDelegate.setVideoState((String) msg.obj, msg.arg1);
+                    mDelegate.setVideoState((String) msg.obj, msg.arg1, null /*Session.Info*/);
                     break;
                 case MSG_SET_VIDEO_CALL_PROVIDER: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
                         mDelegate.setVideoProvider((String) args.arg1,
-                                (IVideoProvider) args.arg2);
+                                (IVideoProvider) args.arg2, null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
                     break;
                 }
                 case MSG_SET_IS_VOIP_AUDIO_MODE:
-                    mDelegate.setIsVoipAudioMode((String) msg.obj, msg.arg1 == 1);
+                    mDelegate.setIsVoipAudioMode((String) msg.obj, msg.arg1 == 1,
+                            null /*Session.Info*/);
                     break;
                 case MSG_SET_STATUS_HINTS: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.setStatusHints((String) args.arg1, (StatusHints) args.arg2);
+                        mDelegate.setStatusHints((String) args.arg1, (StatusHints) args.arg2,
+                                null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
@@ -197,7 +211,8 @@
                 case MSG_SET_ADDRESS: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.setAddress((String) args.arg1, (Uri) args.arg2, args.argi1);
+                        mDelegate.setAddress((String) args.arg1, (Uri) args.arg2, args.argi1,
+                                null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
@@ -207,7 +222,8 @@
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
                         mDelegate.setCallerDisplayName(
-                                (String) args.arg1, (String) args.arg2, args.argi1);
+                                (String) args.arg1, (String) args.arg2, args.argi1,
+                                null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
@@ -216,8 +232,8 @@
                 case MSG_SET_CONFERENCEABLE_CONNECTIONS: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.setConferenceableConnections(
-                                (String) args.arg1, (List<String>) args.arg2);
+                        mDelegate.setConferenceableConnections((String) args.arg1,
+                                (List<String>) args.arg2, null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
@@ -226,8 +242,8 @@
                 case MSG_ADD_EXISTING_CONNECTION: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.addExistingConnection(
-                                (String) args.arg1, (ParcelableConnection) args.arg2);
+                        mDelegate.addExistingConnection((String) args.arg1,
+                                (ParcelableConnection) args.arg2, null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
@@ -236,7 +252,8 @@
                 case MSG_SET_CONFERENCE_MERGE_FAILED: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.setConferenceMergeFailed((String) args.arg1);
+                        mDelegate.setConferenceMergeFailed((String) args.arg1,
+                                null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
@@ -245,7 +262,8 @@
                 case MSG_PUT_EXTRAS: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.putExtras((String) args.arg1, (Bundle) args.arg2);
+                        mDelegate.putExtras((String) args.arg1, (Bundle) args.arg2,
+                                null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
@@ -254,7 +272,8 @@
                 case MSG_REMOVE_EXTRAS: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
-                        mDelegate.removeExtras((String) args.arg1, (List<String>) args.arg2);
+                        mDelegate.removeExtras((String) args.arg1, (List<String>) args.arg2,
+                                null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
@@ -264,7 +283,7 @@
                     SomeArgs args = (SomeArgs) msg.obj;
                     try {
                         mDelegate.onConnectionEvent((String) args.arg1, (String) args.arg2,
-                                (Bundle) args.arg3);
+                                (Bundle) args.arg3, null /*Session.Info*/);
                     } finally {
                         args.recycle();
                     }
@@ -279,7 +298,8 @@
         public void handleCreateConnectionComplete(
                 String id,
                 ConnectionRequest request,
-                ParcelableConnection connection) {
+                ParcelableConnection connection,
+                Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = id;
             args.arg2 = request;
@@ -288,28 +308,28 @@
         }
 
         @Override
-        public void setActive(String connectionId) {
+        public void setActive(String connectionId, Session.Info sessionInfo) {
             mHandler.obtainMessage(MSG_SET_ACTIVE, connectionId).sendToTarget();
         }
 
         @Override
-        public void setRinging(String connectionId) {
+        public void setRinging(String connectionId, Session.Info sessionInfo) {
             mHandler.obtainMessage(MSG_SET_RINGING, connectionId).sendToTarget();
         }
 
         @Override
-        public void setDialing(String connectionId) {
+        public void setDialing(String connectionId, Session.Info sessionInfo) {
             mHandler.obtainMessage(MSG_SET_DIALING, connectionId).sendToTarget();
         }
 
         @Override
-        public void setPulling(String connectionId) {
+        public void setPulling(String connectionId, Session.Info sessionInfo) {
             mHandler.obtainMessage(MSG_SET_PULLING, connectionId).sendToTarget();
         }
 
         @Override
-        public void setDisconnected(
-                String connectionId, DisconnectCause disconnectCause) {
+        public void setDisconnected(String connectionId, DisconnectCause disconnectCause,
+                Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.arg2 = disconnectCause;
@@ -317,39 +337,43 @@
         }
 
         @Override
-        public void setOnHold(String connectionId) {
+        public void setOnHold(String connectionId, Session.Info sessionInfo) {
             mHandler.obtainMessage(MSG_SET_ON_HOLD, connectionId).sendToTarget();
         }
 
         @Override
-        public void setRingbackRequested(String connectionId, boolean ringback) {
+        public void setRingbackRequested(String connectionId, boolean ringback,
+                Session.Info sessionInfo) {
             mHandler.obtainMessage(MSG_SET_RINGBACK_REQUESTED, ringback ? 1 : 0, 0, connectionId)
                     .sendToTarget();
         }
 
         @Override
-        public void setConnectionCapabilities(String connectionId, int connectionCapabilities) {
+        public void setConnectionCapabilities(String connectionId, int connectionCapabilities,
+                Session.Info sessionInfo) {
             mHandler.obtainMessage(
                     MSG_SET_CONNECTION_CAPABILITIES, connectionCapabilities, 0, connectionId)
                     .sendToTarget();
         }
 
         @Override
-        public void setConnectionProperties(String connectionId, int connectionProperties) {
+        public void setConnectionProperties(String connectionId, int connectionProperties,
+                Session.Info sessionInfo) {
             mHandler.obtainMessage(
                     MSG_SET_CONNECTION_PROPERTIES, connectionProperties, 0, connectionId)
                     .sendToTarget();
         }
 
         @Override
-        public void setConferenceMergeFailed(String callId) {
+        public void setConferenceMergeFailed(String callId, Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = callId;
             mHandler.obtainMessage(MSG_SET_CONFERENCE_MERGE_FAILED, args).sendToTarget();
         }
 
         @Override
-        public void setIsConferenced(String callId, String conferenceCallId) {
+        public void setIsConferenced(String callId, String conferenceCallId,
+                Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = callId;
             args.arg2 = conferenceCallId;
@@ -357,7 +381,8 @@
         }
 
         @Override
-        public void addConferenceCall(String callId, ParcelableConference parcelableConference) {
+        public void addConferenceCall(String callId, ParcelableConference parcelableConference,
+                Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = callId;
             args.arg2 = parcelableConference;
@@ -365,12 +390,14 @@
         }
 
         @Override
-        public void removeCall(String connectionId) {
+        public void removeCall(String connectionId,
+                Session.Info sessionInfo) {
             mHandler.obtainMessage(MSG_REMOVE_CALL, connectionId).sendToTarget();
         }
 
         @Override
-        public void onPostDialWait(String connectionId, String remainingDigits) {
+        public void onPostDialWait(String connectionId, String remainingDigits,
+                Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.arg2 = remainingDigits;
@@ -378,7 +405,8 @@
         }
 
         @Override
-        public void onPostDialChar(String connectionId, char nextChar) {
+        public void onPostDialChar(String connectionId, char nextChar,
+                Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.argi1 = nextChar;
@@ -386,17 +414,20 @@
         }
 
         @Override
-        public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
+        public void queryRemoteConnectionServices(RemoteServiceCallback callback,
+                Session.Info sessionInfo) {
             mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, callback).sendToTarget();
         }
 
         @Override
-        public void setVideoState(String connectionId, int videoState) {
+        public void setVideoState(String connectionId, int videoState,
+                Session.Info sessionInfo) {
             mHandler.obtainMessage(MSG_SET_VIDEO_STATE, videoState, 0, connectionId).sendToTarget();
         }
 
         @Override
-        public void setVideoProvider(String connectionId, IVideoProvider videoProvider) {
+        public void setVideoProvider(String connectionId, IVideoProvider videoProvider,
+                Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.arg2 = videoProvider;
@@ -404,13 +435,15 @@
         }
 
         @Override
-        public final void setIsVoipAudioMode(String connectionId, boolean isVoip) {
+        public final void setIsVoipAudioMode(String connectionId, boolean isVoip,
+                Session.Info sessionInfo) {
             mHandler.obtainMessage(MSG_SET_IS_VOIP_AUDIO_MODE, isVoip ? 1 : 0, 0,
                     connectionId).sendToTarget();
         }
 
         @Override
-        public final void setStatusHints(String connectionId, StatusHints statusHints) {
+        public final void setStatusHints(String connectionId, StatusHints statusHints,
+                Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.arg2 = statusHints;
@@ -418,7 +451,8 @@
         }
 
         @Override
-        public final void setAddress(String connectionId, Uri address, int presentation) {
+        public final void setAddress(String connectionId, Uri address, int presentation,
+                Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.arg2 = address;
@@ -428,7 +462,8 @@
 
         @Override
         public final void setCallerDisplayName(
-                String connectionId, String callerDisplayName, int presentation) {
+                String connectionId, String callerDisplayName, int presentation,
+                Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.arg2 = callerDisplayName;
@@ -437,8 +472,8 @@
         }
 
         @Override
-        public final void setConferenceableConnections(
-                String connectionId, List<String> conferenceableConnectionIds) {
+        public final void setConferenceableConnections(String connectionId,
+                List<String> conferenceableConnectionIds, Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.arg2 = conferenceableConnectionIds;
@@ -446,8 +481,8 @@
         }
 
         @Override
-        public final void addExistingConnection(
-                String connectionId, ParcelableConnection connection) {
+        public final void addExistingConnection(String connectionId,
+                ParcelableConnection connection, Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.arg2 = connection;
@@ -455,7 +490,7 @@
         }
 
         @Override
-        public final void putExtras(String connectionId, Bundle extras) {
+        public final void putExtras(String connectionId, Bundle extras, Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.arg2 = extras;
@@ -463,7 +498,8 @@
         }
 
         @Override
-        public final void removeExtras(String connectionId, List<String> keys) {
+        public final void removeExtras(String connectionId, List<String> keys,
+                Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.arg2 = keys;
@@ -471,7 +507,8 @@
         }
 
         @Override
-        public final void onConnectionEvent(String connectionId, String event, Bundle extras) {
+        public final void onConnectionEvent(String connectionId, String event, Bundle extras,
+                Session.Info sessionInfo) {
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = connectionId;
             args.arg2 = event;
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/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/telecomm/java/android/telecom/Logging/Session.aidl
similarity index 83%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to telecomm/java/android/telecom/Logging/Session.aidl
index 5f66d16..68961b6 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/telecomm/java/android/telecom/Logging/Session.aidl
@@ -11,9 +11,12 @@
  * 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.
+ * limitations under the License
  */
 
-package android.net.wifi.nan;
+package android.telecom.Logging;
 
-parcelable PublishConfig;
+/**
+ * {@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..0a8470a 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -21,6 +21,7 @@
 import android.os.IBinder;
 import android.os.IBinder.DeathRecipient;
 import android.os.RemoteException;
+import android.telecom.Logging.Session;
 
 import com.android.internal.telecom.IConnectionService;
 import com.android.internal.telecom.IConnectionServiceAdapter;
@@ -54,7 +55,8 @@
         public void handleCreateConnectionComplete(
                 String id,
                 ConnectionRequest request,
-                ParcelableConnection parcel) {
+                ParcelableConnection parcel,
+                Session.Info info) {
             RemoteConnection connection =
                     findConnectionForAction(id, "handleCreateConnectionSuccessful");
             if (connection != NULL_CONNECTION && mPendingConnections.contains(connection)) {
@@ -95,7 +97,7 @@
         }
 
         @Override
-        public void setActive(String callId) {
+        public void setActive(String callId, Session.Info sessionInfo) {
             if (mConnectionById.containsKey(callId)) {
                 findConnectionForAction(callId, "setActive")
                         .setState(Connection.STATE_ACTIVE);
@@ -106,25 +108,26 @@
         }
 
         @Override
-        public void setRinging(String callId) {
+        public void setRinging(String callId, Session.Info sessionInfo) {
             findConnectionForAction(callId, "setRinging")
                     .setState(Connection.STATE_RINGING);
         }
 
         @Override
-        public void setDialing(String callId) {
+        public void setDialing(String callId, Session.Info sessionInfo) {
             findConnectionForAction(callId, "setDialing")
                     .setState(Connection.STATE_DIALING);
         }
 
         @Override
-        public void setPulling(String callId) {
+        public void setPulling(String callId, Session.Info sessionInfo) {
             findConnectionForAction(callId, "setPulling")
                     .setState(Connection.STATE_PULLING_CALL);
         }
 
         @Override
-        public void setDisconnected(String callId, DisconnectCause disconnectCause) {
+        public void setDisconnected(String callId, DisconnectCause disconnectCause,
+                Session.Info sessionInfo) {
             if (mConnectionById.containsKey(callId)) {
                 findConnectionForAction(callId, "setDisconnected")
                         .setDisconnected(disconnectCause);
@@ -135,7 +138,7 @@
         }
 
         @Override
-        public void setOnHold(String callId) {
+        public void setOnHold(String callId, Session.Info sessionInfo) {
             if (mConnectionById.containsKey(callId)) {
                 findConnectionForAction(callId, "setOnHold")
                         .setState(Connection.STATE_HOLDING);
@@ -146,13 +149,14 @@
         }
 
         @Override
-        public void setRingbackRequested(String callId, boolean ringing) {
+        public void setRingbackRequested(String callId, boolean ringing, Session.Info sessionInfo) {
             findConnectionForAction(callId, "setRingbackRequested")
                     .setRingbackRequested(ringing);
         }
 
         @Override
-        public void setConnectionCapabilities(String callId, int connectionCapabilities) {
+        public void setConnectionCapabilities(String callId, int connectionCapabilities,
+                Session.Info sessionInfo) {
             if (mConnectionById.containsKey(callId)) {
                 findConnectionForAction(callId, "setConnectionCapabilities")
                         .setConnectionCapabilities(connectionCapabilities);
@@ -163,7 +167,8 @@
         }
 
         @Override
-        public void setConnectionProperties(String callId, int connectionProperties) {
+        public void setConnectionProperties(String callId, int connectionProperties,
+                Session.Info sessionInfo) {
             if (mConnectionById.containsKey(callId)) {
                 findConnectionForAction(callId, "setConnectionProperties")
                         .setConnectionProperties(connectionProperties);
@@ -174,7 +179,8 @@
         }
 
         @Override
-        public void setIsConferenced(String callId, String conferenceCallId) {
+        public void setIsConferenced(String callId, String conferenceCallId,
+                Session.Info sessionInfo) {
             // Note: callId should not be null; conferenceCallId may be null
             RemoteConnection connection =
                     findConnectionForAction(callId, "setIsConferenced");
@@ -195,7 +201,7 @@
         }
 
         @Override
-        public void setConferenceMergeFailed(String callId) {
+        public void setConferenceMergeFailed(String callId, Session.Info sessionInfo) {
             // Nothing to do here.
             // The event has already been handled and there is no state to update
             // in the underlying connection or conference objects
@@ -203,8 +209,7 @@
 
         @Override
         public void addConferenceCall(
-                final String callId,
-                ParcelableConference parcel) {
+                final String callId, ParcelableConference parcel, Session.Info sessionInfo) {
             RemoteConference conference = new RemoteConference(callId,
                     mOutgoingConnectionServiceRpc);
 
@@ -247,7 +252,7 @@
         }
 
         @Override
-        public void removeCall(String callId) {
+        public void removeCall(String callId, Session.Info sessionInfo) {
             if (mConnectionById.containsKey(callId)) {
                 findConnectionForAction(callId, "removeCall")
                         .setDestroyed();
@@ -258,24 +263,26 @@
         }
 
         @Override
-        public void onPostDialWait(String callId, String remaining) {
+        public void onPostDialWait(String callId, String remaining, Session.Info sessionInfo) {
             findConnectionForAction(callId, "onPostDialWait")
                     .setPostDialWait(remaining);
         }
 
         @Override
-        public void onPostDialChar(String callId, char nextChar) {
+        public void onPostDialChar(String callId, char nextChar, Session.Info sessionInfo) {
             findConnectionForAction(callId, "onPostDialChar")
                     .onPostDialChar(nextChar);
         }
 
         @Override
-        public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
+        public void queryRemoteConnectionServices(RemoteServiceCallback callback,
+                Session.Info sessionInfo) {
             // Not supported from remote connection service.
         }
 
         @Override
-        public void setVideoProvider(String callId, IVideoProvider videoProvider) {
+        public void setVideoProvider(String callId, IVideoProvider videoProvider,
+                Session.Info sessionInfo) {
             RemoteConnection.VideoProvider remoteVideoProvider = null;
             if (videoProvider != null) {
                 remoteVideoProvider = new RemoteConnection.VideoProvider(videoProvider);
@@ -285,32 +292,34 @@
         }
 
         @Override
-        public void setVideoState(String callId, int videoState) {
+        public void setVideoState(String callId, int videoState, Session.Info sessionInfo) {
             findConnectionForAction(callId, "setVideoState")
                     .setVideoState(videoState);
         }
 
         @Override
-        public void setIsVoipAudioMode(String callId, boolean isVoip) {
+        public void setIsVoipAudioMode(String callId, boolean isVoip, Session.Info sessionInfo) {
             findConnectionForAction(callId, "setIsVoipAudioMode")
                     .setIsVoipAudioMode(isVoip);
         }
 
         @Override
-        public void setStatusHints(String callId, StatusHints statusHints) {
+        public void setStatusHints(String callId, StatusHints statusHints,
+                Session.Info sessionInfo) {
             findConnectionForAction(callId, "setStatusHints")
                     .setStatusHints(statusHints);
         }
 
         @Override
-        public void setAddress(String callId, Uri address, int presentation) {
+        public void setAddress(String callId, Uri address, int presentation,
+                Session.Info sessionInfo) {
             findConnectionForAction(callId, "setAddress")
                     .setAddress(address, presentation);
         }
 
         @Override
         public void setCallerDisplayName(String callId, String callerDisplayName,
-                int presentation) {
+                int presentation, Session.Info sessionInfo) {
             findConnectionForAction(callId, "setCallerDisplayName")
                     .setCallerDisplayName(callerDisplayName, presentation);
         }
@@ -321,8 +330,8 @@
         }
 
         @Override
-        public final void setConferenceableConnections(
-                String callId, List<String> conferenceableConnectionIds) {
+        public final void setConferenceableConnections(String callId,
+                List<String> conferenceableConnectionIds, Session.Info sessionInfo) {
             List<RemoteConnection> conferenceable = new ArrayList<>();
             for (String id : conferenceableConnectionIds) {
                 if (mConnectionById.containsKey(id)) {
@@ -340,7 +349,8 @@
         }
 
         @Override
-        public void addExistingConnection(final String callId, ParcelableConnection connection) {
+        public void addExistingConnection(String callId, ParcelableConnection connection,
+                Session.Info sessionInfo) {
             RemoteConnection remoteConnection = new RemoteConnection(callId,
                     mOutgoingConnectionServiceRpc, connection);
             mConnectionById.put(callId, remoteConnection);
@@ -355,7 +365,7 @@
         }
 
         @Override
-        public void putExtras(String callId, Bundle extras) {
+        public void putExtras(String callId, Bundle extras, Session.Info sessionInfo) {
             if (hasConnection(callId)) {
                 findConnectionForAction(callId, "putExtras").putExtras(extras);
             } else {
@@ -364,7 +374,7 @@
         }
 
         @Override
-        public void removeExtras(String callId, List<String> keys) {
+        public void removeExtras(String callId, List<String> keys, Session.Info sessionInfo) {
             if (hasConnection(callId)) {
                 findConnectionForAction(callId, "removeExtra").removeExtras(keys);
             } else {
@@ -373,7 +383,8 @@
         }
 
         @Override
-        public void onConnectionEvent(String callId, String event, Bundle extras) {
+        public void onConnectionEvent(String callId, String event, Bundle extras,
+                Session.Info sessionInfo) {
             if (mConnectionById.containsKey(callId)) {
                 findConnectionForAction(callId, "onConnectionEvent").onConnectionEvent(event,
                         extras);
@@ -431,7 +442,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 +454,8 @@
                     id,
                     newRequest,
                     isIncoming,
-                    false /* isUnknownCall */);
+                    false /* isUnknownCall */,
+                    null /*Session.info*/);
             connection.registerCallback(new RemoteConnection.Callback() {
                 @Override
                 public void onDestroyed(RemoteConnection connection) {
@@ -482,7 +495,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/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
index 3bf83ae..002c3bb 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
@@ -21,6 +21,7 @@
 import android.os.Bundle;
 import android.telecom.ConnectionRequest;
 import android.telecom.DisconnectCause;
+import android.telecom.Logging.Session;
 import android.telecom.ParcelableConnection;
 import android.telecom.ParcelableConference;
 import android.telecom.StatusHints;
@@ -39,59 +40,68 @@
     void handleCreateConnectionComplete(
             String callId,
             in ConnectionRequest request,
-            in ParcelableConnection connection);
+            in ParcelableConnection connection,
+            in Session.Info sessionInfo);
 
-    void setActive(String callId);
+    void setActive(String callId, in Session.Info sessionInfo);
 
-    void setRinging(String callId);
+    void setRinging(String callId, in Session.Info sessionInfo);
 
-    void setDialing(String callId);
+    void setDialing(String callId, in Session.Info sessionInfo);
 
-    void setPulling(String callId);
+    void setPulling(String callId, in Session.Info sessionInfo);
 
-    void setDisconnected(String callId, in DisconnectCause disconnectCause);
+    void setDisconnected(String callId, in DisconnectCause disconnectCause,
+    in Session.Info sessionInfo);
 
-    void setOnHold(String callId);
+    void setOnHold(String callId, in Session.Info sessionInfo);
 
-    void setRingbackRequested(String callId, boolean ringing);
+    void setRingbackRequested(String callId, boolean ringing, in Session.Info sessionInfo);
 
-    void setConnectionCapabilities(String callId, int connectionCapabilities);
+    void setConnectionCapabilities(String callId, int connectionCapabilities,
+    in Session.Info sessionInfo);
 
-    void setConnectionProperties(String callId, int connectionProperties);
+    void setConnectionProperties(String callId, int connectionProperties,
+    in Session.Info sessionInfo);
 
-    void setIsConferenced(String callId, String conferenceCallId);
+    void setIsConferenced(String callId, String conferenceCallId, in Session.Info sessionInfo);
 
-    void setConferenceMergeFailed(String callId);
+    void setConferenceMergeFailed(String callId, in Session.Info sessionInfo);
 
-    void addConferenceCall(String callId, in ParcelableConference conference);
+    void addConferenceCall(String callId, in ParcelableConference conference,
+    in Session.Info sessionInfo);
 
-    void removeCall(String callId);
+    void removeCall(String callId, in Session.Info sessionInfo);
 
-    void onPostDialWait(String callId, String remaining);
+    void onPostDialWait(String callId, String remaining, in Session.Info sessionInfo);
 
-    void onPostDialChar(String callId, char nextChar);
+    void onPostDialChar(String callId, char nextChar, in Session.Info sessionInfo);
 
-    void queryRemoteConnectionServices(RemoteServiceCallback callback);
+    void queryRemoteConnectionServices(RemoteServiceCallback callback, in Session.Info sessionInfo);
 
-    void setVideoProvider(String callId, IVideoProvider videoProvider);
+    void setVideoProvider(String callId, IVideoProvider videoProvider, in Session.Info sessionInfo);
 
-    void setVideoState(String callId, int videoState);
+    void setVideoState(String callId, int videoState, in Session.Info sessionInfo);
 
-    void setIsVoipAudioMode(String callId, boolean isVoip);
+    void setIsVoipAudioMode(String callId, boolean isVoip, in Session.Info sessionInfo);
 
-    void setStatusHints(String callId, in StatusHints statusHints);
+    void setStatusHints(String callId, in StatusHints statusHints, in Session.Info sessionInfo);
 
-    void setAddress(String callId, in Uri address, int presentation);
+    void setAddress(String callId, in Uri address, int presentation, in Session.Info sessionInfo);
 
-    void setCallerDisplayName(String callId, String callerDisplayName, int presentation);
+    void setCallerDisplayName(String callId, String callerDisplayName, int presentation,
+    in Session.Info sessionInfo);
 
-    void setConferenceableConnections(String callId, in List<String> conferenceableCallIds);
+    void setConferenceableConnections(String callId, in List<String> conferenceableCallIds,
+    in Session.Info sessionInfo);
 
-    void addExistingConnection(String callId, in ParcelableConnection connection);
+    void addExistingConnection(String callId, in ParcelableConnection connection,
+    in Session.Info sessionInfo);
 
-    void putExtras(String callId, in Bundle extras);
+    void putExtras(String callId, in Bundle extras, in Session.Info sessionInfo);
 
-    void removeExtras(String callId, in List<String> keys);
+    void removeExtras(String callId, in List<String> keys, in Session.Info sessionInfo);
 
-    void onConnectionEvent(String callId, String event, in Bundle extras);
+    void onConnectionEvent(String callId, String event, 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..60a27bd 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -498,6 +498,13 @@
             "disable_severe_when_extreme_disabled_bool";
 
     /**
+     * The message expiration time in milliseconds for duplicate detection purposes.
+     * @hide
+     */
+    public static final String KEY_MESSAGE_EXPIRATION_TIME_LONG =
+            "message_expiration_time_long";
+
+    /**
      * The data call retry configuration for different types of APN.
      * @hide
      */
@@ -1072,6 +1079,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;
 
@@ -1153,6 +1172,7 @@
         sDefaults.putBoolean(KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL, false);
         sDefaults.putBoolean(KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL, false);
         sDefaults.putBoolean(KEY_DISABLE_SEVERE_WHEN_EXTREME_DISABLED_BOOL, true);
+        sDefaults.putLong(KEY_MESSAGE_EXPIRATION_TIME_LONG, 86400000L);
         sDefaults.putStringArray(KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS, new String[]{
                 "default:default_randomization=2000,5000,10000,20000,40000,80000:5000,160000:5000,"
                         + "320000:5000,640000:5000,1280000:5000,1800000:5000",
@@ -1266,6 +1286,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 fe9d41a..d75dd7d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -16,7 +16,10 @@
 
 package android.telephony;
 
+import static com.android.internal.util.Preconditions.checkNotNull;
+
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
@@ -27,11 +30,12 @@
 import android.net.ConnectivityManager;
 import android.net.Uri;
 import android.os.BatteryStats;
-import android.os.ResultReceiver;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.service.carrier.CarrierIdentifier;
@@ -792,6 +796,29 @@
      */
     public static final String VVM_TYPE_CVVM = "vvm_type_cvvm";
 
+    /**
+     * @hide
+     */
+    public static final String USSD_RESPONSE = "USSD_RESPONSE";
+
+    /**
+     * USSD return code success.
+     * @hide
+     */
+    public static final int USSD_RETURN_SUCCESS = 100;
+
+    /**
+     * USSD return code for failure case.
+     * @hide
+     */
+    public static final int USSD_RETURN_FAILURE = -1;
+
+    /**
+     * USSD return code for failure case.
+     * @hide
+     */
+    public static final int USSD_ERROR_SERVICE_UNAVAIL = -2;
+
     //
     //
     // Device Info
@@ -1166,7 +1193,7 @@
     private int getPhoneTypeFromProperty(int phoneId) {
         String type = getTelephonyProperty(phoneId,
                 TelephonyProperties.CURRENT_ACTIVE_PHONE, null);
-        if (type == null || type.equals("")) {
+        if (type == null || type.isEmpty()) {
             return getPhoneTypeFromNetworkType(phoneId);
         }
         return Integer.parseInt(type);
@@ -1182,7 +1209,7 @@
         // use the system property for default network type.
         // This is a fail safe, and can only happen at first boot.
         String mode = getTelephonyProperty(phoneId, "ro.telephony.default_network", null);
-        if (mode != null) {
+        if (mode != null && !mode.isEmpty()) {
             return TelephonyManager.getPhoneType(Integer.parseInt(mode));
         }
         return TelephonyManager.PHONE_TYPE_NONE;
@@ -4609,6 +4636,56 @@
         return new int[0];
     }
 
+    public static abstract class OnReceiveUssdResponseCallback {
+       /**
+        ** Called when USSD has succeeded.
+        **/
+       public void onReceiveUssdResponse(String request, CharSequence response) {};
+
+       /**
+        ** Called when USSD has failed.
+        **/
+       public void onReceiveUssdResponseFailed(String request, int failureCode) {};
+    }
+
+    /* <p>Requires permission:
+     * @link android.Manifest.permission#CALL_PHONE}
+     */
+    @RequiresPermission(android.Manifest.permission.CALL_PHONE)
+    public void sendUssdRequest(String ussdRequest,
+                                final OnReceiveUssdResponseCallback callback, Handler handler) {
+       checkNotNull(callback, "OnReceiveUssdResponseCallback cannot be null.");
+
+       ResultReceiver wrappedCallback = new ResultReceiver(handler) {
+           @Override
+           protected void onReceiveResult(int resultCode, Bundle ussdResponse) {
+              Rlog.d(TAG, "USSD:" + resultCode);
+              checkNotNull(ussdResponse, "ussdResponse cannot be null.");
+              UssdResponse response = ussdResponse.getParcelable(USSD_RESPONSE);
+
+              if (resultCode == USSD_RETURN_SUCCESS) {
+                 callback.onReceiveUssdResponse(response.getUssdRequest(),
+                         response.getReturnMessage());
+              } else {
+                 callback.onReceiveUssdResponseFailed(response.getUssdRequest(), resultCode);
+              }
+           }
+        };
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                telephony.handleUssdRequest(ussdRequest, wrappedCallback);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelephony#sendUSSDCode", e);
+            UssdResponse response = new UssdResponse(ussdRequest, "");
+            Bundle returnData = new Bundle();
+            returnData.putParcelable(USSD_RESPONSE, response);
+            wrappedCallback.send(USSD_ERROR_SERVICE_UNAVAIL, returnData);
+        }
+    }
+
     /** @hide */
     @SystemApi
     public boolean handlePinMmi(String dialString) {
diff --git a/telephony/java/android/telephony/UssdResponse.aidl b/telephony/java/android/telephony/UssdResponse.aidl
new file mode 100644
index 0000000..add28a0
--- /dev/null
+++ b/telephony/java/android/telephony/UssdResponse.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** 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.
+*/
+
+package android.telephony;
+
+parcelable UssdResponse;
diff --git a/telephony/java/android/telephony/UssdResponse.java b/telephony/java/android/telephony/UssdResponse.java
new file mode 100644
index 0000000..5df681d
--- /dev/null
+++ b/telephony/java/android/telephony/UssdResponse.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * Represents the Ussd response, including
+ * the message and the return code.
+ * @hide
+ */
+public final class UssdResponse implements Parcelable {
+    private CharSequence mReturnMessage;
+    private String mUssdRequest;
+
+
+    /**
+     * Implement the Parcelable interface
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mUssdRequest);
+        TextUtils.writeToParcel(mReturnMessage, dest, 0);
+    }
+
+    public String getUssdRequest() {
+        return mUssdRequest;
+    }
+
+    public CharSequence getReturnMessage() {
+        return mReturnMessage;
+    }
+
+    /**
+     * Implement the Parcelable interface
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * * Initialize the object from the request and return message.
+     */
+    public UssdResponse(String ussdRequest, CharSequence returnMessage) {
+        mUssdRequest = ussdRequest;
+        mReturnMessage = returnMessage;
+    }
+
+    public static final Parcelable.Creator<UssdResponse> CREATOR = new Creator<UssdResponse>() {
+
+        @Override
+        public UssdResponse createFromParcel(Parcel in) {
+            String request = in.readString();
+            CharSequence message = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+            return new UssdResponse(request, message);
+        }
+
+        @Override
+        public UssdResponse[] newArray(int size) {
+            return new UssdResponse[size];
+        }
+    };
+}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index c72b32a..4c66be1 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -271,6 +271,15 @@
      */
     boolean handlePinMmi(String dialString);
 
+
+    /**
+     * Handles USSD commands.
+     *
+     * @param ussdRequest the USSD command to be executed.
+     * @param wrappedCallback receives a callback result.
+     */
+    void handleUssdRequest(String ussdRequest, in ResultReceiver wrappedCallback);
+
     /**
      * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated
      * without SEND (so <code>dial</code> is not appropriate) for
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 16a0def..f5f7ea3 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -32,7 +32,6 @@
 import android.os.UserHandle;
 import android.app.UiAutomation;
 import android.app.IActivityManager;
-import android.app.IActivityManager.WaitResult;
 import android.support.test.rule.logging.AtraceLogger;
 import android.test.InstrumentationTestCase;
 import android.test.InstrumentationTestRunner;
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 97%
rename from services/tests/servicestests/src/android/net/ConnectivityMetricsLoggerTest.java
rename to tests/net/java/android/net/ConnectivityMetricsLoggerTest.java
index 6d42cce..f896030 100644
--- a/services/tests/servicestests/src/android/net/ConnectivityMetricsLoggerTest.java
+++ b/tests/net/java/android/net/ConnectivityMetricsLoggerTest.java
@@ -18,6 +18,7 @@
 
 import android.os.Bundle;
 import android.os.Parcel;
+import android.test.suitebuilder.annotation.SmallTest;
 import java.util.List;
 import junit.framework.TestCase;
 import org.mockito.ArgumentCaptor;
@@ -49,6 +50,7 @@
         mLog = new ConnectivityMetricsLogger(mService);
     }
 
+    @SmallTest
     public void testLogEvents() throws Exception {
         mLog.logEvent(1, FAKE_COMPONENT, FAKE_EVENT, FAKE_EV);
         mLog.logEvent(2, FAKE_COMPONENT, FAKE_EVENT, FAKE_EV);
@@ -60,6 +62,7 @@
         assertEventsEqual(expectedEvent(3), gotEvents.get(2));
     }
 
+    @SmallTest
     public void testLogEventTriggerThrottling() throws Exception {
         when(mService.logEvent(any())).thenReturn(1234L);
 
@@ -70,6 +73,7 @@
         assertEventsEqual(expectedEvent(1), gotEvents.get(0));
     }
 
+    @SmallTest
     public void testLogEventFails() throws Exception {
         when(mService.logEvent(any())).thenReturn(-1L); // Error.
 
@@ -80,6 +84,7 @@
         assertEventsEqual(expectedEvent(1), gotEvents.get(0));
     }
 
+    @SmallTest
     public void testLogEventWhenThrottling() throws Exception {
         when(mService.logEvent(any())).thenReturn(Long.MAX_VALUE); // Throttled
 
@@ -92,6 +97,7 @@
         assertEventsEqual(expectedEvent(1), gotEvents.get(0));
     }
 
+    @SmallTest
     public void testLogEventRecoverFromThrottling() throws Exception {
         final long throttleTimeout = System.currentTimeMillis() + 10;
         when(mService.logEvent(any())).thenReturn(throttleTimeout, 0L);
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 98%
rename from services/tests/servicestests/src/android/net/apf/ApfTest.java
rename to tests/net/java/android/net/apf/ApfTest.java
index 37807b2..51adfe7 100644
--- a/services/tests/servicestests/src/android/net/apf/ApfTest.java
+++ b/tests/net/java/android/net/apf/ApfTest.java
@@ -32,10 +32,10 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.SmallTest;
 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.
@@ -154,7 +154,7 @@
      * generating bytecode for that program and running it through the
      * interpreter to verify it functions correctly.
      */
-    @LargeTest
+    @SmallTest
     public void testApfInstructions() throws IllegalInstructionException {
         // Empty program should pass because having the program counter reach the
         // location immediately after the program indicates the packet should be
@@ -562,7 +562,7 @@
      * Generate some BPF programs, translate them to APF, then run APF and BPF programs
      * over packet traces and verify both programs filter out the same packets.
      */
-    @LargeTest
+    @SmallTest
     public void testApfAgainstBpf() throws Exception {
         String[] tcpdump_filters = new String[]{ "udp", "tcp", "icmp", "icmp6", "udp port 53",
                 "arp", "dst 239.255.255.250", "arp or tcp or udp port 53", "net 192.168.1.0/24",
@@ -720,7 +720,7 @@
     private static final byte[] ANOTHER_IPV4_ADDR        = {10, 0, 0, 2};
     private static final byte[] IPV4_ANY_HOST_ADDR       = {0, 0, 0, 0};
 
-    @LargeTest
+    @SmallTest
     public void testApfFilterIPv4() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
@@ -775,7 +775,7 @@
         apfFilter.shutdown();
     }
 
-    @LargeTest
+    @SmallTest
     public void testApfFilterIPv6() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog);
@@ -801,7 +801,7 @@
         apfFilter.shutdown();
     }
 
-    @LargeTest
+    @SmallTest
     public void testApfFilterMulticast() throws Exception {
         final byte[] unicastIpv4Addr   = {(byte)192,0,2,63};
         final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255};
@@ -911,7 +911,7 @@
         assertDrop(program, garpReply());
     }
 
-    @LargeTest
+    @SmallTest
     public void testApfFilterArp() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog);
@@ -1030,7 +1030,7 @@
         ipManagerCallback.assertNoProgramUpdate();
     }
 
-    @LargeTest
+    @SmallTest
     public void testApfFilterRa() throws Exception {
         MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
         TestApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog);
@@ -1147,6 +1147,7 @@
         buffer.position(original);
     }
 
+    @SmallTest
     public void testRaParsing() throws Exception {
         final int maxRandomPacketSize = 512;
         final Random r = new Random();
@@ -1164,6 +1165,7 @@
         }
     }
 
+    @SmallTest
     public void testRaProcessing() throws Exception {
         final int maxRandomPacketSize = 512;
         final Random r = new Random();
@@ -1201,6 +1203,7 @@
     private native static boolean compareBpfApf(String filter, String pcap_filename,
             byte[] apf_program);
 
+    @SmallTest
     public void testBytesToInt() {
         assertEquals(0x00000000, ApfFilter.bytesToInt(IPV4_ANY_HOST_ADDR));
         assertEquals(0xffffffff, ApfFilter.bytesToInt(IPV4_BROADCAST_ADDRESS));
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 99%
rename from services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
rename to tests/net/java/android/net/dhcp/DhcpPacketTest.java
index bc8baa1..d79c312 100644
--- a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
+++ b/tests/net/java/android/net/dhcp/DhcpPacketTest.java
@@ -473,6 +473,7 @@
         assertEquals(Integer.toHexString(expected), Integer.toHexString(got));
     }
 
+    @SmallTest
     public void testTruncatedOfferPackets() throws Exception {
         final byte[] packet = HexDump.hexStringToByteArray(
             // IP header.
@@ -506,6 +507,7 @@
         }
     }
 
+    @SmallTest
     public void testRandomPackets() throws Exception {
         final int maxRandomPacketSize = 512;
         final Random r = new Random();
diff --git a/services/tests/servicestests/src/android/net/netlink/NetlinkErrorMessageTest.java b/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
similarity index 97%
rename from services/tests/servicestests/src/android/net/netlink/NetlinkErrorMessageTest.java
rename to tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
index e677475..5deba27 100644
--- a/services/tests/servicestests/src/android/net/netlink/NetlinkErrorMessageTest.java
+++ b/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
@@ -24,6 +24,7 @@
 import android.net.netlink.NetlinkErrorMessage;
 import android.net.netlink.NetlinkMessage;
 import android.net.netlink.StructNlMsgErr;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
@@ -53,6 +54,7 @@
     public static final byte[] NLM_ERROR_OK =
             HexEncoding.decode(NLM_ERROR_OK_HEX.toCharArray(), false);
 
+    @SmallTest
     public void testParseNlmErrorOk() {
         final ByteBuffer byteBuffer = ByteBuffer.wrap(NLM_ERROR_OK);
         byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
diff --git a/services/tests/servicestests/src/android/net/netlink/NetlinkSocketTest.java b/tests/net/java/android/net/netlink/NetlinkSocketTest.java
similarity index 97%
rename from services/tests/servicestests/src/android/net/netlink/NetlinkSocketTest.java
rename to tests/net/java/android/net/netlink/NetlinkSocketTest.java
index c599fe3..78b3b70 100644
--- a/services/tests/servicestests/src/android/net/netlink/NetlinkSocketTest.java
+++ b/tests/net/java/android/net/netlink/NetlinkSocketTest.java
@@ -20,6 +20,7 @@
 import android.net.netlink.RtNetlinkNeighborMessage;
 import android.net.netlink.StructNdMsg;
 import android.net.netlink.StructNlMsgHdr;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.system.ErrnoException;
 import android.system.NetlinkSocketAddress;
 import android.system.OsConstants;
@@ -33,6 +34,7 @@
 public class NetlinkSocketTest extends TestCase {
     private final String TAG = "NetlinkSocketTest";
 
+    @SmallTest
     public void testBasicWorkingGetNeighborsQuery() throws Exception {
         NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
         assertNotNull(s);
@@ -91,6 +93,7 @@
         s.close();
     }
 
+    @SmallTest
     public void testRepeatedCloseCallsAreQuiet() throws Exception {
         // Create a working NetlinkSocket.
         NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
diff --git a/services/tests/servicestests/src/android/net/netlink/RtNetlinkNeighborMessageTest.java b/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
similarity index 98%
rename from services/tests/servicestests/src/android/net/netlink/RtNetlinkNeighborMessageTest.java
rename to tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
index 19ee000..029758e 100644
--- a/services/tests/servicestests/src/android/net/netlink/RtNetlinkNeighborMessageTest.java
+++ b/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
@@ -21,12 +21,13 @@
 import android.net.netlink.RtNetlinkNeighborMessage;
 import android.net.netlink.StructNdMsg;
 import android.net.netlink.StructNlMsgHdr;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.system.OsConstants;
 import android.util.Log;
 import libcore.util.HexEncoding;
 
-import java.net.InetAddress;
 import java.net.Inet4Address;
+import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
@@ -135,6 +136,7 @@
     public static final byte[] RTM_GETNEIGH_RESPONSE =
             HexEncoding.decode(RTM_GETNEIGH_RESPONSE_HEX.replaceAll(" ", "").toCharArray(), false);
 
+    @SmallTest
     public void testParseRtmDelNeigh() {
         final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_DELNEIGH);
         byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
@@ -161,6 +163,7 @@
         assertEquals(InetAddress.parseNumericAddress("192.168.159.254"), destination);
     }
 
+    @SmallTest
     public void testParseRtmNewNeigh() {
         final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_NEWNEIGH);
         byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
@@ -187,6 +190,7 @@
         assertEquals(InetAddress.parseNumericAddress("fe80::86c9:b2ff:fe6a:ed4b"), destination);
     }
 
+    @SmallTest
     public void testParseRtmGetNeighResponse() {
         final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_GETNEIGH_RESPONSE);
         byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
@@ -211,6 +215,7 @@
         assertEquals(14, messageCount);
     }
 
+    @SmallTest
     public void testCreateRtmNewNeighMessage() {
         final int seqNo = 2635;
         final int ifIndex = 14;
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 98%
rename from services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
rename to tests/net/java/com/android/server/ConnectivityServiceTest.java
index a921e8a..4a6fb13 100644
--- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -68,14 +68,15 @@
 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;
@@ -193,6 +194,7 @@
     }
 
     // Tests that IdleableHandlerThread works as expected.
+    @SmallTest
     public void testIdleableHandlerThread() {
         final int attempts = 50;  // Causes the test to take about 200ms on bullhead-eng.
 
@@ -215,8 +217,21 @@
             mService.waitForIdle();
             assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength());
         }
+    }
+
+    @SmallTest
+    @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()) {
@@ -828,7 +843,7 @@
         return cv;
     }
 
-    @LargeTest
+    @SmallTest
     public void testLingering() throws Exception {
         verifyNoNetwork();
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -868,7 +883,7 @@
         verifyNoNetwork();
     }
 
-    @LargeTest
+    @SmallTest
     public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception {
         // Test bringing up unvalidated WiFi
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -903,7 +918,7 @@
         verifyNoNetwork();
     }
 
-    @LargeTest
+    @SmallTest
     public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception {
         // Test bringing up unvalidated cellular.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -929,7 +944,7 @@
         verifyNoNetwork();
     }
 
-    @LargeTest
+    @SmallTest
     public void testUnlingeringDoesNotValidate() throws Exception {
         // Test bringing up unvalidated WiFi.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -957,7 +972,7 @@
                 NET_CAPABILITY_VALIDATED));
     }
 
-    @LargeTest
+    @SmallTest
     public void testCellularOutscoresWeakWifi() throws Exception {
         // Test bringing up validated cellular.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -983,7 +998,7 @@
         verifyActiveNetwork(TRANSPORT_WIFI);
     }
 
-    @LargeTest
+    @SmallTest
     public void testReapingNetwork() throws Exception {
         // Test bringing up WiFi without NET_CAPABILITY_INTERNET.
         // Expect it to be torn down immediately because it satisfies no requests.
@@ -1016,7 +1031,7 @@
         waitFor(cv);
     }
 
-    @LargeTest
+    @SmallTest
     public void testCellularFallback() throws Exception {
         // Test bringing up validated cellular.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1054,7 +1069,7 @@
         verifyActiveNetwork(TRANSPORT_WIFI);
     }
 
-    @LargeTest
+    @SmallTest
     public void testWiFiFallback() throws Exception {
         // Test bringing up unvalidated WiFi.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -1181,7 +1196,7 @@
         }
     }
 
-    @LargeTest
+    @SmallTest
     public void testStateChangeNetworkCallbacks() throws Exception {
         final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
         final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
@@ -1564,7 +1579,7 @@
         handlerThread.quit();
     }
 
-    @LargeTest
+    @SmallTest
     public void testNetworkFactoryRequests() throws Exception {
         tryNetworkFactoryRequests(NET_CAPABILITY_MMS);
         tryNetworkFactoryRequests(NET_CAPABILITY_SUPL);
@@ -1584,7 +1599,7 @@
         // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed.
     }
 
-    @LargeTest
+    @SmallTest
     public void testNoMutableNetworkRequests() throws Exception {
         PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0);
         NetworkRequest.Builder builder = new NetworkRequest.Builder();
@@ -1609,7 +1624,7 @@
         } catch (IllegalArgumentException expected) {}
     }
 
-    @LargeTest
+    @SmallTest
     public void testMMSonWiFi() throws Exception {
         // Test bringing up cellular without MMS NetworkRequest gets reaped
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1644,7 +1659,7 @@
         verifyActiveNetwork(TRANSPORT_WIFI);
     }
 
-    @LargeTest
+    @SmallTest
     public void testMMSonCell() throws Exception {
         // Test bringing up cellular without MMS
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1670,7 +1685,7 @@
         verifyActiveNetwork(TRANSPORT_CELLULAR);
     }
 
-    @LargeTest
+    @SmallTest
     public void testCaptivePortal() {
         final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
         final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
@@ -1719,7 +1734,7 @@
         validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
     }
 
-    @LargeTest
+    @SmallTest
     public void testAvoidOrIgnoreCaptivePortals() {
         final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
         final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
@@ -1790,7 +1805,7 @@
                 execptionCalled);
     }
 
-    @LargeTest
+    @SmallTest
     public void testRegisterDefaultNetworkCallback() throws Exception {
         final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
         mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
@@ -1851,7 +1866,7 @@
         }
     }
 
-    @LargeTest
+    @SmallTest
     public void testRequestCallbackUpdates() throws Exception {
         // File a network request for mobile.
         final TestNetworkCallback cellNetworkCallback = new TestRequestUpdateCallback();
@@ -2444,6 +2459,7 @@
         return mWiFiNetworkAgent.getNetwork();
     }
 
+    @SmallTest
     public void testPacketKeepalives() throws Exception {
         InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
         InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35");
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 97%
rename from services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
rename to tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
index 84f0f90..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 {
 
@@ -351,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 97%
rename from services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java
rename to tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index aa491bb..c7982b1 100644
--- a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -16,6 +16,9 @@
 
 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;
@@ -30,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 =
@@ -254,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 97%
rename from services/tests/servicestests/src/com/android/server/connectivity/LingerMonitorTest.java
rename to tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index bce5787e..77956be 100644
--- a/services/tests/servicestests/src/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -24,6 +24,7 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.net.NetworkMisc;
+import android.test.suitebuilder.annotation.SmallTest;
 import android.text.format.DateUtils;
 import com.android.internal.R;
 import com.android.server.ConnectivityService;
@@ -70,6 +71,7 @@
         mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, HIGH_RATE_LIMIT);
     }
 
+    @SmallTest
     public void testTransitions() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         NetworkAgentInfo nai1 = wifiNai(100);
@@ -79,6 +81,7 @@
         assertFalse(mMonitor.isNotificationEnabled(nai2, nai1));
     }
 
+    @SmallTest
     public void testNotificationOnLinger() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -89,6 +92,7 @@
         verifyNotification(from, to);
     }
 
+    @SmallTest
     public void testToastOnLinger() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
@@ -99,6 +103,7 @@
         verifyToast(from, to);
     }
 
+    @SmallTest
     public void testNotificationClearedAfterDisconnect() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -112,6 +117,7 @@
         verify(mNotifier, times(1)).clearNotification(100);
     }
 
+    @SmallTest
     public void testNotificationClearedAfterSwitchingBack() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -125,6 +131,7 @@
         verify(mNotifier, times(1)).clearNotification(100);
     }
 
+    @SmallTest
     public void testUniqueToast() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
@@ -142,6 +149,7 @@
         verifyNoNotifications();
     }
 
+    @SmallTest
     public void testMultipleNotifications() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -160,6 +168,7 @@
         verifyNotification(wifi2, cell);
     }
 
+    @SmallTest
     public void testRateLimiting() throws InterruptedException {
         mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, LOW_RATE_LIMIT);
 
@@ -185,6 +194,7 @@
         verifyNoNotifications();
     }
 
+    @SmallTest
     public void testDailyLimiting() throws InterruptedException {
         mMonitor = new TestableLingerMonitor(mCtx, mNotifier, LOW_DAILY_LIMIT, HIGH_RATE_LIMIT);
 
@@ -211,6 +221,7 @@
         verifyNoNotifications();
     }
 
+    @SmallTest
     public void testUniqueNotification() {
         setNotificationSwitch(transition(WIFI, CELLULAR));
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -227,6 +238,7 @@
         verifyNotification(from, to);
     }
 
+    @SmallTest
     public void testIgnoreNeverValidatedNetworks() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
         setNotificationSwitch(transition(WIFI, CELLULAR));
@@ -238,6 +250,7 @@
         verifyNoNotifications();
     }
 
+    @SmallTest
     public void testIgnoreCurrentlyValidatedNetworks() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
         setNotificationSwitch(transition(WIFI, CELLULAR));
@@ -249,6 +262,7 @@
         verifyNoNotifications();
     }
 
+    @SmallTest
     public void testNoNotificationType() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
         setNotificationSwitch();
@@ -259,6 +273,7 @@
         verifyNoNotifications();
     }
 
+    @SmallTest
     public void testNoTransitionToNotify() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_NONE);
         setNotificationSwitch(transition(WIFI, CELLULAR));
@@ -269,6 +284,7 @@
         verifyNoNotifications();
     }
 
+    @SmallTest
     public void testDifferentTransitionToNotify() {
         setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
         setNotificationSwitch(transition(CELLULAR, WIFI));
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 97%
rename from services/tests/servicestests/src/com/android/server/connectivity/MetricsLoggerServiceTest.java
rename to tests/net/java/com/android/server/connectivity/MetricsLoggerServiceTest.java
index 5f84ea1..5981f48 100644
--- a/services/tests/servicestests/src/com/android/server/connectivity/MetricsLoggerServiceTest.java
+++ b/tests/net/java/com/android/server/connectivity/MetricsLoggerServiceTest.java
@@ -20,6 +20,7 @@
 import android.net.ConnectivityMetricsEvent;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.test.suitebuilder.annotation.SmallTest;
 import static android.net.ConnectivityMetricsEvent.Reference;
 
 import junit.framework.TestCase;
@@ -67,12 +68,14 @@
         mService.onStart();
     }
 
+    @SmallTest
     public void testGetNoEvents() throws Exception {
         Reference r = new Reference(0);
         assertArrayEquals(NO_EVENTS, mService.mBinder.getEvents(r));
         assertEquals(0, r.getValue());
     }
 
+    @SmallTest
     public void testLogAndGetEvents() throws Exception {
         mService.mBinder.logEvents(EVENTS);
 
@@ -85,6 +88,7 @@
         assertEquals(N_EVENTS, r.getValue());
     }
 
+    @SmallTest
     public void testLogOneByOne() throws Exception {
         for (ConnectivityMetricsEvent ev : EVENTS) {
             mService.mBinder.logEvent(ev);
@@ -99,6 +103,7 @@
         assertEquals(N_EVENTS, r.getValue());
     }
 
+    @SmallTest
     public void testInterleavedLogAndGet() throws Exception {
         mService.mBinder.logEvents(Arrays.copyOfRange(EVENTS, 0, 3));
 
@@ -117,6 +122,7 @@
         assertEquals(N_EVENTS, r.getValue());
     }
 
+    @SmallTest
     public void testMultipleGetAll() throws Exception {
         mService.mBinder.logEvents(Arrays.copyOf(EVENTS, 3));
 
@@ -131,6 +137,7 @@
         assertEquals(N_EVENTS, r2.getValue());
     }
 
+    @SmallTest
     public void testLogAndDumpConcurrently() throws Exception {
         for (int i = 0; i < 50; i++) {
             mContext = null;
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 93%
rename from services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java
rename to tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
index 9e2fd62..2bb62bb 100644
--- a/services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
@@ -22,6 +22,8 @@
 import android.net.metrics.DnsEvent;
 import android.net.metrics.INetdEventListener;
 import android.net.metrics.IpConnectivityLog;
+import android.os.RemoteException;
+import android.test.suitebuilder.annotation.SmallTest;
 
 import junit.framework.TestCase;
 import org.junit.Before;
@@ -82,6 +84,7 @@
         verify(mCm, times(1)).registerNetworkCallback(any(), mCallbackCaptor.capture());
     }
 
+    @SmallTest
     public void testOneBatch() throws Exception {
         log(105, LATENCIES);
         log(106, Arrays.copyOf(LATENCIES, BATCH_SIZE - 1)); // one lookup short of a batch event
@@ -96,6 +99,7 @@
             new DnsEvent(106, EVENT_TYPES, RETURN_CODES, LATENCIES));
     }
 
+    @SmallTest
     public void testSeveralBatches() throws Exception {
         log(105, LATENCIES);
         log(106, LATENCIES);
@@ -109,6 +113,7 @@
             new DnsEvent(107, EVENT_TYPES, RETURN_CODES, LATENCIES));
     }
 
+    @SmallTest
     public void testBatchAndNetworkLost() throws Exception {
         byte[] eventTypes = Arrays.copyOf(EVENT_TYPES, 20);
         byte[] returnCodes = Arrays.copyOf(RETURN_CODES, 20);
@@ -125,6 +130,7 @@
             new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES));
     }
 
+    @SmallTest
     public void testConcurrentBatchesAndDumps() throws Exception {
         final long stop = System.currentTimeMillis() + 100;
         final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null"));
@@ -146,6 +152,7 @@
             new DnsEvent(107, EVENT_TYPES, RETURN_CODES, LATENCIES));
     }
 
+    @SmallTest
     public void testConcurrentBatchesAndNetworkLoss() throws Exception {
         logAsync(105, LATENCIES);
         Thread.sleep(10L);
@@ -157,9 +164,13 @@
     }
 
     void log(int netId, int[] latencies) {
-        for (int l : latencies) {
-            mNetdEventListenerService.onDnsEvent(netId, EVENT_TYPE, RETURN_CODE, l, null, null, 0,
-                    0);
+        try {
+            for (int l : latencies) {
+                mNetdEventListenerService.onDnsEvent(netId, EVENT_TYPE, RETURN_CODE, l, null, null,
+                        0, 0);
+            }
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
         }
     }
 
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..7d6f32b 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.
@@ -72,7 +73,7 @@
         }
 
         try {
-            mWm.addWindowToken(null, 0);
+            mWm.addWindowToken(null, 0, DEFAULT_DISPLAY);
             fail("IWindowManager.addWindowToken did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {
@@ -82,7 +83,7 @@
         }
 
         try {
-            mWm.removeWindowToken(null);
+            mWm.removeWindowToken(null, DEFAULT_DISPLAY);
             fail("IWindowManager.removeWindowToken did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {
@@ -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) {
@@ -124,7 +126,7 @@
 
         try {
             mWm.setAppOrientation(null, 0);
-            mWm.addWindowToken(null, 0);
+            mWm.addWindowToken(null, 0, DEFAULT_DISPLAY);
             fail("IWindowManager.setAppOrientation did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {
@@ -204,7 +206,7 @@
         }
 
         try {
-            mWm.removeAppToken(null);
+            mWm.removeAppToken(null, DEFAULT_DISPLAY);
             fail("IWindowManager.removeAppToken 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/aapt/Command.cpp b/tools/aapt/Command.cpp
index 9b62e14..2e34197 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -803,7 +803,7 @@
             ResXMLTree tree(dynamicRefTable);
             asset = assets.openNonAsset(assetsCookie, resname, Asset::ACCESS_BUFFER);
             if (asset == NULL) {
-                fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname);
+                fprintf(stderr, "ERROR: dump failed because resource %s not found\n", resname);
                 goto bail;
             }
 
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 284c787..1efd2ed 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -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,14 +194,14 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := libaapt2_jni
 LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-LOCAL_MODULE_HOST_OS := darwin linux
+LOCAL_MODULE_HOST_OS := darwin linux windows
 LOCAL_CFLAGS := $(cFlags)
 LOCAL_CFLAGS_darwin := $(cFlags_darwin)
 LOCAL_CFLAGS_windows := $(cFlags_windows)
 LOCAL_CPPFLAGS := $(cppFlags)
 LOCAL_C_INCLUDES := $(protoIncludes)
 LOCAL_SRC_FILES := $(toolSources) $(sourcesJni)
-LOCAL_STATIC_LIBRARIES := libaapt2 libnativehelper $(hostStaticLibs)
+LOCAL_STATIC_LIBRARIES := libaapt2 $(hostStaticLibs)
 LOCAL_STATIC_LIBRARIES_windows := $(hostStaticLibs_windows)
 LOCAL_LDLIBS := $(hostLdLibs)
 LOCAL_LDLIBS_darwin := $(hostLdLibs_darwin)
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 7d50e1d..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,362 +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(StringPool::Context::kStylePriority, 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(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(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;
   }
@@ -889,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;
     }
 
@@ -963,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;
     }
   }
@@ -1099,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;
     }
   }
@@ -1174,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;
     }
   }
@@ -1253,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;
@@ -1302,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;
     }
 
@@ -1346,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 6e0d646..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 {
@@ -72,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;
@@ -95,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 {
@@ -116,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 {
@@ -134,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;
@@ -149,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 2ea63d0..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) {
+  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 b1536d5..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
deleted file mode 100644
index aed23de..0000000
--- a/tools/aapt2/jni/Aapt2.java
+++ /dev/null
@@ -1,44 +0,0 @@
-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
deleted file mode 100644
index a9e628f..0000000
--- a/tools/aapt2/jni/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# 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/ScopedUtfChars.h b/tools/aapt2/jni/ScopedUtfChars.h
new file mode 100644
index 0000000..a8c4b13
--- /dev/null
+++ b/tools/aapt2/jni/ScopedUtfChars.h
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+#ifndef SCOPED_UTF_CHARS_H_included
+#define SCOPED_UTF_CHARS_H_included
+
+#include <string.h>
+#include <jni.h>
+
+#include "android-base/logging.h"
+
+// This file was copied with some minor modifications from libnativehelper.
+// As soon as libnativehelper can be compiled for Windows, this file should be
+// replaced with libnativehelper's implementation.
+class ScopedUtfChars {
+ public:
+  ScopedUtfChars(JNIEnv* env, jstring s) : env_(env), string_(s) {
+    CHECK(s != nullptr);
+    utf_chars_ = env->GetStringUTFChars(s, nullptr);
+  }
+
+  ScopedUtfChars(ScopedUtfChars&& rhs) :
+      env_(rhs.env_), string_(rhs.string_), utf_chars_(rhs.utf_chars_) {
+    rhs.env_ = nullptr;
+    rhs.string_ = nullptr;
+    rhs.utf_chars_ = nullptr;
+  }
+
+  ~ScopedUtfChars() {
+    if (utf_chars_) {
+      env_->ReleaseStringUTFChars(string_, utf_chars_);
+    }
+  }
+
+  ScopedUtfChars& operator=(ScopedUtfChars&& rhs) {
+    if (this != &rhs) {
+      // Delete the currently owned UTF chars.
+      this->~ScopedUtfChars();
+
+      // Move the rhs ScopedUtfChars and zero it out.
+      env_ = rhs.env_;
+      string_ = rhs.string_;
+      utf_chars_ = rhs.utf_chars_;
+      rhs.env_ = nullptr;
+      rhs.string_ = nullptr;
+      rhs.utf_chars_ = nullptr;
+    }
+    return *this;
+  }
+
+  const char* c_str() const {
+    return utf_chars_;
+  }
+
+  size_t size() const {
+    return strlen(utf_chars_);
+  }
+
+  const char& operator[](size_t n) const {
+    return utf_chars_[n];
+  }
+
+ private:
+  JNIEnv* env_;
+  jstring string_;
+  const char* utf_chars_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedUtfChars);
+};
+
+#endif  // SCOPED_UTF_CHARS_H_included
diff --git a/tools/aapt2/jni/aapt2_jni.cpp b/tools/aapt2/jni/aapt2_jni.cpp
index dff77b9..5518fe2 100644
--- a/tools/aapt2/jni/aapt2_jni.cpp
+++ b/tools/aapt2/jni/aapt2_jni.cpp
@@ -14,84 +14,86 @@
  * limitations under the License.
  */
 
+#include "com_android_tools_aapt2_Aapt2Jni.h"
+
 #include <algorithm>
-#include <cassert>
 #include <memory>
 #include <utility>
 #include <vector>
 
-#include <ScopedUtfChars.h>
+#include "android-base/logging.h"
+#include "ScopedUtfChars.h"
 
 #include "util/Util.h"
 
-#include "com_android_tools_aapt2_Aapt2.h"
-
 namespace aapt {
-    extern int compile(const std::vector<StringPiece>& args);
-    extern int link(const std::vector<StringPiece>& args);
+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;
+  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");
-    assert(size_method_id != 0);
-    jint size = env->CallIntMethod(obj, size_method_id);
-    assert(size >= 0);
+  // 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);
-        assert(string_obj_uncast != nullptr);
-        jstring string_obj = static_cast<jstring>(string_obj_uncast);
-        converted.push_back(ScopedUtfChars(env, string_obj));
-    }
+  // Now, iterate all strings in the list
+  // (note: generic erasure means get() return an Object)
+  jmethodID get_method_id = env->GetMethodID(list_cls, "get", "(I)Ljava/lang/Object;");
+  CHECK(get_method_id != 0);
+  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;
+  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;
+    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_Aapt2Jni_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);
+JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_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);
+}
+
+JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_ping(
+        JNIEnv *env, jclass aapt_obj) {
+  // This is just a dummy method to see if the library has been loaded.
 }
diff --git a/tools/aapt2/jni/com_android_tools_aapt2_Aapt2.h b/tools/aapt2/jni/com_android_tools_aapt2_Aapt2.h
deleted file mode 100644
index 443b98f..0000000
--- a/tools/aapt2/jni/com_android_tools_aapt2_Aapt2.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* 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/jni/com_android_tools_aapt2_Aapt2Jni.h b/tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h
new file mode 100644
index 0000000..56c3c18
--- /dev/null
+++ b/tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h
@@ -0,0 +1,37 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_android_tools_aapt2_Aapt2Jni */
+
+#ifndef _Included_com_android_tools_aapt2_Aapt2Jni
+#define _Included_com_android_tools_aapt2_Aapt2Jni
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     com_android_tools_aapt2_Aapt2Jni
+ * Method:    ping
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_ping
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     com_android_tools_aapt2_Aapt2Jni
+ * Method:    nativeCompile
+ * Signature: (Ljava/util/List;)V
+ */
+JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeCompile
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     com_android_tools_aapt2_Aapt2Jni
+ * Method:    nativeLink
+ * Signature: (Ljava/util/List;)V
+ */
+JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_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 6dd34e3..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,63 +1248,63 @@
    * 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::stringEndsWith(src.path, ".xml") ||
-               util::stringEndsWith(src.path, ".png")) {
+    } 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 fileType =
-          util::stringEndsWith(src.path, ".xml") ? "XML" : "PNG";
-      mContext->getDiagnostics()->error(DiagMessage(src)
-                                        << "uncompiled " << fileType
+      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;
@@ -1318,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;
       }
@@ -1414,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;
         }
       }
@@ -1533,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 {
@@ -1615,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;
     }
@@ -1692,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;
           }
         }
@@ -1730,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 0dfb01c..d93d495 100644
--- a/tools/aapt2/proto/TableProtoDeserializer.cpp
+++ b/tools/aapt2/proto/TableProtoDeserializer.cpp
@@ -14,13 +14,15 @@
  * 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 {
 
@@ -28,28 +30,28 @@
 
 class ReferenceIdToNameVisitor : public ValueVisitor {
  public:
-  using ValueVisitor::visit;
+  using ValueVisitor::Visit;
 
   explicit ReferenceIdToNameVisitor(
       const std::map<ResourceId, ResourceNameRef>* mapping)
-      : mMapping(mapping) {
-    assert(mMapping);
+      : mapping_(mapping) {
+    CHECK(mapping_ != nullptr);
   }
 
-  void visit(Reference* reference) override {
-    if (!reference->id || !reference->id.value().isValid()) {
+  void Visit(Reference* reference) override {
+    if (!reference->id || !reference->id.value().is_valid()) {
       return;
     }
 
     ResourceId id = reference->id.value();
-    auto cacheIter = mMapping->find(id);
-    if (cacheIter != mMapping->end()) {
-      reference->name = cacheIter->second.toResourceName();
+    auto cache_iter = mapping_->find(id);
+    if (cache_iter != mapping_->end()) {
+      reference->name = cache_iter->second.ToResourceName();
     }
   }
 
  private:
-  const std::map<ResourceId, ResourceNameRef>* mMapping;
+  const std::map<ResourceId, ResourceNameRef>* mapping_;
 };
 
 class PackagePbDeserializer {
@@ -58,14 +60,14 @@
                         const android::ResStringPool* sourcePool,
                         const android::ResStringPool* symbolPool,
                         const Source& source, IDiagnostics* diag)
-      : mValuePool(valuePool),
-        mSourcePool(sourcePool),
-        mSymbolPool(symbolPool),
-        mSource(source),
-        mDiag(diag) {}
+      : value_pool_(valuePool),
+        source_pool_(sourcePool),
+        symbol_pool_(symbolPool),
+        source_(source),
+        diag_(diag) {}
 
  public:
-  bool deserializeFromPb(const pb::Package& pbPackage, ResourceTable* table) {
+  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());
@@ -74,36 +76,36 @@
     std::map<ResourceId, ResourceNameRef> idIndex;
 
     ResourceTablePackage* pkg =
-        table->createPackage(pbPackage.package_name(), id);
+        table->CreatePackage(pbPackage.package_name(), id);
     for (const pb::Type& pbType : pbPackage.types()) {
-      const ResourceType* resType = parseResourceType(pbType.name());
+      const ResourceType* resType = ParseResourceType(pbType.name());
       if (!resType) {
-        mDiag->error(DiagMessage(mSource) << "unknown type '" << pbType.name()
+        diag_->Error(DiagMessage(source_) << "unknown type '" << pbType.name()
                                           << "'");
         return {};
       }
 
-      ResourceTableType* type = pkg->findOrCreateType(*resType);
+      ResourceTableType* type = pkg->FindOrCreateType(*resType);
 
       for (const pb::Entry& pbEntry : pbType.entries()) {
-        ResourceEntry* entry = type->findOrCreateEntry(pbEntry.name());
+        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);
+            DeserializeSourceFromPb(pbStatus.source(), *source_pool_,
+                                    &entry->symbol_status.source);
           }
 
           if (pbStatus.has_comment()) {
-            entry->symbolStatus.comment = pbStatus.comment();
+            entry->symbol_status.comment = pbStatus.comment();
           }
 
           SymbolState visibility =
-              deserializeVisibilityFromPb(pbStatus.visibility());
-          entry->symbolStatus.state = 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
@@ -112,22 +114,22 @@
               entry->id = static_cast<uint16_t>(pbEntry.id());
             }
 
-            if (type->symbolStatus.state != SymbolState::kPublic) {
+            if (type->symbol_status.state != SymbolState::kPublic) {
               // If the type has not been made public, do so now.
-              type->symbolStatus.state = SymbolState::kPublic;
+              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->symbolStatus.state == SymbolState::kUndefined) {
-              type->symbolStatus.state = SymbolState::kPrivate;
+            if (type->symbol_status.state == SymbolState::kUndefined) {
+              type->symbol_status.state = SymbolState::kPrivate;
             }
           }
         }
 
         ResourceId resId(pbPackage.package_id(), pbType.id(), pbEntry.id());
-        if (resId.isValid()) {
+        if (resId.is_valid()) {
           idIndex[resId] = ResourceNameRef(pkg->name, type->type, entry->name);
         }
 
@@ -135,21 +137,21 @@
           const pb::ConfigDescription& pbConfig = pbConfigValue.config();
 
           ConfigDescription config;
-          if (!deserializeConfigDescriptionFromPb(pbConfig, &config)) {
-            mDiag->error(DiagMessage(mSource) << "invalid configuration");
+          if (!DeserializeConfigDescriptionFromPb(pbConfig, &config)) {
+            diag_->Error(DiagMessage(source_) << "invalid configuration");
             return {};
           }
 
           ResourceConfigValue* configValue =
-              entry->findOrCreateValue(config, pbConfig.product());
+              entry->FindOrCreateValue(config, pbConfig.product());
           if (configValue->value) {
             // Duplicate config.
-            mDiag->error(DiagMessage(mSource) << "duplicate configuration");
+            diag_->Error(DiagMessage(source_) << "duplicate configuration");
             return {};
           }
 
-          configValue->value = deserializeValueFromPb(
-              pbConfigValue.value(), config, &table->stringPool);
+          configValue->value = DeserializeValueFromPb(
+              pbConfigValue.value(), config, &table->string_pool);
           if (!configValue->value) {
             return {};
           }
@@ -158,247 +160,247 @@
     }
 
     ReferenceIdToNameVisitor visitor(&idIndex);
-    visitAllValuesInPackage(pkg, &visitor);
+    VisitAllValuesInPackage(pkg, &visitor);
     return true;
   }
 
  private:
-  std::unique_ptr<Item> deserializeItemFromPb(const pb::Item& pbItem,
+  std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item,
                                               const ConfigDescription& config,
                                               StringPool* pool) {
-    if (pbItem.has_ref()) {
-      const pb::Reference& pbRef = pbItem.ref();
+    if (pb_item.has_ref()) {
+      const pb::Reference& pb_ref = pb_item.ref();
       std::unique_ptr<Reference> ref = util::make_unique<Reference>();
-      if (!deserializeReferenceFromPb(pbRef, ref.get())) {
+      if (!DeserializeReferenceFromPb(pb_ref, ref.get())) {
         return {};
       }
       return std::move(ref);
 
-    } else if (pbItem.has_prim()) {
-      const pb::Primitive& pbPrim = pbItem.prim();
+    } else if (pb_item.has_prim()) {
+      const pb::Primitive& pb_prim = pb_item.prim();
       android::Res_value prim = {};
-      prim.dataType = static_cast<uint8_t>(pbPrim.type());
-      prim.data = pbPrim.data();
+      prim.dataType = static_cast<uint8_t>(pb_prim.type());
+      prim.data = pb_prim.data();
       return util::make_unique<BinaryPrimitive>(prim);
 
-    } else if (pbItem.has_id()) {
+    } else if (pb_item.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);
+    } 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 = mValuePool->styleAt(idx);
+      const android::ResStringPool_span* spans = value_pool_->styleAt(idx);
       if (spans && spans->name.index != android::ResStringPool_span::END) {
-        StyleString styleStr = {str};
+        StyleString style_str = {str};
         while (spans->name.index != android::ResStringPool_span::END) {
-          styleStr.spans.push_back(
-              Span{util::getString(*mValuePool, spans->name.index),
+          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(
-            styleStr,
+        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)));
+          pool->MakeRef(str, StringPool::Context(config)));
 
-    } else if (pbItem.has_raw_str()) {
-      const uint32_t idx = pbItem.raw_str().idx();
-      const std::string str = util::getString(*mValuePool, idx);
+    } 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)));
+          pool->MakeRef(str, StringPool::Context(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(
+    } 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 {
-      mDiag->error(DiagMessage(mSource) << "unknown item");
+      diag_->Error(DiagMessage(source_) << "unknown item");
     }
     return {};
   }
 
-  std::unique_ptr<Value> deserializeValueFromPb(const pb::Value& pbValue,
+  std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value,
                                                 const ConfigDescription& config,
                                                 StringPool* pool) {
-    const bool isWeak = pbValue.has_weak() ? pbValue.weak() : false;
+    const bool is_weak = pb_value.has_weak() ? pb_value.weak() : false;
 
     std::unique_ptr<Value> value;
-    if (pbValue.has_item()) {
-      value = deserializeItemFromPb(pbValue.item(), config, pool);
+    if (pb_value.has_item()) {
+      value = DeserializeItemFromPb(pb_value.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()) {
+    } 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(pbSymbol, &symbol.symbol);
-          if (!deserializeReferenceFromPb(pbSymbol.name(), &symbol.symbol)) {
+          DeserializeItemCommon(pb_symbol, &symbol.symbol);
+          if (!DeserializeReferenceFromPb(pb_symbol.name(), &symbol.symbol)) {
             return {};
           }
-          symbol.value = pbSymbol.value();
+          symbol.value = pb_symbol.value();
           attr->symbols.push_back(std::move(symbol));
         }
         value = std::move(attr);
 
-      } else if (pbCompoundValue.has_style()) {
-        const pb::Style& pbStyle = pbCompoundValue.style();
+      } 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 (pbStyle.has_parent()) {
+        if (pb_style.has_parent()) {
           style->parent = Reference();
-          if (!deserializeReferenceFromPb(pbStyle.parent(),
+          if (!DeserializeReferenceFromPb(pb_style.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));
+          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));
           }
         }
 
-        for (const pb::Style_Entry& pbEntry : pbStyle.entries()) {
+        for (const pb::Style_Entry& pb_entry : pb_style.entries()) {
           Style::Entry entry;
-          deserializeItemCommon(pbEntry, &entry.key);
-          if (!deserializeReferenceFromPb(pbEntry.key(), &entry.key)) {
+          DeserializeItemCommon(pb_entry, &entry.key);
+          if (!DeserializeReferenceFromPb(pb_entry.key(), &entry.key)) {
             return {};
           }
 
-          entry.value = deserializeItemFromPb(pbEntry.item(), config, pool);
+          entry.value = DeserializeItemFromPb(pb_entry.item(), config, pool);
           if (!entry.value) {
             return {};
           }
 
-          deserializeItemCommon(pbEntry, entry.value.get());
+          DeserializeItemCommon(pb_entry, 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();
+      } 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& pbEntry : pbStyleable.entries()) {
-          Reference attrRef;
-          deserializeItemCommon(pbEntry, &attrRef);
-          deserializeReferenceFromPb(pbEntry.attr(), &attrRef);
-          styleable->entries.push_back(std::move(attrRef));
+        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 (pbCompoundValue.has_array()) {
-        const pb::Array& pbArray = pbCompoundValue.array();
+      } 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& pbEntry : pbArray.entries()) {
+        for (const pb::Array_Entry& pb_entry : pb_array.entries()) {
           std::unique_ptr<Item> item =
-              deserializeItemFromPb(pbEntry.item(), config, pool);
+              DeserializeItemFromPb(pb_entry.item(), config, pool);
           if (!item) {
             return {};
           }
 
-          deserializeItemCommon(pbEntry, item.get());
+          DeserializeItemCommon(pb_entry, item.get());
           array->items.push_back(std::move(item));
         }
         value = std::move(array);
 
-      } else if (pbCompoundValue.has_plural()) {
-        const pb::Plural& pbPlural = pbCompoundValue.plural();
+      } 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& pbEntry : pbPlural.entries()) {
-          size_t pluralIdx = deserializePluralEnumFromPb(pbEntry.arity());
+        for (const pb::Plural_Entry& pb_entry : pb_plural.entries()) {
+          size_t pluralIdx = DeserializePluralEnumFromPb(pb_entry.arity());
           plural->values[pluralIdx] =
-              deserializeItemFromPb(pbEntry.item(), config, pool);
+              DeserializeItemFromPb(pb_entry.item(), config, pool);
           if (!plural->values[pluralIdx]) {
             return {};
           }
 
-          deserializeItemCommon(pbEntry, plural->values[pluralIdx].get());
+          DeserializeItemCommon(pb_entry, plural->values[pluralIdx].get());
         }
         value = std::move(plural);
 
       } else {
-        mDiag->error(DiagMessage(mSource) << "unknown compound value");
+        diag_->Error(DiagMessage(source_) << "unknown compound value");
         return {};
       }
     } else {
-      mDiag->error(DiagMessage(mSource) << "unknown value");
+      diag_->Error(DiagMessage(source_) << "unknown value");
       return {};
     }
 
-    assert(value && "forgot to set value");
+    CHECK(value) << "forgot to set value";
 
-    value->setWeak(isWeak);
-    deserializeItemCommon(pbValue, value.get());
+    value->SetWeak(is_weak);
+    DeserializeItemCommon(pb_value, value.get());
     return value;
   }
 
-  bool deserializeReferenceFromPb(const pb::Reference& pbRef,
-                                  Reference* outRef) {
-    outRef->referenceType = deserializeReferenceTypeFromPb(pbRef.type());
-    outRef->privateReference = pbRef.private_();
+  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_id() && !pbRef.has_symbol_idx()) {
+    if (!pb_ref.has_id() && !pb_ref.has_symbol_idx()) {
       return false;
     }
 
-    if (pbRef.has_id()) {
-      outRef->id = ResourceId(pbRef.id());
+    if (pb_ref.has_id()) {
+      out_ref->id = ResourceId(pb_ref.id());
     }
 
-    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 << "'");
+    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;
       }
 
-      outRef->name = nameRef.toResourceName();
+      out_ref->name = name_ref.ToResourceName();
     }
     return true;
   }
 
   template <typename T>
-  void deserializeItemCommon(const T& pbItem, Value* outValue) {
-    if (pbItem.has_source()) {
+  void DeserializeItemCommon(const T& pb_item, Value* out_value) {
+    if (pb_item.has_source()) {
       Source source;
-      deserializeSourceFromPb(pbItem.source(), *mSourcePool, &source);
-      outValue->setSource(std::move(source));
+      DeserializeSourceFromPb(pb_item.source(), *source_pool_, &source);
+      out_value->SetSource(std::move(source));
     }
 
-    if (pbItem.has_comment()) {
-      outValue->setComment(pbItem.comment());
+    if (pb_item.has_comment()) {
+      out_value->SetComment(pb_item.comment());
     }
   }
 
  private:
-  const android::ResStringPool* mValuePool;
-  const android::ResStringPool* mSourcePool;
-  const android::ResStringPool* mSymbolPool;
-  const Source mSource;
-  IDiagnostics* mDiag;
+  const android::ResStringPool* value_pool_;
+  const android::ResStringPool* source_pool_;
+  const android::ResStringPool* symbol_pool_;
+  const Source source_;
+  IDiagnostics* diag_;
 };
 
 }  // namespace
 
-std::unique_ptr<ResourceTable> deserializeTableFromPb(
-    const pb::ResourceTable& pbTable, const Source& source,
+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
@@ -407,78 +409,79 @@
 
   std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
 
-  if (!pbTable.has_string_pool()) {
-    diag->error(DiagMessage(source) << "no string pool found");
+  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");
+    diag->Error(DiagMessage(source) << "invalid string pool");
     return {};
   }
 
-  ResStringPool sourcePool;
-  if (pbTable.has_source_pool()) {
-    result = sourcePool.setTo(pbTable.source_pool().data().data(),
-                              pbTable.source_pool().data().size());
+  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 source pool");
+      diag->Error(DiagMessage(source) << "invalid source pool");
       return {};
     }
   }
 
-  ResStringPool symbolPool;
-  if (pbTable.has_symbol_pool()) {
-    result = symbolPool.setTo(pbTable.symbol_pool().data().data(),
-                              pbTable.symbol_pool().data().size());
+  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");
+      diag->Error(DiagMessage(source) << "invalid symbol pool");
       return {};
     }
   }
 
-  PackagePbDeserializer packagePbDeserializer(&valuePool, &sourcePool,
-                                              &symbolPool, source, diag);
-  for (const pb::Package& pbPackage : pbTable.packages()) {
-    if (!packagePbDeserializer.deserializeFromPb(pbPackage, table.get())) {
+  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 {};
     }
   }
   return table;
 }
 
-std::unique_ptr<ResourceFile> deserializeCompiledFileFromPb(
-    const pb::CompiledFile& pbFile, const Source& source, IDiagnostics* diag) {
+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)
+  if (!ResourceUtils::ParseResourceName(pb_file.resource_name(), &name_ref)) {
+    diag->Error(DiagMessage(source)
                 << "invalid resource name in compiled file header: "
-                << pbFile.resource_name());
+                << pb_file.resource_name());
     return {};
   }
-  file->name = nameRef.toResourceName();
-  file->source.path = pbFile.source_path();
-  deserializeConfigDescriptionFromPb(pbFile.config(), &file->config);
+  file->name = name_ref.ToResourceName();
+  file->source.path = pb_file.source_path();
+  DeserializeConfigDescriptionFromPb(pb_file.config(), &file->config);
 
-  for (const pb::CompiledFile_Symbol& pbSymbol : pbFile.exported_symbols()) {
+  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(pbSymbol.resource_name(), &nameRef)) {
-      diag->error(DiagMessage(source)
+    if (!ResourceUtils::ParseResourceName(pb_symbol.resource_name(),
+                                          &name_ref)) {
+      diag->Error(DiagMessage(source)
                   << "invalid resource name for exported symbol in "
                      "compiled file header: "
-                  << pbFile.resource_name());
+                  << pb_file.resource_name());
       return {};
     }
-    file->exportedSymbols.push_back(
-        SourcedResourceName{nameRef.toResourceName(), pbSymbol.line_no()});
+    file->exported_symbols.push_back(
+        SourcedResourceName{name_ref.ToResourceName(), pb_symbol.line_no()});
   }
   return file;
 }
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 546b607..aeabcff 100644
--- a/tools/aapt2/unflatten/BinaryResourceParser.cpp
+++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp
@@ -15,6 +15,16 @@
  */
 
 #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"
@@ -23,13 +33,6 @@
 #include "unflatten/ResChunkPullParser.h"
 #include "util/Util.h"
 
-#include <android-base/macros.h>
-#include <androidfw/ResourceTypes.h>
-#include <androidfw/TypeWrappers.h>
-#include <algorithm>
-#include <map>
-#include <string>
-
 namespace aapt {
 
 using namespace android;
@@ -41,29 +44,31 @@
  * given a mapping from resource ID to resource name.
  */
 class ReferenceIdToNameVisitor : public ValueVisitor {
- private:
-  const std::map<ResourceId, ResourceName>* mMapping;
-
  public:
-  using ValueVisitor::visit;
+  using ValueVisitor::Visit;
 
   explicit ReferenceIdToNameVisitor(
       const std::map<ResourceId, ResourceName>* mapping)
-      : mMapping(mapping) {
-    assert(mMapping);
+      : mapping_(mapping) {
+    CHECK(mapping_ != nullptr);
   }
 
-  void visit(Reference* reference) override {
-    if (!reference->id || !reference->id.value().isValid()) {
+  void Visit(Reference* reference) override {
+    if (!reference->id || !reference->id.value().is_valid()) {
       return;
     }
 
     ResourceId id = reference->id.value();
-    auto cacheIter = mMapping->find(id);
-    if (cacheIter != mMapping->end()) {
-      reference->name = cacheIter->second;
+    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
@@ -72,33 +77,32 @@
                                            ResourceTable* table,
                                            const Source& source,
                                            const void* data, size_t len)
-    : mContext(context),
-      mTable(table),
-      mSource(source),
-      mData(data),
-      mDataLen(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)
+  while (ResChunkPullParser::IsGoodEvent(parser.Next())) {
+    if (parser.chunk()->type != android::RES_TABLE_TYPE) {
+      context_->GetDiagnostics()->Warn(DiagMessage(source_)
                                        << "unknown chunk of type '"
-                                       << (int)parser.getChunk()->type << "'");
+                                       << (int)parser.chunk()->type << "'");
       continue;
     }
 
-    if (!parseTable(parser.getChunk())) {
+    if (!ParseTable(parser.chunk())) {
       error = true;
     }
   }
 
-  if (parser.getEvent() == ResChunkPullParser::Event::BadDocument) {
-    mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                      << "corrupt resource table: "
-                                      << parser.getLastError());
+  if (parser.event() == ResChunkPullParser::Event::kBadDocument) {
+    context_->GetDiagnostics()->Error(
+        DiagMessage(source_) << "corrupt resource table: " << parser.error());
     return false;
   }
   return !error;
@@ -108,212 +112,210 @@
  * 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)
+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)) {
+  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 (mValuePool.getError() == NO_INIT) {
-          status_t err = mValuePool.setTo(
-              parser.getChunk(), util::deviceToHost32(parser.getChunk()->size));
+        if (value_pool_.getError() == NO_INIT) {
+          status_t err = value_pool_.setTo(
+              parser.chunk(), util::DeviceToHost32(parser.chunk()->size));
           if (err != NO_ERROR) {
-            mContext->getDiagnostics()->error(
-                DiagMessage(mSource) << "corrupt string pool in ResTable: "
-                                     << mValuePool.getError());
+            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());
+          table_->string_pool.HintWillAdd(value_pool_.size(),
+                                          value_pool_.styleCount());
         } else {
-          mContext->getDiagnostics()->warn(
-              DiagMessage(mSource) << "unexpected string pool in ResTable");
+          context_->GetDiagnostics()->Warn(
+              DiagMessage(source_) << "unexpected string pool in ResTable");
         }
         break;
 
       case android::RES_TABLE_PACKAGE_TYPE:
-        if (!parsePackage(parser.getChunk())) {
+        if (!ParsePackage(parser.chunk())) {
           return false;
         }
         break;
 
       default:
-        mContext->getDiagnostics()->warn(
-            DiagMessage(mSource)
+        context_->GetDiagnostics()->Warn(
+            DiagMessage(source_)
             << "unexpected chunk type "
-            << (int)util::deviceToHost16(parser.getChunk()->type));
+            << (int)util::DeviceToHost16(parser.chunk()->type));
         break;
     }
   }
 
-  if (parser.getEvent() == ResChunkPullParser::Event::BadDocument) {
-    mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                      << "corrupt resource table: "
-                                      << parser.getLastError());
+  if (parser.event() == ResChunkPullParser::Event::kBadDocument) {
+    context_->GetDiagnostics()->Error(
+        DiagMessage(source_) << "corrupt resource table: " << parser.error());
     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)
+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;
   }
 
-  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 << ")");
+  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;
   }
 
   // Extract the package name.
-  size_t len = strnlen16((const char16_t*)packageHeader->name,
-                         arraysize(packageHeader->name));
-  std::u16string packageName;
-  packageName.resize(len);
+  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++) {
-    packageName[i] = util::deviceToHost16(packageHeader->name[i]);
+    package_name[i] = util::DeviceToHost16(package_header->name[i]);
   }
 
-  ResourceTablePackage* package = mTable->createPackage(
-      util::utf16ToUtf8(packageName), static_cast<uint8_t>(packageId));
+  ResourceTablePackage* package = table_->CreatePackage(
+      util::Utf16ToUtf8(package_name), static_cast<uint8_t>(package_id));
   if (!package) {
-    mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                      << "incompatible package '" << packageName
-                                      << "' with ID " << packageId);
+    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.
-  mTypePool.uninit();
-  mKeyPool.uninit();
+  type_pool_.uninit();
+  key_pool_.uninit();
 
-  ResChunkPullParser parser(getChunkData(&packageHeader->header),
-                            getChunkDataLen(&packageHeader->header));
-  while (ResChunkPullParser::isGoodEvent(parser.next())) {
-    switch (util::deviceToHost16(parser.getChunk()->type)) {
+  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 (mTypePool.getError() == NO_INIT) {
-          status_t err = mTypePool.setTo(
-              parser.getChunk(), util::deviceToHost32(parser.getChunk()->size));
+        if (type_pool_.getError() == NO_INIT) {
+          status_t err = type_pool_.setTo(
+              parser.chunk(), util::DeviceToHost32(parser.chunk()->size));
           if (err != NO_ERROR) {
-            mContext->getDiagnostics()->error(DiagMessage(mSource)
+            context_->GetDiagnostics()->Error(DiagMessage(source_)
                                               << "corrupt type string pool in "
                                               << "ResTable_package: "
-                                              << mTypePool.getError());
+                                              << type_pool_.getError());
             return false;
           }
-        } else if (mKeyPool.getError() == NO_INIT) {
-          status_t err = mKeyPool.setTo(
-              parser.getChunk(), util::deviceToHost32(parser.getChunk()->size));
+        } else if (key_pool_.getError() == NO_INIT) {
+          status_t err = key_pool_.setTo(
+              parser.chunk(), util::DeviceToHost32(parser.chunk()->size));
           if (err != NO_ERROR) {
-            mContext->getDiagnostics()->error(DiagMessage(mSource)
+            context_->GetDiagnostics()->Error(DiagMessage(source_)
                                               << "corrupt key string pool in "
                                               << "ResTable_package: "
-                                              << mKeyPool.getError());
+                                              << key_pool_.getError());
             return false;
           }
         } else {
-          mContext->getDiagnostics()->warn(DiagMessage(mSource)
+          context_->GetDiagnostics()->Warn(DiagMessage(source_)
                                            << "unexpected string pool");
         }
         break;
 
       case android::RES_TABLE_TYPE_SPEC_TYPE:
-        if (!parseTypeSpec(parser.getChunk())) {
+        if (!ParseTypeSpec(parser.chunk())) {
           return false;
         }
         break;
 
       case android::RES_TABLE_TYPE_TYPE:
-        if (!parseType(package, parser.getChunk())) {
+        if (!ParseType(package, parser.chunk())) {
           return false;
         }
         break;
 
       default:
-        mContext->getDiagnostics()->warn(
-            DiagMessage(mSource)
+        context_->GetDiagnostics()->Warn(
+            DiagMessage(source_)
             << "unexpected chunk type "
-            << (int)util::deviceToHost16(parser.getChunk()->type));
+            << (int)util::DeviceToHost16(parser.chunk()->type));
         break;
     }
   }
 
-  if (parser.getEvent() == ResChunkPullParser::Event::BadDocument) {
-    mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                      << "corrupt ResTable_package: "
-                                      << parser.getLastError());
+  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(&mIdIndex);
-  visitAllValuesInTable(mTable, &visitor);
+  ReferenceIdToNameVisitor visitor(&id_index_);
+  VisitAllValuesInTable(table_, &visitor);
   return true;
 }
 
-bool BinaryResourceParser::parseTypeSpec(const ResChunk_header* chunk) {
-  if (mTypePool.getError() != NO_ERROR) {
-    mContext->getDiagnostics()->error(DiagMessage(mSource)
+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* typeSpec = convertTo<ResTable_typeSpec>(chunk);
-  if (!typeSpec) {
-    mContext->getDiagnostics()->error(DiagMessage(mSource)
+  const ResTable_typeSpec* type_spec = ConvertTo<ResTable_typeSpec>(chunk);
+  if (!type_spec) {
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
                                       << "corrupt ResTable_typeSpec chunk");
     return false;
   }
 
-  if (typeSpec->id == 0) {
-    mContext->getDiagnostics()->error(DiagMessage(mSource)
+  if (type_spec->id == 0) {
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
                                       << "ResTable_typeSpec has invalid id: "
-                                      << typeSpec->id);
+                                      << type_spec->id);
     return false;
   }
   return true;
 }
 
-bool BinaryResourceParser::parseType(const ResourceTablePackage* package,
+bool BinaryResourceParser::ParseType(const ResourceTablePackage* package,
                                      const ResChunk_header* chunk) {
-  if (mTypePool.getError() != NO_ERROR) {
-    mContext->getDiagnostics()->error(DiagMessage(mSource)
+  if (type_pool_.getError() != NO_ERROR) {
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
                                       << "missing type string pool");
     return false;
   }
 
-  if (mKeyPool.getError() != NO_ERROR) {
-    mContext->getDiagnostics()->error(DiagMessage(mSource)
+  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);
+  const ResTable_type* type = ConvertTo<ResTable_type>(chunk);
   if (!type) {
-    mContext->getDiagnostics()->error(DiagMessage(mSource)
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
                                       << "corrupt ResTable_type chunk");
     return false;
   }
 
   if (type->id == 0) {
-    mContext->getDiagnostics()->error(DiagMessage(mSource)
+    context_->GetDiagnostics()->Error(DiagMessage(source_)
                                       << "ResTable_type has invalid id: "
                                       << (int)type->id);
     return false;
@@ -322,12 +324,12 @@
   ConfigDescription config;
   config.copyFromDtoH(type->config);
 
-  const std::string typeStr = util::getString(mTypePool, type->id - 1);
+  const std::string type_str = util::GetString(type_pool_, type->id - 1);
 
-  const ResourceType* parsedType = parseResourceType(typeStr);
-  if (!parsedType) {
-    mContext->getDiagnostics()->error(
-        DiagMessage(mSource) << "invalid type name '" << typeStr
+  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;
   }
@@ -340,91 +342,90 @@
     }
 
     const ResourceName name(
-        package->name, *parsedType,
-        util::getString(mKeyPool, util::deviceToHost32(entry->key.index)));
+        package->name, *parsed_type,
+        util::GetString(key_pool_, util::DeviceToHost32(entry->key.index)));
 
-    const ResourceId resId(package->id.value(), type->id,
-                           static_cast<uint16_t>(it.index()));
+    const ResourceId res_id(package->id.value(), type->id,
+                            static_cast<uint16_t>(it.index()));
 
-    std::unique_ptr<Value> resourceValue;
+    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.
-      resourceValue = parseMapEntry(name, config, mapEntry);
+      resource_value = 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);
+                             util::DeviceToHost32(entry->size));
+      resource_value = ParseValue(name, config, value, entry->flags);
     }
 
-    if (!resourceValue) {
-      mContext->getDiagnostics()->error(
-          DiagMessage(mSource) << "failed to parse value for resource " << name
-                               << " (" << resId << ") with configuration '"
+    if (!resource_value) {
+      context_->GetDiagnostics()->Error(
+          DiagMessage(source_) << "failed to parse value for resource " << name
+                               << " (" << res_id << ") with configuration '"
                                << config << "'");
       return false;
     }
 
-    if (!mTable->addResourceAllowMangled(name, config, {},
-                                         std::move(resourceValue),
-                                         mContext->getDiagnostics())) {
+    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 = mSource.withLine(0);
-      if (!mTable->setSymbolStateAllowMangled(name, resId, symbol,
-                                              mContext->getDiagnostics())) {
+      symbol.source = source_.WithLine(0);
+      if (!table_->SetSymbolStateAllowMangled(name, res_id, symbol,
+                                              context_->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});
+    auto cache_iter = id_index_.find(res_id);
+    if (cache_iter == id_index_.end()) {
+      id_index_.insert({res_id, name});
     }
   }
   return true;
 }
 
-std::unique_ptr<Item> BinaryResourceParser::parseValue(
+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);
+  const uint32_t data = util::DeviceToHost32(value->data);
 
   if (value->dataType == Res_value::TYPE_STRING) {
-    const std::string str = util::getString(mValuePool, data);
+    const std::string str = util::GetString(value_pool_, data);
 
-    const ResStringPool_span* spans = mValuePool.styleAt(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 styleStr = {str};
+      StyleString style_str = {str};
       while (spans->name.index != ResStringPool_span::END) {
-        styleStr.spans.push_back(
-            Span{util::getString(mValuePool, spans->name.index),
+        style_str.spans.push_back(
+            Span{util::GetString(value_pool_, spans->name.index),
                  spans->firstChar, spans->lastChar});
         spans++;
       }
-      return util::make_unique<StyledString>(mTable->stringPool.makeRef(
-          styleStr,
+      return util::make_unique<StyledString>(table_->string_pool.MakeRef(
+          style_str,
           StringPool::Context(StringPool::Context::kStylePriority, config)));
     } else {
-      if (name.type != ResourceType::kString &&
-          util::stringStartsWith(str, "res/")) {
+      if (name.type != ResourceType::kString && util::StartsWith(str, "res/")) {
         // This must be a FileReference.
-        return util::make_unique<FileReference>(mTable->stringPool.makeRef(
+        return util::make_unique<FileReference>(table_->string_pool.MakeRef(
             str,
             StringPool::Context(StringPool::Context::kHighPriority, config)));
       }
@@ -432,7 +433,7 @@
       // 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(config)));
+          table_->string_pool.MakeRef(str, StringPool::Context(config)));
     }
   }
 
@@ -444,9 +445,9 @@
 
     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);
+      Res_value null_type = {};
+      null_type.dataType = Res_value::TYPE_REFERENCE;
+      return util::make_unique<BinaryPrimitive>(null_type);
     }
 
     // This is a normal reference.
@@ -457,87 +458,88 @@
   return util::make_unique<BinaryPrimitive>(*value);
 }
 
-std::unique_ptr<Value> BinaryResourceParser::parseMapEntry(
+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);
+      return ParseStyle(name, config, map);
     case ResourceType::kAttrPrivate:
     // fallthrough
     case ResourceType::kAttr:
-      return parseAttr(name, config, map);
+      return ParseAttr(name, config, map);
     case ResourceType::kArray:
-      return parseArray(name, config, map);
+      return ParseArray(name, config, map);
     case ResourceType::kPlurals:
-      return parsePlural(name, config, map);
+      return ParsePlural(name, config, map);
     default:
-      assert(false && "unknown map type");
+      LOG(FATAL) << "unknown map type";
       break;
   }
   return {};
 }
 
-std::unique_ptr<Style> BinaryResourceParser::parseStyle(
+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) {
+  if (util::DeviceToHost32(map->parent.ident) != 0) {
     // The parent is a regular reference to a resource.
-    style->parent = Reference(util::deviceToHost32(map->parent.ident));
+    style->parent = Reference(util::DeviceToHost32(map->parent.ident));
   }
 
-  for (const ResTable_map& mapEntry : map) {
-    if (Res_INTERNALID(util::deviceToHost32(mapEntry.name.ident))) {
+  for (const ResTable_map& map_entry : map) {
+    if (Res_INTERNALID(util::DeviceToHost32(map_entry.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) {
+    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 {};
     }
-    style->entries.push_back(std::move(styleEntry));
+    style->entries.push_back(std::move(style_entry));
   }
   return style;
 }
 
-std::unique_ptr<Attribute> BinaryResourceParser::parseAttr(
+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);
+  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 =
+  auto type_mask_iter =
       std::find_if(begin(map), end(map), [](const ResTable_map& entry) -> bool {
-        return util::deviceToHost32(entry.name.ident) ==
+        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& mapEntry : map) {
-    if (Res_INTERNALID(util::deviceToHost32(mapEntry.name.ident))) {
-      switch (util::deviceToHost32(mapEntry.name.ident)) {
+  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->minInt = static_cast<int32_t>(mapEntry.value.data);
+          attr->min_int = static_cast<int32_t>(map_entry.value.data);
           break;
         case ResTable_map::ATTR_MAX:
-          attr->maxInt = static_cast<int32_t>(mapEntry.value.data);
+          attr->max_int = static_cast<int32_t>(map_entry.value.data);
           break;
       }
       continue;
     }
 
-    if (attr->typeMask & (ResTable_map::TYPE_ENUM | ResTable_map::TYPE_FLAGS)) {
+    if (attr->type_mask &
+        (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));
+      symbol.value = util::DeviceToHost32(map_entry.value.data);
+      symbol.symbol = Reference(util::DeviceToHost32(map_entry.name.ident));
       attr->symbols.push_back(std::move(symbol));
     }
   }
@@ -546,27 +548,27 @@
   return attr;
 }
 
-std::unique_ptr<Array> BinaryResourceParser::parseArray(
+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));
+  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(
+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);
+  for (const ResTable_map& map_entry : map) {
+    std::unique_ptr<Item> item = ParseValue(name, config, &map_entry.value, 0);
     if (!item) {
       return {};
     }
 
-    switch (util::deviceToHost32(mapEntry.name.ident)) {
+    switch (util::DeviceToHost32(map_entry.name.ident)) {
       case ResTable_map::ATTR_ZERO:
         plural->values[Plural::Zero] = std::move(item);
         break;
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/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/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index fa880f0..4a4c6c8 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -123,7 +123,7 @@
     /*package*/ static long initRaster(@Nullable Bitmap bitmap) {
         long nativeBitmapOrZero = 0;
         if (bitmap != null) {
-            nativeBitmapOrZero = bitmap.refSkPixelRef();
+            nativeBitmapOrZero = bitmap.getNativeInstance();
         }
         if (nativeBitmapOrZero > 0) {
             // get the Bitmap from the int
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 09ab657..4596210 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -86,7 +86,7 @@
     }
 
     @Override
-    public void addWindowToken(IBinder arg0, int arg1) throws RemoteException {
+    public void addWindowToken(IBinder arg0, int arg1, int arg2) throws RemoteException {
         // TODO Auto-generated method stub
 
     }
@@ -277,13 +277,13 @@
     }
 
     @Override
-    public void removeAppToken(IBinder arg0) throws RemoteException {
+    public void removeAppToken(IBinder arg0, int arg1) throws RemoteException {
         // TODO Auto-generated method stub
 
     }
 
     @Override
-    public void removeWindowToken(IBinder arg0) throws RemoteException {
+    public void removeWindowToken(IBinder arg0, int arg1) throws RemoteException {
         // TODO Auto-generated method stub
 
     }
@@ -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;
@@ -523,10 +524,6 @@
     }
 
     @Override
-    public void setKeyguardAnimatingIn(boolean animating) throws RemoteException {
-    }
-
-    @Override
     public void setSwitchingUser(boolean switching) throws RemoteException {
     }
 
@@ -590,6 +587,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 +615,7 @@
     }
 
     @Override
-    public void getStableInsets(Rect outInsets) throws RemoteException {
+    public void getStableInsets(int displayId, Rect outInsets) throws RemoteException {
     }
 
     @Override
diff --git a/tools/split-select/Android.mk b/tools/split-select/Android.mk
index 199fafa..4a1511e 100644
--- a/tools/split-select/Android.mk
+++ b/tools/split-select/Android.mk
@@ -73,7 +73,7 @@
 LOCAL_MODULE_HOST_OS := darwin linux windows
 
 LOCAL_SRC_FILES := $(sources)
-
+LOCAL_STATIC_LIBRARIES := $(hostStaticLibs)
 LOCAL_C_INCLUDES := $(cIncludes)
 LOCAL_CFLAGS := $(cFlags) -D_DARWIN_UNLIMITED_STREAMS
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 8d819b9..18a580e 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1066,7 +1066,7 @@
     /** @hide */
     public static final int WIFI_FEATURE_SCANNER          = 0x0020;  // WifiScanner APIs
     /** @hide */
-    public static final int WIFI_FEATURE_NAN              = 0x0040;  // Neighbor Awareness Networking
+    public static final int WIFI_FEATURE_AWARE              = 0x0040;  // Wi-Fi AWare networking
     /** @hide */
     public static final int WIFI_FEATURE_D2D_RTT          = 0x0080;  // Device-to-device RTT
     /** @hide */
@@ -1147,8 +1147,8 @@
      * @return true if this adapter supports Neighbour Awareness Network APIs
      * @hide
      */
-    public boolean isNanSupported() {
-        return isFeatureSupported(WIFI_FEATURE_NAN);
+    public boolean isWifiAwareSupported() {
+        return isFeatureSupported(WIFI_FEATURE_AWARE);
     }
 
     /**
diff --git a/wifi/java/android/net/wifi/nan/ConfigRequest.aidl b/wifi/java/android/net/wifi/aware/ConfigRequest.aidl
similarity index 95%
rename from wifi/java/android/net/wifi/nan/ConfigRequest.aidl
rename to wifi/java/android/net/wifi/aware/ConfigRequest.aidl
index 38dddc2..68a7c85 100644
--- a/wifi/java/android/net/wifi/nan/ConfigRequest.aidl
+++ b/wifi/java/android/net/wifi/aware/ConfigRequest.aidl
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 parcelable ConfigRequest;
diff --git a/wifi/java/android/net/wifi/nan/ConfigRequest.java b/wifi/java/android/net/wifi/aware/ConfigRequest.java
similarity index 96%
rename from wifi/java/android/net/wifi/nan/ConfigRequest.java
rename to wifi/java/android/net/wifi/aware/ConfigRequest.java
index bcd7932..4aacbae 100644
--- a/wifi/java/android/net/wifi/nan/ConfigRequest.java
+++ b/wifi/java/android/net/wifi/aware/ConfigRequest.java
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 import android.os.Parcel;
 import android.os.Parcelable;
 
 /**
- * Defines a request object to configure a Wi-Fi NAN network. Built using
+ * Defines a request object to configure a Wi-Fi Aware network. Built using
  * {@link ConfigRequest.Builder}. Configuration is requested using
- * {@link WifiNanManager#attach(android.os.Handler, WifiNanAttachCallback)}.
+ * {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)}.
  * Note that the actual achieved configuration may be different from the
  * requested configuration - since different applications may request different
  * configurations.
@@ -221,7 +221,7 @@
         }
 
         /**
-         * The Cluster ID is generated randomly for new NAN networks. Specify
+         * The Cluster ID is generated randomly for new Aware networks. Specify
          * the lower range of the cluster ID. The upper range is specified using
          * the {@link ConfigRequest.Builder#setClusterHigh(int)}. The permitted
          * range is 0 (the default) to the value specified by
@@ -246,7 +246,7 @@
         }
 
         /**
-         * The Cluster ID is generated randomly for new NAN networks. Specify
+         * The Cluster ID is generated randomly for new Aware networks. Specify
          * the lower upper of the cluster ID. The lower range is specified using
          * the {@link ConfigRequest.Builder#setClusterLow(int)}. The permitted
          * range is the value specified by
diff --git a/wifi/java/android/net/wifi/nan/IWifiNanDiscoverySessionCallback.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl
similarity index 88%
rename from wifi/java/android/net/wifi/nan/IWifiNanDiscoverySessionCallback.aidl
rename to wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl
index f2e371d..8ff3842 100644
--- a/wifi/java/android/net/wifi/nan/IWifiNanDiscoverySessionCallback.aidl
+++ b/wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 /**
- * Callback interface that WifiNanManager implements
+ * Callback interface that WifiAwareManager implements
  *
  * {@hide}
  */
-oneway interface IWifiNanDiscoverySessionCallback
+oneway interface IWifiAwareDiscoverySessionCallback
 {
     void onSessionStarted(int discoverySessionId);
     void onSessionConfigSuccess();
diff --git a/wifi/java/android/net/wifi/nan/IWifiNanEventCallback.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl
similarity index 85%
rename from wifi/java/android/net/wifi/nan/IWifiNanEventCallback.aidl
rename to wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl
index 9ac7bf2..30dd64d 100644
--- a/wifi/java/android/net/wifi/nan/IWifiNanEventCallback.aidl
+++ b/wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl
@@ -14,17 +14,17 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
-import android.net.wifi.nan.ConfigRequest;
+import android.net.wifi.aware.ConfigRequest;
 import android.net.wifi.RttManager;
 
 /**
- * Callback interface that WifiNanManager implements
+ * Callback interface that WifiAwareManager implements
  *
  * {@hide}
  */
-oneway interface IWifiNanEventCallback
+oneway interface IWifiAwareEventCallback
 {
     void onConnectSuccess(int clientId);
     void onConnectFail(int reason);
diff --git a/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
similarity index 71%
rename from wifi/java/android/net/wifi/nan/IWifiNanManager.aidl
rename to wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
index 5485824..9c92807 100644
--- a/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl
+++ b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
@@ -14,40 +14,40 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 import android.app.PendingIntent;
 
-import android.net.wifi.nan.ConfigRequest;
-import android.net.wifi.nan.IWifiNanDiscoverySessionCallback;
-import android.net.wifi.nan.IWifiNanEventCallback;
-import android.net.wifi.nan.PublishConfig;
-import android.net.wifi.nan.SubscribeConfig;
-import android.net.wifi.nan.WifiNanCharacteristics;
+import android.net.wifi.aware.ConfigRequest;
+import android.net.wifi.aware.IWifiAwareDiscoverySessionCallback;
+import android.net.wifi.aware.IWifiAwareEventCallback;
+import android.net.wifi.aware.PublishConfig;
+import android.net.wifi.aware.SubscribeConfig;
+import android.net.wifi.aware.WifiAwareCharacteristics;
 import android.net.wifi.RttManager;
 
 /**
- * Interface that WifiNanService implements
+ * Interface that WifiAwareService implements
  *
  * {@hide}
  */
-interface IWifiNanManager
+interface IWifiAwareManager
 {
-    // NAN API
+    // Aware API
     void enableUsage();
     void disableUsage();
     boolean isUsageEnabled();
-    WifiNanCharacteristics getCharacteristics();
+    WifiAwareCharacteristics getCharacteristics();
 
     // client API
-    void connect(in IBinder binder, in String callingPackage, in IWifiNanEventCallback callback,
+    void connect(in IBinder binder, in String callingPackage, in IWifiAwareEventCallback callback,
             in ConfigRequest configRequest, boolean notifyOnIdentityChanged);
     void disconnect(int clientId, in IBinder binder);
 
     void publish(int clientId, in PublishConfig publishConfig,
-            in IWifiNanDiscoverySessionCallback callback);
+            in IWifiAwareDiscoverySessionCallback callback);
     void subscribe(int clientId, in SubscribeConfig subscribeConfig,
-            in IWifiNanDiscoverySessionCallback callback);
+            in IWifiAwareDiscoverySessionCallback callback);
 
     // session API
     void updatePublish(int clientId, int discoverySessionId, in PublishConfig publishConfig);
diff --git a/wifi/java/android/net/wifi/nan/LvBufferUtils.java b/wifi/java/android/net/wifi/aware/LvBufferUtils.java
similarity index 99%
rename from wifi/java/android/net/wifi/nan/LvBufferUtils.java
rename to wifi/java/android/net/wifi/aware/LvBufferUtils.java
index eb56070..3265243 100644
--- a/wifi/java/android/net/wifi/nan/LvBufferUtils.java
+++ b/wifi/java/android/net/wifi/aware/LvBufferUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 import android.annotation.Nullable;
 
@@ -28,7 +28,7 @@
  * Length/Value format. The utilities accept a configuration of the size of
  * the Length field.
  *
- * @hide PROPOSED_NAN_API
+ * @hide PROPOSED_AWARE_API
  */
 public class LvBufferUtils {
     private LvBufferUtils() {
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/wifi/java/android/net/wifi/aware/PublishConfig.aidl
similarity index 95%
rename from wifi/java/android/net/wifi/nan/PublishConfig.aidl
rename to wifi/java/android/net/wifi/aware/PublishConfig.aidl
index 5f66d16..2e6dd00 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/wifi/java/android/net/wifi/aware/PublishConfig.aidl
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 parcelable PublishConfig;
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java
similarity index 92%
rename from wifi/java/android/net/wifi/nan/PublishConfig.java
rename to wifi/java/android/net/wifi/aware/PublishConfig.java
index 30c5bc0..5d3ad058 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.java
+++ b/wifi/java/android/net/wifi/aware/PublishConfig.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -30,13 +30,14 @@
 import java.util.Arrays;
 
 /**
- * Defines the configuration of a NAN publish session. Built using
+ * Defines the configuration of a Aware publish session. Built using
  * {@link PublishConfig.Builder}. A publish session is created using
- * {@link WifiNanSession#publish(android.os.Handler, PublishConfig, WifiNanDiscoverySessionCallback)}
+ * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig,
+ * WifiAwareDiscoverySessionCallback)}
  * or updated using
- * {@link WifiNanPublishDiscoverySession#updatePublish(PublishConfig)}.
+ * {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)}.
  *
- * @hide PROPOSED_NAN_API
+ * @hide PROPOSED_AWARE_API
  */
 public final class PublishConfig implements Parcelable {
     /** @hide */
@@ -182,8 +183,9 @@
      *
      * @hide
      */
-    public void assertValid(WifiNanCharacteristics characteristics) throws IllegalArgumentException {
-        WifiNanUtils.validateServiceName(mServiceName);
+    public void assertValid(WifiAwareCharacteristics characteristics)
+            throws IllegalArgumentException {
+        WifiAwareUtils.validateServiceName(mServiceName);
 
         if (!LvBufferUtils.isValid(mMatchFilter, 1)) {
             throw new IllegalArgumentException(
@@ -320,12 +322,12 @@
          * Sets the number of times an unsolicited (configured using
          * {@link PublishConfig.Builder#setPublishType(int)}) publish session
          * will be broadcast. When the count is reached an event will be
-         * generated for {@link WifiNanDiscoverySessionCallback#onSessionTerminated(int)}
-         * with {@link WifiNanDiscoverySessionCallback#TERMINATE_REASON_DONE} [unless
+         * generated for {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)}
+         * with {@link WifiAwareDiscoverySessionCallback#TERMINATE_REASON_DONE} [unless
          * {@link #setTerminateNotificationEnabled(boolean)} disables the callback].
          * <p>
          *     Optional. 0 by default - indicating the session doesn't terminate on its own.
-         *     Session will be terminated when {@link WifiNanDiscoveryBaseSession#destroy()} is
+         *     Session will be terminated when {@link WifiAwareDiscoveryBaseSession#destroy()} is
          *     called.
          *
          * @param publishCount Number of publish packets to broadcast.
@@ -346,12 +348,12 @@
          * {@link PublishConfig.Builder#setPublishType(int)}) publish session
          * will be alive - broadcasting a packet. When the TTL is reached
          * an event will be generated for
-         * {@link WifiNanDiscoverySessionCallback#onSessionTerminated(int)} with
-         * {@link WifiNanDiscoverySessionCallback#TERMINATE_REASON_DONE}  [unless
+         * {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)} with
+         * {@link WifiAwareDiscoverySessionCallback#TERMINATE_REASON_DONE}  [unless
          * {@link #setTerminateNotificationEnabled(boolean)} disables the callback].
          * <p>
          *     Optional. 0 by default - indicating the session doesn't terminate on its own.
-         *     Session will be terminated when {@link WifiNanDiscoveryBaseSession#destroy()} is
+         *     Session will be terminated when {@link WifiAwareDiscoveryBaseSession#destroy()} is
          *     called.
          *
          * @param ttlSec Lifetime of a publish session in seconds.
@@ -369,7 +371,7 @@
 
         /**
          * Configure whether a publish terminate notification
-         * {@link WifiNanDiscoverySessionCallback#onSessionTerminated(int)} is reported
+         * {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)} is reported
          * back to the callback.
          *
          * @param enable If true the terminate callback will be called when the
diff --git a/wifi/java/android/net/wifi/nan/SubscribeConfig.aidl b/wifi/java/android/net/wifi/aware/SubscribeConfig.aidl
similarity index 95%
rename from wifi/java/android/net/wifi/nan/SubscribeConfig.aidl
rename to wifi/java/android/net/wifi/aware/SubscribeConfig.aidl
index 92344a4..bd73d5e 100644
--- a/wifi/java/android/net/wifi/nan/SubscribeConfig.aidl
+++ b/wifi/java/android/net/wifi/aware/SubscribeConfig.aidl
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 parcelable SubscribeConfig;
diff --git a/wifi/java/android/net/wifi/nan/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
similarity index 93%
rename from wifi/java/android/net/wifi/nan/SubscribeConfig.java
rename to wifi/java/android/net/wifi/aware/SubscribeConfig.java
index ea7b8e4..2a6cc93 100644
--- a/wifi/java/android/net/wifi/nan/SubscribeConfig.java
+++ b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -30,13 +30,14 @@
 import java.util.Arrays;
 
 /**
- * Defines the configuration of a NAN subscribe session. Built using
+ * Defines the configuration of a Aware subscribe session. Built using
  * {@link SubscribeConfig.Builder}. Subscribe is done using
- * {@link WifiNanSession#subscribe(android.os.Handler, SubscribeConfig, WifiNanDiscoverySessionCallback)}
+ * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig,
+ * WifiAwareDiscoverySessionCallback)}
  * or
- * {@link WifiNanSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
+ * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
  *
- * @hide PROPOSED_NAN_API
+ * @hide PROPOSED_AWARE_API
  */
 public final class SubscribeConfig implements Parcelable {
     /** @hide */
@@ -209,8 +210,9 @@
      *
      * @hide
      */
-    public void assertValid(WifiNanCharacteristics characteristics) throws IllegalArgumentException {
-        WifiNanUtils.validateServiceName(mServiceName);
+    public void assertValid(WifiAwareCharacteristics characteristics)
+            throws IllegalArgumentException {
+        WifiAwareUtils.validateServiceName(mServiceName);
 
         if (!LvBufferUtils.isValid(mMatchFilter, 1)) {
             throw new IllegalArgumentException(
@@ -352,11 +354,11 @@
          * Sets the number of times an active (
          * {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe session
          * will broadcast. When the count is reached an event will be
-         * generated for {@link WifiNanDiscoverySessionCallback#onSessionTerminated(int)}
-         * with {@link WifiNanDiscoverySessionCallback#TERMINATE_REASON_DONE}.
+         * generated for {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)}
+         * with {@link WifiAwareDiscoverySessionCallback#TERMINATE_REASON_DONE}.
          * <p>
          *     Optional. 0 by default - indicating the session doesn't terminate on its own.
-         *     Session will be terminated when {@link WifiNanDiscoveryBaseSession#destroy()} is
+         *     Session will be terminated when {@link WifiAwareDiscoveryBaseSession#destroy()} is
          *     called.
          *
          * @param subscribeCount Number of subscribe packets to broadcast.
@@ -377,11 +379,11 @@
          * {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe session
          * will be alive - i.e. broadcasting a packet. When the TTL is reached
          * an event will be generated for
-         * {@link WifiNanDiscoverySessionCallback#onSessionTerminated(int)} with
-         * {@link WifiNanDiscoverySessionCallback#TERMINATE_REASON_DONE}.
+         * {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)} with
+         * {@link WifiAwareDiscoverySessionCallback#TERMINATE_REASON_DONE}.
          * <p>
          *     Optional. 0 by default - indicating the session doesn't terminate on its own.
-         *     Session will be terminated when {@link WifiNanDiscoveryBaseSession#destroy()} is
+         *     Session will be terminated when {@link WifiAwareDiscoveryBaseSession#destroy()} is
          *     called.
          *
          * @param ttlSec Lifetime of a subscribe session in seconds.
@@ -401,7 +403,7 @@
          * Sets the match style of the subscription - how are matches from a
          * single match session (corresponding to the same publish action on the
          * peer) reported to the host (using the
-         * {@link WifiNanDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])}
+         * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])}
          * ). The options are: only report the first match and ignore the rest
          * {@link SubscribeConfig#MATCH_STYLE_FIRST_ONLY} or report every single
          * match {@link SubscribeConfig#MATCH_STYLE_ALL} (the default).
@@ -421,7 +423,7 @@
 
         /**
          * Configure whether a subscribe terminate notification
-         * {@link WifiNanDiscoverySessionCallback#onSessionTerminated(int)} is reported
+         * {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)} is reported
          * back to the callback.
          *
          * @param enable If true the terminate callback will be called when the
diff --git a/wifi/java/android/net/wifi/nan/TlvBufferUtils.java b/wifi/java/android/net/wifi/aware/TlvBufferUtils.java
similarity index 99%
rename from wifi/java/android/net/wifi/nan/TlvBufferUtils.java
rename to wifi/java/android/net/wifi/aware/TlvBufferUtils.java
index 2c5aab4..56c9069 100644
--- a/wifi/java/android/net/wifi/nan/TlvBufferUtils.java
+++ b/wifi/java/android/net/wifi/aware/TlvBufferUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 import android.annotation.Nullable;
 
@@ -32,7 +32,7 @@
  * the Type field and the Length field. A Type field size of 0 is allowed -
  * allowing usage for LV (no T) array formats.
  *
- * @hide PROPOSED_NAN_API
+ * @hide PROPOSED_AWARE_API
  */
 public class TlvBufferUtils {
     private TlvBufferUtils() {
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java b/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java
new file mode 100644
index 0000000..2cace61
--- /dev/null
+++ b/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java
@@ -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.
+ */
+
+package android.net.wifi.aware;
+
+/**
+ * Base class for Aware attach callbacks. Should be extended by applications and set when calling
+ * {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)}. These are callbacks
+ * applying to the Aware connection as a whole - not to specific publish or subscribe sessions -
+ * for that see {@link WifiAwareDiscoverySessionCallback}.
+ *
+ * @hide PROPOSED_AWARE_API
+ */
+public class WifiAwareAttachCallback {
+    /**
+     * Called when Aware attach operation
+     * {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)}
+     * is completed and that we can now start discovery sessions or connections.
+     *
+     * @param session The Aware object on which we can execute further Aware operations - e.g.
+     *                discovery, connections.
+     */
+    public void onAttached(WifiAwareSession session) {
+        /* empty */
+    }
+
+    /**
+     * Called when Aware attach operation
+     * {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)} failed.
+     */
+    public void onAttachFailed() {
+        /* empty */
+    }
+}
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.aidl
similarity index 89%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.aidl
index 5f66d16..a35e71d 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.aidl
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
-parcelable PublishConfig;
+parcelable WifiAwareCharacteristics;
diff --git a/wifi/java/android/net/wifi/nan/WifiNanCharacteristics.java b/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java
similarity index 73%
rename from wifi/java/android/net/wifi/nan/WifiNanCharacteristics.java
rename to wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java
index f43ed4d..6232c14 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanCharacteristics.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java
@@ -14,18 +14,18 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
 /**
- * The characteristics of the Wi-Fi NAN implementation.
+ * The characteristics of the Wi-Fi Aware implementation.
  *
- * @hide PROPOSED_NAN_API
+ * @hide PROPOSED_AWARE_API
  */
-public class WifiNanCharacteristics implements Parcelable {
+public class WifiAwareCharacteristics implements Parcelable {
     /** @hide */
     public static final String KEY_MAX_SERVICE_NAME_LENGTH = "key_max_service_name_length";
     /** @hide */
@@ -37,41 +37,41 @@
     private Bundle mCharacteristics = new Bundle();
 
     /** @hide : should not be created by apps */
-    public WifiNanCharacteristics(Bundle characteristics) {
+    public WifiAwareCharacteristics(Bundle characteristics) {
         mCharacteristics = characteristics;
     }
 
     /**
-     * Returns the maximum string length that can be used to specify a NAN service name. Restricts
+     * Returns the maximum string length that can be used to specify a Aware service name. Restricts
      * the parameters of the {@link PublishConfig.Builder#setServiceName(String)} and
      * {@link SubscribeConfig.Builder#setServiceName(String)}.
      *
-     * @return A positive integer, maximum string length of NAN service name.
+     * @return A positive integer, maximum string length of Aware service name.
      */
     public int getMaxServiceNameLength() {
         return mCharacteristics.getInt(KEY_MAX_SERVICE_NAME_LENGTH);
     }
 
     /**
-     * Returns the maximum length of byte array that can be used to specify a NAN service specific
-     * information field: the arbitrary load used in discovery or the message length of NAN
+     * Returns the maximum length of byte array that can be used to specify a Aware service specific
+     * information field: the arbitrary load used in discovery or the message length of Aware
      * message exchange. Restricts the parameters of the
      * {@link PublishConfig.Builder#setServiceSpecificInfo(byte[])},
      * {@link SubscribeConfig.Builder#setServiceSpecificInfo(byte[])}, and
-     * {@link WifiNanDiscoveryBaseSession#sendMessage(Object, int, byte[])} variants.
+     * {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])} variants.
      *
-     * @return A positive integer, maximum length of byte array for NAN messaging.
+     * @return A positive integer, maximum length of byte array for Aware messaging.
      */
     public int getMaxServiceSpecificInfoLength() {
         return mCharacteristics.getInt(KEY_MAX_SERVICE_SPECIFIC_INFO_LENGTH);
     }
 
     /**
-     * Returns the maximum length of byte array that can be used to specify a NAN match filter.
+     * Returns the maximum length of byte array that can be used to specify a Aware match filter.
      * Restricts the parameters of the {@link PublishConfig.Builder#setMatchFilter(byte[])} and
      * {@link SubscribeConfig.Builder#setMatchFilter(byte[])}.
      *
-     * @return A positive integer, maximum legngth of byte array for NAN discovery match filter.
+     * @return A positive integer, maximum legngth of byte array for Aware discovery match filter.
      */
     public int getMaxMatchFilterLength() {
         return mCharacteristics.getInt(KEY_MAX_MATCH_FILTER_LENGTH);
@@ -87,17 +87,17 @@
         return 0;
     }
 
-    public static final Creator<WifiNanCharacteristics> CREATOR =
-            new Creator<WifiNanCharacteristics>() {
+    public static final Creator<WifiAwareCharacteristics> CREATOR =
+            new Creator<WifiAwareCharacteristics>() {
                 @Override
-                public WifiNanCharacteristics createFromParcel(Parcel in) {
-                    WifiNanCharacteristics c = new WifiNanCharacteristics(in.readBundle());
+                public WifiAwareCharacteristics createFromParcel(Parcel in) {
+                    WifiAwareCharacteristics c = new WifiAwareCharacteristics(in.readBundle());
                     return c;
                 }
 
                 @Override
-                public WifiNanCharacteristics[] newArray(int size) {
-                    return new WifiNanCharacteristics[size];
+                public WifiAwareCharacteristics[] newArray(int size) {
+                    return new WifiAwareCharacteristics[size];
                 }
             };
 }
diff --git a/wifi/java/android/net/wifi/nan/WifiNanDiscoveryBaseSession.java b/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java
similarity index 70%
rename from wifi/java/android/net/wifi/nan/WifiNanDiscoveryBaseSession.java
rename to wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java
index 17e974b..07f7523 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanDiscoveryBaseSession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -27,30 +27,30 @@
 import java.lang.ref.WeakReference;
 
 /**
- * A class representing a single publish or subscribe NAN session. This object
+ * A class representing a single publish or subscribe Aware session. This object
  * will not be created directly - only its child classes are available:
- * {@link WifiNanPublishDiscoverySession} and {@link WifiNanSubscribeDiscoverySession}. This
+ * {@link WifiAwarePublishDiscoverySession} and {@link WifiAwareSubscribeDiscoverySession}. This
  * class provides functionality common to both publish and subscribe discovery sessions:
  * <ul>
  *     <li>Sending messages: {@link #sendMessage(Object, int, byte[])} or
  *     {@link #sendMessage(Object, int, byte[], int)} methods.
- *     <li>Creating a network-specifier when requesting a NAN connection:
+ *     <li>Creating a network-specifier when requesting a Aware connection:
  *     {@link #createNetworkSpecifier(int, Object, byte[])}.
  * </ul>
  * The {@link #destroy()} method must be called to destroy discovery sessions once they are
  * no longer needed.
  *
- * @hide PROPOSED_NAN_API
+ * @hide PROPOSED_AWARE_API
  */
-public class WifiNanDiscoveryBaseSession {
-    private static final String TAG = "WifiNanDiscoveryBaseSsn";
+public class WifiAwareDiscoveryBaseSession {
+    private static final String TAG = "WifiAwareDiscBaseSsn";
     private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
     private static final int MAX_SEND_RETRY_COUNT = 5;
 
     /** @hide */
-    protected WeakReference<WifiNanManager> mMgr;
+    protected WeakReference<WifiAwareManager> mMgr;
     /** @hide */
     protected final int mClientId;
     /** @hide */
@@ -71,7 +71,7 @@
     }
 
     /** @hide */
-    public WifiNanDiscoveryBaseSession(WifiNanManager manager, int clientId, int sessionId) {
+    public WifiAwareDiscoveryBaseSession(WifiAwareManager manager, int clientId, int sessionId) {
         if (VDBG) {
             Log.v(TAG, "New discovery session created: manager=" + manager + ", clientId="
                     + clientId + ", sessionId=" + sessionId);
@@ -93,12 +93,12 @@
      *     This operation must be done on a session which is no longer needed. Otherwise system
      *     resources will continue to be utilized until the application exits. The only
      *     exception is a session for which we received a termination callback,
-     *     {@link WifiNanDiscoverySessionCallback#onSessionTerminated(int)}.
+     *     {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)}.
      */
     public void destroy() {
-        WifiNanManager mgr = mMgr.get();
+        WifiAwareManager mgr = mMgr.get();
         if (mgr == null) {
-            Log.w(TAG, "destroy: called post GC on WifiNanManager");
+            Log.w(TAG, "destroy: called post GC on WifiAwareManager");
             return;
         }
         mgr.terminateSession(mClientId, mSessionId);
@@ -137,26 +137,26 @@
     }
 
     /**
-     * Sends a message to the specified destination. NAN messages are transmitted in the context
+     * Sends a message to the specified destination. Aware messages are transmitted in the context
      * of a discovery session - executed subsequent to a publish/subscribe
-     * {@link WifiNanDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} event.
+     * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} event.
      * <p>
-     *     NAN messages are not guaranteed delivery. Callbacks on
-     *     {@link WifiNanDiscoverySessionCallback} indicate message was transmitted successfully,
-     *     {@link WifiNanDiscoverySessionCallback#onMessageSent(int)}, or transmission failed
+     *     Aware messages are not guaranteed delivery. Callbacks on
+     *     {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully,
+     *     {@link WifiAwareDiscoverySessionCallback#onMessageSent(int)}, or transmission failed
      *     (possibly after several retries) -
-     *     {@link WifiNanDiscoverySessionCallback#onMessageSendFailed(int)}.
+     *     {@link WifiAwareDiscoverySessionCallback#onMessageSendFailed(int)}.
      * <p>
      *     The peer will get a callback indicating a message was received using
-     *     {@link WifiNanDiscoverySessionCallback#onMessageReceived(Object, byte[])}.
+     *     {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])}.
      *
      * @param peerHandle The peer's handle for the message. Must be a result of an
-     *        {@link WifiNanDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])}
+     *        {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])}
      *        or
-     *        {@link WifiNanDiscoverySessionCallback#onMessageReceived(Object, byte[])} events.
+     *        {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])} events.
      * @param messageId An arbitrary integer used by the caller to identify the message. The same
      *            integer ID will be returned in the callbacks indicating message send success or
-     *            failure. The {@code messageId} is not used internally by the NAN service - it
+     *            failure. The {@code messageId} is not used internally by the Aware service - it
      *                  can be arbitrary and non-unique.
      * @param message The message to be transmitted.
      * @param retryCount An integer specifying how many additional service-level (as opposed to PHY
@@ -170,9 +170,9 @@
             Log.w(TAG, "sendMessage: called on terminated session");
             return;
         } else {
-            WifiNanManager mgr = mMgr.get();
+            WifiAwareManager mgr = mMgr.get();
             if (mgr == null) {
-                Log.w(TAG, "sendMessage: called post GC on WifiNanManager");
+                Log.w(TAG, "sendMessage: called post GC on WifiAwareManager");
                 return;
             }
 
@@ -181,28 +181,28 @@
     }
 
     /**
-     * Sends a message to the specified destination. NAN messages are transmitted in the context
+     * Sends a message to the specified destination. Aware messages are transmitted in the context
      * of a discovery session - executed subsequent to a publish/subscribe
-     * {@link WifiNanDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} event.
+     * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} event.
      * <p>
-     *     NAN messages are not guaranteed delivery. Callbacks on
-     *     {@link WifiNanDiscoverySessionCallback} indicate message was transmitted successfully,
-     *     {@link WifiNanDiscoverySessionCallback#onMessageSent(int)}, or transmission failed
+     *     Aware messages are not guaranteed delivery. Callbacks on
+     *     {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully,
+     *     {@link WifiAwareDiscoverySessionCallback#onMessageSent(int)}, or transmission failed
      *     (possibly after several retries) -
-     *     {@link WifiNanDiscoverySessionCallback#onMessageSendFailed(int)}.
+     *     {@link WifiAwareDiscoverySessionCallback#onMessageSendFailed(int)}.
      * <p>
      *     The peer will get a callback indicating a message was received using
-     *     {@link WifiNanDiscoverySessionCallback#onMessageReceived(Object, byte[])}.
+     *     {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])}.
      * Equivalent to {@link #sendMessage(Object, int, byte[], int)} with a {@code retryCount} of
      * 0.
      *
      * @param peerHandle The peer's handle for the message. Must be a result of an
-     *        {@link WifiNanDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])}
+     *        {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])}
      *        or
-     *        {@link WifiNanDiscoverySessionCallback#onMessageReceived(Object, byte[])} events.
+     *        {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])} events.
      * @param messageId An arbitrary integer used by the caller to identify the message. The same
      *            integer ID will be returned in the callbacks indicating message send success or
-     *            failure. The {@code messageId} is not used internally by the NAN service - it
+     *            failure. The {@code messageId} is not used internally by the Aware service - it
      *                  can be arbitrary and non-unique.
      * @param message The message to be transmitted.
      */
@@ -212,8 +212,8 @@
 
     /**
      * Start a ranging operation with the specified peers. The peer IDs are obtained from an
-     * {@link WifiNanDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} or
-     * {@link WifiNanDiscoverySessionCallback#onMessageReceived(Object, byte[])} operation - can
+     * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} or
+     * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])} operation - can
      * only range devices which are part of an ongoing discovery session.
      *
      * @param params   RTT parameters - each corresponding to a specific peer ID (the array sizes
@@ -221,16 +221,17 @@
      *                 {@link android.net.wifi.RttManager.RttParams#bssid} member must be set to
      *                 a peer ID - not to a MAC address.
      * @param listener The listener to receive the results of the ranging session.
-     * @hide PROPOSED_NAN_SYSTEM_API [TODO: b/28847998 - track RTT API & visilibity]
+     * @hide PROPOSED_AWARE_SYSTEM_API
+     * [TODO: b/28847998 - track RTT API & visilibity]
      */
     public void startRanging(RttManager.RttParams[] params, RttManager.RttListener listener) {
         if (mTerminated) {
             Log.w(TAG, "startRanging: called on terminated session");
             return;
         } else {
-            WifiNanManager mgr = mMgr.get();
+            WifiAwareManager mgr = mMgr.get();
             if (mgr == null) {
-                Log.w(TAG, "startRanging: called post GC on WifiNanManager");
+                Log.w(TAG, "startRanging: called post GC on WifiAwareManager");
                 return;
             }
 
@@ -240,23 +241,23 @@
 
     /**
      * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for a
-     * WiFi NAN connection to the specified peer. The
+     * WiFi Aware connection to the specified peer. The
      * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
-     * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_NAN}.
+     * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
      * <p>
-     * This method should be used when setting up a connection with a peer discovered through NAN
+     * This method should be used when setting up a connection with a peer discovered through Aware
      * discovery or communication (in such scenarios the MAC address of the peer is shielded by
-     * an opaque peer ID handle). If a NAN connection is needed to a peer discovered using other
+     * an opaque peer ID handle). If a Aware connection is needed to a peer discovered using other
      * OOB (out-of-band) mechanism then use the alternative
-     * {@link WifiNanSession#createNetworkSpecifier(int, byte[], byte[])} method - which uses the
+     * {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])} method - which uses the
      * peer's MAC address.
      *
      * @param role The role of this device:
-     * {@link WifiNanManager#WIFI_NAN_DATA_PATH_ROLE_INITIATOR} or
-     * {@link WifiNanManager#WIFI_NAN_DATA_PATH_ROLE_RESPONDER}
+     * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
+     * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
      * @param peerHandle The peer's handle obtained through
-     * {@link WifiNanDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} or
-     * {@link WifiNanDiscoverySessionCallback#onMessageReceived(Object, byte[])}. On a RESPONDER
+     * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} or
+     * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])}. On a RESPONDER
      *               this value is used to gate the acceptance of a connection request from only
      *               that peer. A RESPONDER may specified a null - indicating that it will accept
      *               connection requests from any device.
@@ -268,18 +269,19 @@
      *
      * @return A string to be used to construct
      * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
-     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,android.net.ConnectivityManager.NetworkCallback)}
+     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
+     * android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
      */
-    public String createNetworkSpecifier(@WifiNanManager.DataPathRole int role,
+    public String createNetworkSpecifier(@WifiAwareManager.DataPathRole int role,
             @Nullable Object peerHandle, @Nullable byte[] token) {
         if (mTerminated) {
             Log.w(TAG, "createNetworkSpecifier: called on terminated session");
             return null;
         } else {
-            WifiNanManager mgr = mMgr.get();
+            WifiAwareManager mgr = mMgr.get();
             if (mgr == null) {
-                Log.w(TAG, "createNetworkSpecifier: called post GC on WifiNanManager");
+                Log.w(TAG, "createNetworkSpecifier: called post GC on WifiAwareManager");
                 return null;
             }
 
diff --git a/wifi/java/android/net/wifi/nan/WifiNanDiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java
similarity index 66%
rename from wifi/java/android/net/wifi/nan/WifiNanDiscoverySessionCallback.java
rename to wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java
index 271f420..9dfa24f 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanDiscoverySessionCallback.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -23,18 +23,20 @@
 import java.lang.annotation.RetentionPolicy;
 
 /**
- * Base class for NAN session events callbacks. Should be extended by
+ * Base class for Aware session events callbacks. Should be extended by
  * applications wanting notifications. The callbacks are set when a
  * publish or subscribe session is created using
- * {@link WifiNanSession#publish(android.os.Handler, PublishConfig, WifiNanDiscoverySessionCallback)}
+ * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig,
+ * WifiAwareDiscoverySessionCallback)}
  * or
- * {@link WifiNanSession#subscribe(android.os.Handler, SubscribeConfig, WifiNanDiscoverySessionCallback)} .
+ * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig,
+ * WifiAwareDiscoverySessionCallback)} .
  * <p>
  * A single callback is set at session creation - it cannot be replaced.
  *
- * @hide PROPOSED_NAN_API
+ * @hide PROPOSED_AWARE_API
  */
-public class WifiNanDiscoverySessionCallback {
+public class WifiAwareDiscoverySessionCallback {
     /** @hide */
     @IntDef({
             TERMINATE_REASON_DONE, TERMINATE_REASON_FAIL })
@@ -46,7 +48,7 @@
      * Indicates that publish or subscribe session is done - all the
      * requested operations (per {@link PublishConfig} or
      * {@link SubscribeConfig}) have been executed. Failure reason flag for
-     * {@link WifiNanDiscoverySessionCallback#onSessionTerminated(int)} callback.
+     * {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)} callback.
      */
     public static final int TERMINATE_REASON_DONE = 100;
 
@@ -54,39 +56,41 @@
      * Indicates that publish or subscribe session is terminated due to a
      * failure.
      * Failure reason flag for
-     * {@link WifiNanDiscoverySessionCallback#onSessionTerminated(int)} callback.
+     * {@link WifiAwareDiscoverySessionCallback#onSessionTerminated(int)} callback.
      */
     public static final int TERMINATE_REASON_FAIL = 101;
 
     /**
      * Called when a publish operation is started successfully in response to a
-     * {@link WifiNanSession#publish(android.os.Handler, PublishConfig, WifiNanDiscoverySessionCallback)}
+     * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig,
+     * WifiAwareDiscoverySessionCallback)}
      * operation.
      *
-     * @param session The {@link WifiNanPublishDiscoverySession} used to control the
+     * @param session The {@link WifiAwarePublishDiscoverySession} used to control the
      *            discovery session.
      */
-    public void onPublishStarted(@NonNull WifiNanPublishDiscoverySession session) {
+    public void onPublishStarted(@NonNull WifiAwarePublishDiscoverySession session) {
         /* empty */
     }
 
     /**
      * Called when a subscribe operation is started successfully in response to a
-     * {@link WifiNanSession#subscribe(android.os.Handler, SubscribeConfig, WifiNanDiscoverySessionCallback)}
+     * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig,
+     * WifiAwareDiscoverySessionCallback)}
      * operation.
      *
-     * @param session The {@link WifiNanSubscribeDiscoverySession} used to control the
+     * @param session The {@link WifiAwareSubscribeDiscoverySession} used to control the
      *            discovery session.
      */
-    public void onSubscribeStarted(@NonNull WifiNanSubscribeDiscoverySession session) {
+    public void onSubscribeStarted(@NonNull WifiAwareSubscribeDiscoverySession session) {
         /* empty */
     }
 
     /**
      * Called when a publish or subscribe discovery session configuration update request
      * succeeds. Called in response to
-     * {@link WifiNanPublishDiscoverySession#updatePublish(PublishConfig)} or
-     * {@link WifiNanSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
+     * {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)} or
+     * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
      */
     public void onSessionConfigUpdated() {
         /* empty */
@@ -94,12 +98,14 @@
 
     /**
      * Called when a publish or subscribe discovery session cannot be created:
-     * {@link WifiNanSession#publish(android.os.Handler, PublishConfig, WifiNanDiscoverySessionCallback)}
+     * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig,
+     * WifiAwareDiscoverySessionCallback)}
      * or
-     * {@link WifiNanSession#subscribe(android.os.Handler, SubscribeConfig, WifiNanDiscoverySessionCallback)},
+     * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig,
+     * WifiAwareDiscoverySessionCallback)},
      * or when a configuration update fails:
-     * {@link WifiNanPublishDiscoverySession#updatePublish(PublishConfig)} or
-     * {@link WifiNanSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
+     * {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)} or
+     * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
      * <p>
      *     For discovery session updates failure leaves the session running with its previous
      *     configuration - the discovery session is not terminated.
@@ -110,12 +116,12 @@
 
     /**
      * Called when a discovery session (publish or subscribe) terminates. Termination may be due
-     * to user-request (either directly through {@link WifiNanDiscoveryBaseSession#destroy()} or
+     * to user-request (either directly through {@link WifiAwareDiscoveryBaseSession#destroy()} or
      * application-specified expiration, e.g. {@link PublishConfig.Builder#setPublishCount(int)}
      * or {@link SubscribeConfig.Builder#setTtlSec(int)}) or due to a failure.
      *
      * @param reason The termination reason using
-     *            {@code WifiNanDiscoverySessionCallback.TERMINATE_*} codes.
+     *            {@code WifiAwareDiscoverySessionCallback.TERMINATE_*} codes.
      */
     public void onSessionTerminated(@SessionTerminateCodes int reason) {
         /* empty */
@@ -138,12 +144,12 @@
     }
 
     /**
-     * Called in response to {@link WifiNanDiscoveryBaseSession#sendMessage(Object, int, byte[])}
+     * Called in response to {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])}
      * when a message is transmitted successfully - i.e. when it was received successfully by the
      * peer (corresponds to an ACK being received).
      * <p>
      * Note that either this callback or
-     * {@link WifiNanDiscoverySessionCallback#onMessageSendFailed(int)} will be
+     * {@link WifiAwareDiscoverySessionCallback#onMessageSendFailed(int)} will be
      * received - never both.
      *
      * @param messageId The arbitrary message ID specified when sending the message.
@@ -154,12 +160,12 @@
 
     /**
      * Called when message transmission fails - when no ACK is received from the peer.
-     * Retries when ACKs are not received are done by hardware, MAC, and in the NAN stack (using
-     * the {@link WifiNanDiscoveryBaseSession#sendMessage(Object, int, byte[], int)} method) - this
-     * event is received after all retries are exhausted.
+     * Retries when ACKs are not received are done by hardware, MAC, and in the Aware stack (using
+     * the {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[], int)} method) -
+     * this event is received after all retries are exhausted.
      * <p>
      * Note that either this callback or
-     * {@link WifiNanDiscoverySessionCallback#onMessageSent(int)} will be received
+     * {@link WifiAwareDiscoverySessionCallback#onMessageSent(int)} will be received
      * - never both.
      *
      * @param messageId The arbitrary message ID specified when sending the message.
@@ -170,8 +176,8 @@
 
     /**
      * Called when a message is received from a discovery session peer - in response to the
-     * peer's {@link WifiNanDiscoveryBaseSession#sendMessage(Object, int, byte[])} or
-     * {@link WifiNanDiscoveryBaseSession#sendMessage(Object, int, byte[], int)}.
+     * peer's {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])} or
+     * {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[], int)}.
      *
      * @param peerHandle An opaque handle to the peer matching our discovery operation.
      * @param message A byte array containing the message.
diff --git a/wifi/java/android/net/wifi/nan/WifiNanIdentityChangedListener.java b/wifi/java/android/net/wifi/aware/WifiAwareIdentityChangedListener.java
similarity index 75%
rename from wifi/java/android/net/wifi/nan/WifiNanIdentityChangedListener.java
rename to wifi/java/android/net/wifi/aware/WifiAwareIdentityChangedListener.java
index 7cb928f..e8f52cd4 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanIdentityChangedListener.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareIdentityChangedListener.java
@@ -14,23 +14,23 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 /**
- * Base class for a listener which is called with the MAC address of the NAN interface whenever
+ * Base class for a listener which is called with the MAC address of the Aware interface whenever
  * it is changed. Change may be due to device joining a cluster, starting a cluster, or discovery
  * interface change (addresses are randomized at regular intervals). The implication is that
  * peers you've been communicating with may no longer recognize you and you need to re-establish
  * your identity - e.g. by starting a discovery session. This actual MAC address of the
- * interface may also be useful if the application uses alternative (non-NAN) discovery but needs
- * to set up a NAN connection. The provided NAN discovery interface MAC address can then be used
- * in {@link WifiNanSession#createNetworkSpecifier(int, byte[], byte[])}.
+ * interface may also be useful if the application uses alternative (non-Aware) discovery but needs
+ * to set up a Aware connection. The provided Aware discovery interface MAC address can then be used
+ * in {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])}.
  *
- * @hide PROPOSED_NAN_API
+ * @hide PROPOSED_AWARE_API
  */
-public class WifiNanIdentityChangedListener {
+public class WifiAwareIdentityChangedListener {
     /**
-     * @param mac The MAC address of the NAN discovery interface. The application must have the
+     * @param mac The MAC address of the Aware discovery interface. The application must have the
      * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} to get the actual MAC address,
      *            otherwise all 0's will be provided.
      */
diff --git a/wifi/java/android/net/wifi/nan/WifiNanManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
similarity index 76%
rename from wifi/java/android/net/wifi/nan/WifiNanManager.java
rename to wifi/java/android/net/wifi/aware/WifiAwareManager.java
index 002b953..5528ff8 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -48,80 +48,86 @@
 import java.util.Arrays;
 
 /**
- * This class provides the primary API for managing Wi-Fi NAN operations:
+ * This class provides the primary API for managing Wi-Fi Aware operations:
  * discovery and peer-to-peer data connections. Get an instance of this class by calling
  * {@link android.content.Context#getSystemService(String)
- * Context.getSystemService(Context.WIFI_NAN_SERVICE)}.
+ * Context.getSystemService(Context.WIFI_AWARE_SERVICE)}.
  * <p>
  * The class provides access to:
  * <ul>
- * <li>Initialize a NAN cluster (peer-to-peer synchronization). Refer to
- * {@link #attach(Handler, WifiNanAttachCallback)}.
+ * <li>Initialize a Aware cluster (peer-to-peer synchronization). Refer to
+ * {@link #attach(Handler, WifiAwareAttachCallback)}.
  * <li>Create discovery sessions (publish or subscribe sessions). Refer to
- * {@link WifiNanSession#publish(Handler, PublishConfig, WifiNanDiscoverySessionCallback)} and
- * {@link WifiNanSession#subscribe(Handler, SubscribeConfig, WifiNanDiscoverySessionCallback)}.
- * <li>Create a NAN network specifier to be used with
+ * {@link WifiAwareSession#publish(Handler, PublishConfig, WifiAwareDiscoverySessionCallback)} and
+ * {@link WifiAwareSession#subscribe(Handler, SubscribeConfig, WifiAwareDiscoverySessionCallback)}.
+ * <li>Create a Aware network specifier to be used with
  * {@link ConnectivityManager#requestNetwork(NetworkRequest, ConnectivityManager.NetworkCallback)}
- * to set-up a NAN connection with a peer. Refer to
- * {@link WifiNanDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])} and
- * {@link WifiNanSession#createNetworkSpecifier(int, byte[], byte[])}.
+ * to set-up a Aware connection with a peer. Refer to
+ * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])} and
+ * {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])}.
  * </ul>
  * <p>
- *     NAN may not be usable when Wi-Fi is disabled (and other conditions). To validate that
+ *     Aware may not be usable when Wi-Fi is disabled (and other conditions). To validate that
  *     the functionality is available use the {@link #isAvailable()} function. To track
- *     changes in NAN usability register for the {@link #ACTION_WIFI_NAN_STATE_CHANGED} broadcast.
- *     Note that this broadcast is not sticky - you should register for it and then check the
- *     above API to avoid a race condition.
+ *     changes in Aware usability register for the {@link #ACTION_WIFI_AWARE_STATE_CHANGED}
+ *     broadcast. Note that this broadcast is not sticky - you should register for it and then
+ *     check the above API to avoid a race condition.
  * <p>
- *     An application must use {@link #attach(Handler, WifiNanAttachCallback)} to initialize a NAN
- *     cluster - before making any other NAN operation. NAN cluster membership is a device-wide
- *     operation - the API guarantees that the device is in a cluster or joins a NAN cluster (or
- *     starts one if none can be found). Information about attach success (or failure) are
- *     returned in callbacks of {@link WifiNanAttachCallback}. Proceed with NAN discovery or
- *     connection setup only after receiving confirmation that NAN attach succeeded -
- *     {@link WifiNanAttachCallback#onAttached(WifiNanSession)}. When an application is
- *     finished using NAN it <b>must</b> use the {@link WifiNanSession#destroy()} API
- *     to indicate to the NAN service that the device may detach from the NAN cluster. The
- *     device will actually disable NAN once the last application detaches.
+ *     An application must use {@link #attach(Handler, WifiAwareAttachCallback)} to initialize a
+ *     Aware cluster - before making any other Aware operation. Aware cluster membership is a
+ *     device-wide operation - the API guarantees that the device is in a cluster or joins a
+ *     Aware cluster (or starts one if none can be found). Information about attach success (or
+ *     failure) are returned in callbacks of {@link WifiAwareAttachCallback}. Proceed with Aware
+ *     discovery or connection setup only after receiving confirmation that Aware attach
+ *     succeeded - {@link WifiAwareAttachCallback#onAttached(WifiAwareSession)}. When an
+ *     application is finished using Aware it <b>must</b> use the
+ *     {@link WifiAwareSession#destroy()} API to indicate to the Aware service that the device
+ *     may detach from the Aware cluster. The device will actually disable Aware once the last
+ *     application detaches.
  * <p>
- *     Once a NAN attach is confirmed use the
- *     {@link WifiNanSession#publish(Handler, PublishConfig, WifiNanDiscoverySessionCallback)} or
- *     {@link WifiNanSession#subscribe(Handler, SubscribeConfig, WifiNanDiscoverySessionCallback)}
- *     to create publish or subscribe NAN discovery sessions. Events are called on the provided
- *     callback object {@link WifiNanDiscoverySessionCallback}. Specifically, the
- *     {@link WifiNanDiscoverySessionCallback#onPublishStarted(WifiNanPublishDiscoverySession)}
+ *     Once a Aware attach is confirmed use the
+ *     {@link WifiAwareSession#publish(Handler, PublishConfig, WifiAwareDiscoverySessionCallback)}
+ *     or
+ *     {@link WifiAwareSession#subscribe(Handler, SubscribeConfig,
+ *     WifiAwareDiscoverySessionCallback)}
+ *     to create publish or subscribe Aware discovery sessions. Events are called on the provided
+ *     callback object {@link WifiAwareDiscoverySessionCallback}. Specifically, the
+ *     {@link WifiAwareDiscoverySessionCallback#onPublishStarted(WifiAwarePublishDiscoverySession)}
  *     and
- *     {@link WifiNanDiscoverySessionCallback#onSubscribeStarted(WifiNanSubscribeDiscoverySession)}
- *     return {@link WifiNanPublishDiscoverySession} and {@link WifiNanSubscribeDiscoverySession}
+ *     {@link WifiAwareDiscoverySessionCallback#onSubscribeStarted(
+ *     WifiAwareSubscribeDiscoverySession)}
+ *     return {@link WifiAwarePublishDiscoverySession} and
+ *     {@link WifiAwareSubscribeDiscoverySession}
  *     objects respectively on which additional session operations can be performed, e.g. updating
- *     the session {@link WifiNanPublishDiscoverySession#updatePublish(PublishConfig)} and
- *     {@link WifiNanSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}. Sessions can also
- *     be used to send messages using the
- *     {@link WifiNanDiscoveryBaseSession#sendMessage(Object, int, byte[])} APIs. When an
+ *     the session {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)} and
+ *     {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}. Sessions can
+ *     also be used to send messages using the
+ *     {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])} APIs. When an
  *     application is finished with a discovery session it <b>must</b> terminate it using the
- *     {@link WifiNanDiscoveryBaseSession#destroy()} API.
+ *     {@link WifiAwareDiscoveryBaseSession#destroy()} API.
  * <p>
- *    Creating connections between NAN devices is managed by the standard
- *    {@link ConnectivityManager#requestNetwork(NetworkRequest, ConnectivityManager.NetworkCallback)}.
+ *    Creating connections between Aware devices is managed by the standard
+ *    {@link ConnectivityManager#requestNetwork(NetworkRequest,
+ *    ConnectivityManager.NetworkCallback)}.
  *    The {@link NetworkRequest} object should be constructed with:
  *    <ul>
  *        <li>{@link NetworkRequest.Builder#addTransportType(int)} of
- *        {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_NAN}.
+ *        {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
  *        <li>{@link NetworkRequest.Builder#setNetworkSpecifier(String)} using
- *        {@link WifiNanSession#createNetworkSpecifier(int, byte[], byte[])} or
- *        {@link WifiNanDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])}.
+ *        {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])} or
+ *        {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])}.
  *    </ul>
  *
- * @hide PROPOSED_NAN_API
+ * @hide PROPOSED_AWARE_API
  */
-public class WifiNanManager {
-    private static final String TAG = "WifiNanManager";
+public class WifiAwareManager {
+    private static final String TAG = "WifiAwareManager";
     private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
     /**
-     * Keys used to generate a Network Specifier for the NAN network request. The network specifier
-     * is formatted as a JSON string.
+     * Keys used to generate a Network Specifier for the Aware network request. The network
+     * specifier is formatted as a JSON string.
      */
 
     /**
@@ -197,44 +203,44 @@
     public static final String NETWORK_SPECIFIER_KEY_TOKEN = "token";
 
     /**
-     * Broadcast intent action to indicate that the state of Wi-Fi NAN availability has changed.
+     * Broadcast intent action to indicate that the state of Wi-Fi Aware availability has changed.
      * Use the {@link #isAvailable()} to query the current status.
      * This broadcast is <b>not</b> sticky, use the {@link #isAvailable()} API after registering
-     * the broadcast to check the current state of Wi-Fi NAN.
+     * the broadcast to check the current state of Wi-Fi Aware.
      * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
      * components will be launched.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_WIFI_NAN_STATE_CHANGED =
-            "android.net.wifi.nan.action.WIFI_NAN_STATE_CHANGED";
+    public static final String ACTION_WIFI_AWARE_STATE_CHANGED =
+            "android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED";
 
     /** @hide */
     @IntDef({
-            WIFI_NAN_DATA_PATH_ROLE_INITIATOR, WIFI_NAN_DATA_PATH_ROLE_RESPONDER})
+            WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, WIFI_AWARE_DATA_PATH_ROLE_RESPONDER})
     @Retention(RetentionPolicy.SOURCE)
     public @interface DataPathRole {
     }
 
     /**
      * Connection creation role is that of INITIATOR. Used to create a network specifier string
-     * when requesting a NAN network.
+     * when requesting a Aware network.
      *
-     * @see WifiNanDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])
-     * @see WifiNanSession#createNetworkSpecifier(int, byte[], byte[])
+     * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])
+     * @see WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])
      */
-    public static final int WIFI_NAN_DATA_PATH_ROLE_INITIATOR = 0;
+    public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0;
 
     /**
      * Connection creation role is that of RESPONDER. Used to create a network specifier string
-     * when requesting a NAN network.
+     * when requesting a Aware network.
      *
-     * @see WifiNanDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])
-     * @see WifiNanSession#createNetworkSpecifier(int, byte[], byte[])
+     * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])
+     * @see WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])
      */
-    public static final int WIFI_NAN_DATA_PATH_ROLE_RESPONDER = 1;
+    public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1;
 
     private final Context mContext;
-    private final IWifiNanManager mService;
+    private final IWifiAwareManager mService;
 
     private final Object mLock = new Object(); // lock access to the following vars
 
@@ -242,14 +248,14 @@
     private SparseArray<RttManager.RttListener> mRangingListeners = new SparseArray<>();
 
     /** @hide */
-    public WifiNanManager(Context context, IWifiNanManager service) {
+    public WifiAwareManager(Context context, IWifiAwareManager service) {
         mContext = context;
         mService = service;
     }
 
     /**
-     * Enable the usage of the NAN API. Doesn't actually turn on NAN cluster formation - that
-     * only happens when an attach is attempted. {@link #ACTION_WIFI_NAN_STATE_CHANGED} broadcast
+     * Enable the usage of the Aware API. Doesn't actually turn on Aware cluster formation - that
+     * only happens when an attach is attempted. {@link #ACTION_WIFI_AWARE_STATE_CHANGED} broadcast
      * will be triggered.
      *
      * @hide
@@ -263,9 +269,9 @@
     }
 
     /**
-     * Disable the usage of the NAN API. All attempts to attach() will be rejected. All open
-     * connections and sessions will be terminated. {@link #ACTION_WIFI_NAN_STATE_CHANGED} broadcast
-     * will be triggered.
+     * Disable the usage of the Aware API. All attempts to attach() will be rejected. All open
+     * connections and sessions will be terminated. {@link #ACTION_WIFI_AWARE_STATE_CHANGED}
+     * broadcast will be triggered.
      *
      * @hide
      */
@@ -278,10 +284,11 @@
     }
 
     /**
-     * Returns the current status of NAN API: whether or not NAN is available. To track changes
-     * in the state of NAN API register for the {@link #ACTION_WIFI_NAN_STATE_CHANGED} broadcast.
+     * Returns the current status of Aware API: whether or not Aware is available. To track
+     * changes in the state of Aware API register for the
+     * {@link #ACTION_WIFI_AWARE_STATE_CHANGED} broadcast.
      *
-     * @return A boolean indicating whether the app can use the NAN API at this time (true) or
+     * @return A boolean indicating whether the app can use the Aware API at this time (true) or
      * not (false).
      */
     public boolean isAvailable() {
@@ -293,12 +300,12 @@
     }
 
     /**
-     * Returns the characteristics of the Wi-Fi NAN interface: a set of parameters which specify
+     * Returns the characteristics of the Wi-Fi Aware interface: a set of parameters which specify
      * limitations on configurations, e.g. the maximum service name length.
      *
-     * @return An object specifying configuration limitations of NAN.
+     * @return An object specifying configuration limitations of Aware.
      */
-    public WifiNanCharacteristics getCharacteristics() {
+    public WifiAwareCharacteristics getCharacteristics() {
         try {
             return mService.getCharacteristics();
         } catch (RemoteException e) {
@@ -307,14 +314,14 @@
     }
 
     /**
-     * Attach to the Wi-Fi NAN service - enabling the application to create discovery sessions or
+     * Attach to the Wi-Fi Aware service - enabling the application to create discovery sessions or
      * create connections to peers. The device will attach to an existing cluster if it can find
-     * one or create a new cluster (if it is the first to enable NAN in its vicinity). Results
+     * one or create a new cluster (if it is the first to enable Aware in its vicinity). Results
      * (e.g. successful attach to a cluster) are provided to the {@code attachCallback} object.
-     * An application <b>must</b> call {@link WifiNanSession#destroy()} when done with the
-     * Wi-Fi NAN object.
+     * An application <b>must</b> call {@link WifiAwareSession#destroy()} when done with the
+     * Wi-Fi Aware object.
      * <p>
-     * Note: a NAN cluster is a shared resource - if the device is already attached to a cluster
+     * Note: a Aware cluster is a shared resource - if the device is already attached to a cluster
      * then this function will simply indicate success immediately using the same {@code
      * attachCallback}.
      *
@@ -322,29 +329,29 @@
      * attachCallback} object. If a null is provided then the application's main thread will be
      *                used.
      * @param attachCallback A callback for attach events, extended from
-     * {@link WifiNanAttachCallback}.
+     * {@link WifiAwareAttachCallback}.
      */
-    public void attach(@Nullable Handler handler, @NonNull WifiNanAttachCallback attachCallback) {
+    public void attach(@Nullable Handler handler, @NonNull WifiAwareAttachCallback attachCallback) {
         attach(handler, null, attachCallback, null);
     }
 
     /**
-     * Attach to the Wi-Fi NAN service - enabling the application to create discovery sessions or
+     * Attach to the Wi-Fi Aware service - enabling the application to create discovery sessions or
      * create connections to peers. The device will attach to an existing cluster if it can find
-     * one or create a new cluster (if it is the first to enable NAN in its vicinity). Results
+     * one or create a new cluster (if it is the first to enable Aware in its vicinity). Results
      * (e.g. successful attach to a cluster) are provided to the {@code attachCallback} object.
-     * An application <b>must</b> call {@link WifiNanSession#destroy()} when done with the
-     * Wi-Fi NAN object.
+     * An application <b>must</b> call {@link WifiAwareSession#destroy()} when done with the
+     * Wi-Fi Aware object.
      * <p>
-     * Note: a NAN cluster is a shared resource - if the device is already attached to a cluster
+     * Note: a Aware cluster is a shared resource - if the device is already attached to a cluster
      * then this function will simply indicate success immediately using the same {@code
      * attachCallback}.
      * <p>
-     * This version of the API attaches a listener to receive the MAC address of the NAN interface
+     * This version of the API attaches a listener to receive the MAC address of the Aware interface
      * on startup and whenever it is updated (it is randomized at regular intervals for privacy).
      * The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
      * permission to execute this attach request. Otherwise, use the
-     * {@link #attach(Handler, WifiNanAttachCallback)} version. Note that aside from permission
+     * {@link #attach(Handler, WifiAwareAttachCallback)} version. Note that aside from permission
      * requirements this listener will wake up the host at regular intervals causing higher power
      * consumption, do not use it unless the information is necessary (e.g. for OOB discovery).
      *
@@ -352,19 +359,19 @@
      * attachCallback} and {@code identityChangedListener} objects. If a null is provided then the
      *                application's main thread will be used.
      * @param attachCallback A callback for attach events, extended from
-     * {@link WifiNanAttachCallback}.
+     * {@link WifiAwareAttachCallback}.
      * @param identityChangedListener A listener for changed identity, extended from
-     * {@link WifiNanIdentityChangedListener}.
+     * {@link WifiAwareIdentityChangedListener}.
      */
-    public void attach(@Nullable Handler handler, @NonNull WifiNanAttachCallback attachCallback,
-            @NonNull WifiNanIdentityChangedListener identityChangedListener) {
+    public void attach(@Nullable Handler handler, @NonNull WifiAwareAttachCallback attachCallback,
+            @NonNull WifiAwareIdentityChangedListener identityChangedListener) {
         attach(handler, null, attachCallback, identityChangedListener);
     }
 
     /** @hide */
     public void attach(Handler handler, ConfigRequest configRequest,
-            WifiNanAttachCallback attachCallback,
-            WifiNanIdentityChangedListener identityChangedListener) {
+            WifiAwareAttachCallback attachCallback,
+            WifiAwareIdentityChangedListener identityChangedListener) {
         if (VDBG) {
             Log.v(TAG, "attach(): handler=" + handler + ", callback=" + attachCallback
                     + ", configRequest=" + configRequest + ", identityChangedListener="
@@ -377,7 +384,7 @@
             try {
                 Binder binder = new Binder();
                 mService.connect(binder, mContext.getOpPackageName(),
-                        new WifiNanEventCallbackProxy(this, looper, binder, attachCallback,
+                        new WifiAwareEventCallbackProxy(this, looper, binder, attachCallback,
                                 identityChangedListener), configRequest,
                         identityChangedListener != null);
             } catch (RemoteException e) {
@@ -399,12 +406,12 @@
 
     /** @hide */
     public void publish(int clientId, Looper looper, PublishConfig publishConfig,
-            WifiNanDiscoverySessionCallback callback) {
+            WifiAwareDiscoverySessionCallback callback) {
         if (VDBG) Log.v(TAG, "publish(): clientId=" + clientId + ", config=" + publishConfig);
 
         try {
             mService.publish(clientId, publishConfig,
-                    new WifiNanDiscoverySessionCallbackProxy(this, looper, true, callback,
+                    new WifiAwareDiscoverySessionCallbackProxy(this, looper, true, callback,
                             clientId));
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -427,7 +434,7 @@
 
     /** @hide */
     public void subscribe(int clientId, Looper looper, SubscribeConfig subscribeConfig,
-            WifiNanDiscoverySessionCallback callback) {
+            WifiAwareDiscoverySessionCallback callback) {
         if (VDBG) {
             if (VDBG) {
                 Log.v(TAG,
@@ -437,7 +444,7 @@
 
         try {
             mService.subscribe(clientId, subscribeConfig,
-                    new WifiNanDiscoverySessionCallbackProxy(this, looper, false, callback,
+                    new WifiAwareDiscoverySessionCallbackProxy(this, looper, false, callback,
                             clientId));
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -535,13 +542,13 @@
             type = NETWORK_SPECIFIER_TYPE_1D;
         }
 
-        if (role != WIFI_NAN_DATA_PATH_ROLE_INITIATOR
-                && role != WIFI_NAN_DATA_PATH_ROLE_RESPONDER) {
+        if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
+                && role != WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
             throw new IllegalArgumentException(
                     "createNetworkSpecifier: Invalid 'role' argument when creating a network "
                             + "specifier");
         }
-        if (role == WIFI_NAN_DATA_PATH_ROLE_INITIATOR) {
+        if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR) {
             if (token == null) {
                 throw new IllegalArgumentException(
                         "createNetworkSpecifier: Invalid null token - not permitted on INITIATOR");
@@ -592,13 +599,13 @@
             type = NETWORK_SPECIFIER_TYPE_2D;
         }
 
-        if (role != WIFI_NAN_DATA_PATH_ROLE_INITIATOR
-                && role != WIFI_NAN_DATA_PATH_ROLE_RESPONDER) {
+        if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
+                && role != WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
             throw new IllegalArgumentException(
                     "createNetworkSpecifier: Invalid 'role' argument when creating a network "
                             + "specifier");
         }
-        if (role == WIFI_NAN_DATA_PATH_ROLE_INITIATOR) {
+        if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR) {
             if (peer == null || peer.length != 6) {
                 throw new IllegalArgumentException(
                         "createNetworkSpecifier: Invalid peer MAC address");
@@ -634,7 +641,7 @@
         return json.toString();
     }
 
-    private static class WifiNanEventCallbackProxy extends IWifiNanEventCallback.Stub {
+    private static class WifiAwareEventCallbackProxy extends IWifiAwareEventCallback.Stub {
         private static final int CALLBACK_CONNECT_SUCCESS = 0;
         private static final int CALLBACK_CONNECT_FAIL = 1;
         private static final int CALLBACK_IDENTITY_CHANGED = 2;
@@ -643,12 +650,12 @@
         private static final int CALLBACK_RANGING_ABORTED = 5;
 
         private final Handler mHandler;
-        private final WeakReference<WifiNanManager> mNanManager;
+        private final WeakReference<WifiAwareManager> mAwareManager;
         private final Binder mBinder;
         private final Looper mLooper;
 
         RttManager.RttListener getAndRemoveRangingListener(int rangingId) {
-            WifiNanManager mgr = mNanManager.get();
+            WifiAwareManager mgr = mAwareManager.get();
             if (mgr == null) {
                 Log.w(TAG, "getAndRemoveRangingListener: called post GC");
                 return null;
@@ -662,39 +669,40 @@
         }
 
         /**
-         * Constructs a {@link WifiNanAttachCallback} using the specified looper.
+         * Constructs a {@link WifiAwareAttachCallback} using the specified looper.
          * All callbacks will delivered on the thread of the specified looper.
          *
          * @param looper The looper on which to execute the callbacks.
          */
-        WifiNanEventCallbackProxy(WifiNanManager mgr, Looper looper, Binder binder,
-                final WifiNanAttachCallback attachCallback,
-                final WifiNanIdentityChangedListener identityChangedListener) {
-            mNanManager = new WeakReference<>(mgr);
+        WifiAwareEventCallbackProxy(WifiAwareManager mgr, Looper looper, Binder binder,
+                final WifiAwareAttachCallback attachCallback,
+                final WifiAwareIdentityChangedListener identityChangedListener) {
+            mAwareManager = new WeakReference<>(mgr);
             mLooper = looper;
             mBinder = binder;
 
-            if (VDBG) Log.v(TAG, "WifiNanEventCallbackProxy ctor: looper=" + looper);
+            if (VDBG) Log.v(TAG, "WifiAwareEventCallbackProxy ctor: looper=" + looper);
             mHandler = new Handler(looper) {
                 @Override
                 public void handleMessage(Message msg) {
                     if (DBG) {
-                        Log.d(TAG, "WifiNanEventCallbackProxy: What=" + msg.what + ", msg=" + msg);
+                        Log.d(TAG, "WifiAwareEventCallbackProxy: What=" + msg.what + ", msg="
+                                + msg);
                     }
 
-                    WifiNanManager mgr = mNanManager.get();
+                    WifiAwareManager mgr = mAwareManager.get();
                     if (mgr == null) {
-                        Log.w(TAG, "WifiNanEventCallbackProxy: handleMessage post GC");
+                        Log.w(TAG, "WifiAwareEventCallbackProxy: handleMessage post GC");
                         return;
                     }
 
                     switch (msg.what) {
                         case CALLBACK_CONNECT_SUCCESS:
                             attachCallback.onAttached(
-                                    new WifiNanSession(mgr, mBinder, msg.arg1));
+                                    new WifiAwareSession(mgr, mBinder, msg.arg1));
                             break;
                         case CALLBACK_CONNECT_FAIL:
-                            mNanManager.clear();
+                            mAwareManager.clear();
                             attachCallback.onAttachFailed();
                             break;
                         case CALLBACK_IDENTITY_CHANGED:
@@ -801,8 +809,8 @@
         }
     }
 
-    private static class WifiNanDiscoverySessionCallbackProxy extends
-            IWifiNanDiscoverySessionCallback.Stub {
+    private static class WifiAwareDiscoverySessionCallbackProxy extends
+            IWifiAwareDiscoverySessionCallback.Stub {
         private static final int CALLBACK_SESSION_STARTED = 0;
         private static final int CALLBACK_SESSION_CONFIG_SUCCESS = 1;
         private static final int CALLBACK_SESSION_CONFIG_FAIL = 2;
@@ -815,23 +823,24 @@
         private static final String MESSAGE_BUNDLE_KEY_MESSAGE = "message";
         private static final String MESSAGE_BUNDLE_KEY_MESSAGE2 = "message2";
 
-        private final WeakReference<WifiNanManager> mNanManager;
+        private final WeakReference<WifiAwareManager> mAwareManager;
         private final boolean mIsPublish;
-        private final WifiNanDiscoverySessionCallback mOriginalCallback;
+        private final WifiAwareDiscoverySessionCallback mOriginalCallback;
         private final int mClientId;
 
         private final Handler mHandler;
-        private WifiNanDiscoveryBaseSession mSession;
+        private WifiAwareDiscoveryBaseSession mSession;
 
-        WifiNanDiscoverySessionCallbackProxy(WifiNanManager mgr, Looper looper, boolean isPublish,
-                WifiNanDiscoverySessionCallback originalCallback, int clientId) {
-            mNanManager = new WeakReference<>(mgr);
+        WifiAwareDiscoverySessionCallbackProxy(WifiAwareManager mgr, Looper looper,
+                boolean isPublish, WifiAwareDiscoverySessionCallback originalCallback,
+                int clientId) {
+            mAwareManager = new WeakReference<>(mgr);
             mIsPublish = isPublish;
             mOriginalCallback = originalCallback;
             mClientId = clientId;
 
             if (VDBG) {
-                Log.v(TAG, "WifiNanDiscoverySessionCallbackProxy ctor: isPublish=" + isPublish);
+                Log.v(TAG, "WifiAwareDiscoverySessionCallbackProxy ctor: isPublish=" + isPublish);
             }
 
             mHandler = new Handler(looper) {
@@ -839,8 +848,8 @@
                 public void handleMessage(Message msg) {
                     if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
 
-                    if (mNanManager.get() == null) {
-                        Log.w(TAG, "WifiNanDiscoverySessionCallbackProxy: handleMessage post GC");
+                    if (mAwareManager.get() == null) {
+                        Log.w(TAG, "WifiAwareDiscoverySessionCallbackProxy: handleMessage post GC");
                         return;
                     }
 
@@ -858,7 +867,7 @@
                                  * creation failed (as opposed to update
                                  * failing)
                                  */
-                                mNanManager.clear();
+                                mAwareManager.clear();
                             }
                             break;
                         case CALLBACK_SESSION_TERMINATED:
@@ -977,20 +986,20 @@
                         "onSessionStarted: sessionId=" + sessionId + ": session already created!?");
             }
 
-            WifiNanManager mgr = mNanManager.get();
+            WifiAwareManager mgr = mAwareManager.get();
             if (mgr == null) {
                 Log.w(TAG, "onProxySessionStarted: mgr GC'd");
                 return;
             }
 
             if (mIsPublish) {
-                WifiNanPublishDiscoverySession session = new WifiNanPublishDiscoverySession(mgr,
+                WifiAwarePublishDiscoverySession session = new WifiAwarePublishDiscoverySession(mgr,
                         mClientId, sessionId);
                 mSession = session;
                 mOriginalCallback.onPublishStarted(session);
             } else {
-                WifiNanSubscribeDiscoverySession
-                        session = new WifiNanSubscribeDiscoverySession(mgr, mClientId, sessionId);
+                WifiAwareSubscribeDiscoverySession
+                        session = new WifiAwareSubscribeDiscoverySession(mgr, mClientId, sessionId);
                 mSession = session;
                 mOriginalCallback.onSubscribeStarted(session);
             }
@@ -1004,7 +1013,7 @@
             } else {
                 Log.w(TAG, "Proxy: onSessionTerminated called but mSession is null!?");
             }
-            mNanManager.clear();
+            mAwareManager.clear();
             mOriginalCallback.onSessionTerminated(reason);
         }
     }
diff --git a/wifi/java/android/net/wifi/nan/WifiNanPublishDiscoverySession.java b/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java
similarity index 65%
rename from wifi/java/android/net/wifi/nan/WifiNanPublishDiscoverySession.java
rename to wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java
index 75c6cb7..610a92c 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanPublishDiscoverySession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java
@@ -14,39 +14,40 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 import android.annotation.NonNull;
 import android.util.Log;
 
 /**
- * A class representing a NAN publish session. Created when
- * {@link WifiNanSession#publish(android.os.Handler, PublishConfig, WifiNanDiscoverySessionCallback)}
+ * A class representing a Aware publish session. Created when
+ * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig,
+ * WifiAwareDiscoverySessionCallback)}
  * is called and a discovery session is created and returned in
- * {@link WifiNanDiscoverySessionCallback#onPublishStarted(WifiNanPublishDiscoverySession)}. See
- * baseline functionality of all discovery sessions in {@link WifiNanDiscoveryBaseSession}. This
+ * {@link WifiAwareDiscoverySessionCallback#onPublishStarted(WifiAwarePublishDiscoverySession)}. See
+ * baseline functionality of all discovery sessions in {@link WifiAwareDiscoveryBaseSession}. This
  * object allows updating an existing/running publish discovery session using
  * {@link #updatePublish(PublishConfig)}.
  *
- * @hide PROPOSED_NAN_API
+ * @hide PROPOSED_AWARE_API
  */
-public class WifiNanPublishDiscoverySession extends WifiNanDiscoveryBaseSession {
-    private static final String TAG = "WifiNanPublishDiscSsn";
+public class WifiAwarePublishDiscoverySession extends WifiAwareDiscoveryBaseSession {
+    private static final String TAG = "WifiAwarePublishDiscSsn";
 
     /** @hide */
-    public WifiNanPublishDiscoverySession(WifiNanManager manager, int clientId, int sessionId) {
+    public WifiAwarePublishDiscoverySession(WifiAwareManager manager, int clientId, int sessionId) {
         super(manager, clientId, sessionId);
     }
 
     /**
      * Re-configure the currently active publish session. The
-     * {@link WifiNanDiscoverySessionCallback} is not replaced - the same listener used
+     * {@link WifiAwareDiscoverySessionCallback} is not replaced - the same listener used
      * at creation is still used. The results of the configuration are returned using
-     * {@link WifiNanDiscoverySessionCallback}:
+     * {@link WifiAwareDiscoverySessionCallback}:
      * <ul>
-     *     <li>{@link WifiNanDiscoverySessionCallback#onSessionConfigUpdated()}: configuration
+     *     <li>{@link WifiAwareDiscoverySessionCallback#onSessionConfigUpdated()}: configuration
      *     update succeeded.
-     *     <li>{@link WifiNanDiscoverySessionCallback#onSessionConfigFailed()}: configuration
+     *     <li>{@link WifiAwareDiscoverySessionCallback#onSessionConfigFailed()}: configuration
      *     update failed. The publish discovery session is still running using its previous
      *     configuration (i.e. update failure does not terminate the session).
      * </ul>
@@ -58,9 +59,9 @@
             Log.w(TAG, "updatePublish: called on terminated session");
             return;
         } else {
-            WifiNanManager mgr = mMgr.get();
+            WifiAwareManager mgr = mMgr.get();
             if (mgr == null) {
-                Log.w(TAG, "updatePublish: called post GC on WifiNanManager");
+                Log.w(TAG, "updatePublish: called post GC on WifiAwareManager");
                 return;
             }
 
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
similarity index 66%
rename from wifi/java/android/net/wifi/nan/WifiNanSession.java
rename to wifi/java/android/net/wifi/aware/WifiAwareSession.java
index df5e3c1..357bd43 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanSession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.net.NetworkRequest;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.Looper;
@@ -29,17 +28,17 @@
 import java.lang.ref.WeakReference;
 
 /**
- * This class represents a Wi-Fi NAN session - an attachment to the Wi-Fi NAN service through
+ * This class represents a Wi-Fi Aware session - an attachment to the Wi-Fi Aware service through
  * which the app can execute discovery operations.
  *
- * @hide PROPOSED_NAN_API
+ * @hide PROPOSED_AWARE_API
  */
-public class WifiNanSession {
-    private static final String TAG = "WifiNanSession";
+public class WifiAwareSession {
+    private static final String TAG = "WifiAwareSession";
     private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
-    private final WeakReference<WifiNanManager> mMgr;
+    private final WeakReference<WifiAwareManager> mMgr;
     private final Binder mBinder;
     private final int mClientId;
 
@@ -47,7 +46,7 @@
     private final CloseGuard mCloseGuard = CloseGuard.get();
 
     /** @hide */
-    public WifiNanSession(WifiNanManager manager, Binder binder, int clientId) {
+    public WifiAwareSession(WifiAwareManager manager, Binder binder, int clientId) {
         if (VDBG) Log.v(TAG, "New session created: manager=" + manager + ", clientId=" + clientId);
 
         mMgr = new WeakReference<>(manager);
@@ -59,19 +58,19 @@
     }
 
     /**
-     * Destroy the Wi-Fi NAN service session and, if no other applications are attached to NAN,
-     * also disable NAN. This method destroys all outstanding operations - i.e. all publish and
+     * Destroy the Wi-Fi Aware service session and, if no other applications are attached to Aware,
+     * also disable Aware. This method destroys all outstanding operations - i.e. all publish and
      * subscribes are terminated, and any outstanding data-links are shut-down. However, it is
      * good practice to destroy these discovery sessions and connections explicitly before a
      * session-wide destroy.
      * <p>
      * An application may re-attach after a destroy using
-     * {@link WifiNanManager#attach(Handler, WifiNanAttachCallback)} .
+     * {@link WifiAwareManager#attach(Handler, WifiAwareAttachCallback)} .
      */
     public void destroy() {
-        WifiNanManager mgr = mMgr.get();
+        WifiAwareManager mgr = mMgr.get();
         if (mgr == null) {
-            Log.w(TAG, "destroy: called post GC on WifiNanManager");
+            Log.w(TAG, "destroy: called post GC on WifiAwareManager");
             return;
         }
         mgr.disconnect(mClientId, mBinder);
@@ -94,23 +93,24 @@
     }
 
     /**
-     * Issue a request to the NAN service to create a new NAN publish discovery session, using
+     * Issue a request to the Aware service to create a new Aware publish discovery session, using
      * the specified {@code publishConfig} configuration. The results of the publish operation
-     * are routed to the callbacks of {@link WifiNanDiscoverySessionCallback}:
+     * are routed to the callbacks of {@link WifiAwareDiscoverySessionCallback}:
      * <ul>
      *     <li>
-     *     {@link WifiNanDiscoverySessionCallback#onPublishStarted(WifiNanPublishDiscoverySession)}
+     *     {@link WifiAwareDiscoverySessionCallback#onPublishStarted(
+     *     WifiAwarePublishDiscoverySession)}
      *     is called when the publish session is created and provides a handle to the session.
      *     Further operations on the publish session can be executed on that object.
-     *     <li>{@link WifiNanDiscoverySessionCallback#onSessionConfigFailed()} is called if the
+     *     <li>{@link WifiAwareDiscoverySessionCallback#onSessionConfigFailed()} is called if the
      *     publish operation failed.
      * </ul>
      * <p>
      * Other results of the publish session operations will also be routed to callbacks
      * on the {@code callback} object. The resulting publish session can be modified using
-     * {@link WifiNanPublishDiscoverySession#updatePublish(PublishConfig)}.
+     * {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)}.
      * <p>
-     *      An application must use the {@link WifiNanDiscoveryBaseSession#destroy()} to
+     *      An application must use the {@link WifiAwareDiscoveryBaseSession#destroy()} to
      *      terminate the publish discovery session once it isn't needed. This will free
      *      resources as well terminate any on-air transmissions.
      * <p>The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
@@ -120,14 +120,14 @@
      * callback} object. If a null is provided then the application's main thread will be used.
      * @param publishConfig The {@link PublishConfig} specifying the
      *            configuration of the requested publish session.
-     * @param callback A {@link WifiNanDiscoverySessionCallback} derived object to be used for
+     * @param callback A {@link WifiAwareDiscoverySessionCallback} derived object to be used for
      *                 session event callbacks.
      */
     public void publish(@Nullable Handler handler, @NonNull PublishConfig publishConfig,
-            @NonNull WifiNanDiscoverySessionCallback callback) {
-        WifiNanManager mgr = mMgr.get();
+            @NonNull WifiAwareDiscoverySessionCallback callback) {
+        WifiAwareManager mgr = mMgr.get();
         if (mgr == null) {
-            Log.e(TAG, "publish: called post GC on WifiNanManager");
+            Log.e(TAG, "publish: called post GC on WifiAwareManager");
             return;
         }
         if (mTerminated) {
@@ -139,23 +139,24 @@
     }
 
     /**
-     * Issue a request to the NAN service to create a new NAN subscribe discovery session, using
+     * Issue a request to the Aware service to create a new Aware subscribe discovery session, using
      * the specified {@code subscribeConfig} configuration. The results of the subscribe
-     * operation are routed to the callbacks of {@link WifiNanDiscoverySessionCallback}:
+     * operation are routed to the callbacks of {@link WifiAwareDiscoverySessionCallback}:
      * <ul>
      *     <li>
-     *  {@link WifiNanDiscoverySessionCallback#onSubscribeStarted(WifiNanSubscribeDiscoverySession)}
+     *  {@link WifiAwareDiscoverySessionCallback#onSubscribeStarted(
+     *  WifiAwareSubscribeDiscoverySession)}
      *     is called when the subscribe session is created and provides a handle to the session.
      *     Further operations on the subscribe session can be executed on that object.
-     *     <li>{@link WifiNanDiscoverySessionCallback#onSessionConfigFailed()} is called if the
+     *     <li>{@link WifiAwareDiscoverySessionCallback#onSessionConfigFailed()} is called if the
      *     subscribe operation failed.
      * </ul>
      * <p>
      * Other results of the subscribe session operations will also be routed to callbacks
      * on the {@code callback} object. The resulting subscribe session can be modified using
-     * {@link WifiNanSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
+     * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}.
      * <p>
-     *      An application must use the {@link WifiNanDiscoveryBaseSession#destroy()} to
+     *      An application must use the {@link WifiAwareDiscoveryBaseSession#destroy()} to
      *      terminate the subscribe discovery session once it isn't needed. This will free
      *      resources as well terminate any on-air transmissions.
      * <p>The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
@@ -165,14 +166,14 @@
      * callback} object. If a null is provided then the application's main thread will be used.
      * @param subscribeConfig The {@link SubscribeConfig} specifying the
      *            configuration of the requested subscribe session.
-     * @param callback A {@link WifiNanDiscoverySessionCallback} derived object to be used for
+     * @param callback A {@link WifiAwareDiscoverySessionCallback} derived object to be used for
      *                 session event callbacks.
      */
     public void subscribe(@Nullable Handler handler, @NonNull SubscribeConfig subscribeConfig,
-            @NonNull WifiNanDiscoverySessionCallback callback) {
-        WifiNanManager mgr = mMgr.get();
+            @NonNull WifiAwareDiscoverySessionCallback callback) {
+        WifiAwareManager mgr = mMgr.get();
         if (mgr == null) {
-            Log.e(TAG, "publish: called post GC on WifiNanManager");
+            Log.e(TAG, "publish: called post GC on WifiAwareManager");
             return;
         }
         if (mTerminated) {
@@ -184,20 +185,20 @@
     }
 
     /**
-     * Create a {@link NetworkRequest.Builder#setNetworkSpecifier(String)} for a
-     * WiFi NAN connection to the specified peer. The
-     * {@link NetworkRequest.Builder#addTransportType(int)} should be set to
-     * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_NAN}.
+     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for a
+     * WiFi Aware connection to the specified peer. The
+     * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
+     * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
      * <p>
      *     This API is targeted for applications which can obtain the peer MAC address using OOB
-     *     (out-of-band) discovery. NAN discovery does not provide the MAC address of the peer -
-     *     when using NAN discovery use the alternative network specifier method -
-     *     {@link WifiNanDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])}.
+     *     (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
+     *     when using Aware discovery use the alternative network specifier method -
+     *     {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])}.
      *
      * @param role  The role of this device:
-     *              {@link WifiNanManager#WIFI_NAN_DATA_PATH_ROLE_INITIATOR} or
-     *              {@link WifiNanManager#WIFI_NAN_DATA_PATH_ROLE_RESPONDER}
-     * @param peer  The MAC address of the peer's NAN discovery interface. On a RESPONDER this
+     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
+     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
+     * @param peer  The MAC address of the peer's Aware discovery interface. On a RESPONDER this
      *              value is used to gate the acceptance of a connection request from only that
      *              peer. A RESPONDER may specified a null - indicating that it will accept
      *              connection requests from any device.
@@ -209,14 +210,15 @@
      *
      * @return A string to be used to construct
      * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
-     * {@link android.net.ConnectivityManager#requestNetwork(NetworkRequest, android.net.ConnectivityManager.NetworkCallback)}
+     * {@link android.net.ConnectivityManager#requestNetwork(NetworkRequest,
+     * android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
      */
-    public String createNetworkSpecifier(@WifiNanManager.DataPathRole int role, @Nullable byte[] peer,
-            @Nullable byte[] token) {
-        WifiNanManager mgr = mMgr.get();
+    public String createNetworkSpecifier(@WifiAwareManager.DataPathRole int role,
+            @Nullable byte[] peer, @Nullable byte[] token) {
+        WifiAwareManager mgr = mMgr.get();
         if (mgr == null) {
-            Log.e(TAG, "createNetworkSpecifier: called post GC on WifiNanManager");
+            Log.e(TAG, "createNetworkSpecifier: called post GC on WifiAwareManager");
             return "";
         }
         if (mTerminated) {
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSubscribeDiscoverySession.java b/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java
similarity index 65%
rename from wifi/java/android/net/wifi/nan/WifiNanSubscribeDiscoverySession.java
rename to wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java
index f5b4c0c..7c48f54 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanSubscribeDiscoverySession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java
@@ -14,41 +14,43 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 import android.annotation.NonNull;
 import android.util.Log;
 
 /**
- * A class representing a NAN subscribe session. Created when
- * {@link WifiNanSession#subscribe(android.os.Handler, SubscribeConfig, WifiNanDiscoverySessionCallback)}
+ * A class representing a Aware subscribe session. Created when
+ * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig,
+ * WifiAwareDiscoverySessionCallback)}
  * is called and a discovery session is created and returned in
- * {@link WifiNanDiscoverySessionCallback#onSubscribeStarted(WifiNanSubscribeDiscoverySession)}.
- * See baseline functionality of all discovery sessions in {@link WifiNanDiscoveryBaseSession}.
+ * {@link WifiAwareDiscoverySessionCallback#onSubscribeStarted(WifiAwareSubscribeDiscoverySession)}.
+ * See baseline functionality of all discovery sessions in {@link WifiAwareDiscoveryBaseSession}.
  * This object allows updating an existing/running subscribe discovery session using
  * {@link #updateSubscribe(SubscribeConfig)}.
  *
- * @hide PROPOSED_NAN_API
+ * @hide PROPOSED_AWARE_API
  */
-public class WifiNanSubscribeDiscoverySession extends WifiNanDiscoveryBaseSession {
-    private static final String TAG = "WifiNanSubscribeDiscSsn";
+public class WifiAwareSubscribeDiscoverySession extends WifiAwareDiscoveryBaseSession {
+    private static final String TAG = "WifiAwareSubsDiscSsn";
 
     /**
      * {@hide}
      */
-    public WifiNanSubscribeDiscoverySession(WifiNanManager manager, int clientId, int sessionId) {
+    public WifiAwareSubscribeDiscoverySession(WifiAwareManager manager, int clientId,
+            int sessionId) {
         super(manager, clientId, sessionId);
     }
 
     /**
      * Re-configure the currently active subscribe session. The
-     * {@link WifiNanDiscoverySessionCallback} is not replaced - the same listener used
+     * {@link WifiAwareDiscoverySessionCallback} is not replaced - the same listener used
      * at creation is still used. The results of the configuration are returned using
-     * {@link WifiNanDiscoverySessionCallback}:
+     * {@link WifiAwareDiscoverySessionCallback}:
      * <ul>
-     *     <li>{@link WifiNanDiscoverySessionCallback#onSessionConfigUpdated()}: configuration
+     *     <li>{@link WifiAwareDiscoverySessionCallback#onSessionConfigUpdated()}: configuration
      *     update succeeded.
-     *     <li>{@link WifiNanDiscoverySessionCallback#onSessionConfigFailed()}: configuration
+     *     <li>{@link WifiAwareDiscoverySessionCallback#onSessionConfigFailed()}: configuration
      *     update failed. The subscribe discovery session is still running using its previous
      *     configuration (i.e. update failure does not terminate the session).
      * </ul>
@@ -61,9 +63,9 @@
             Log.w(TAG, "updateSubscribe: called on terminated session");
             return;
         } else {
-            WifiNanManager mgr = mMgr.get();
+            WifiAwareManager mgr = mMgr.get();
             if (mgr == null) {
-                Log.w(TAG, "updateSubscribe: called post GC on WifiNanManager");
+                Log.w(TAG, "updateSubscribe: called post GC on WifiAwareManager");
                 return;
             }
 
diff --git a/wifi/java/android/net/wifi/nan/WifiNanUtils.java b/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
similarity index 93%
rename from wifi/java/android/net/wifi/nan/WifiNanUtils.java
rename to wifi/java/android/net/wifi/aware/WifiAwareUtils.java
index c0f36b4..4083388 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanUtils.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareUtils.java
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.aware;
 
 /**
- * Provides utilities for the Wifi NAN manager/service.
+ * Provides utilities for the Wifi Aware manager/service.
  *
  * @hide
  */
-public class WifiNanUtils {
+public class WifiAwareUtils {
     /**
      * Per spec: The Service Name is a UTF-8 encoded string from 1 to 255 bytes in length. The
      * only acceptable single-byte UTF-8 symbols for a Service Name are alphanumeric values (A-Z,
diff --git a/wifi/java/android/net/wifi/aware/package.html b/wifi/java/android/net/wifi/aware/package.html
new file mode 100644
index 0000000..1a990d8
--- /dev/null
+++ b/wifi/java/android/net/wifi/aware/package.html
@@ -0,0 +1,43 @@
+<HTML>
+<BODY>
+<p>Provides classes which allow applications to use Wi-Fi Aware to discover peers and create
+    connections to them.</p>
+<p>Using the Wi-Fi Aware APIs, applications can advertise services, discover peers which are
+    advertising services, and connect to them.
+    Wi-Fi Aware is independent of Wi-Fi infrastructure (i.e. a device may or may
+    not be associated with an AP concurrent to using Wi-Fi Aware). </p>
+<p>The primary entry point to Wi-Fi Aware capabilities is the
+    {@link android.net.wifi.aware.WifiAwareManager} class, which is acquired by calling
+    {@link android.content.Context#getSystemService(String)
+    Context.getSystemService(Context.WIFI_AWARE_SERVICE)}</p>
+
+<p>Some APIs may require the following user permissions:</p>
+<ul>
+    <li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
+    <li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
+    <li>{@link android.Manifest.permission#ACCESS_COARSE_LOCATION}</li>
+</ul>
+
+<p class="note"><strong>Note:</strong> Not all Android-powered devices support Wi-Fi Aware
+    functionality.
+    If your application only works with Wi-Fi Aware (i.e. it should only be installed on devices which
+    support Wi-Fi Aware), declare so with a <a
+            href="{@docRoot}guide/topics/manifest/uses-feature-element.html">
+        {@code &lt;uses-feature&gt;}</a>
+    element in the manifest file:</p>
+<pre>
+&lt;manifest ...>
+    &lt;uses-feature android:name="android.hardware.wifi.aware" />
+    ...
+&lt;/manifest>
+</pre>
+<p>Alternatively, if you application does not require Wi-Fi Aware but can take advantage of it if
+    available, you can perform
+    the check at run-time in your code using {@link
+    android.content.pm.PackageManager#hasSystemFeature(String)} with {@link
+    android.content.pm.PackageManager#FEATURE_WIFI_AWARE}:</p>
+<pre>
+    getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE)
+</pre>
+</BODY>
+</HTML>
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.aidl b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.aidl
similarity index 73%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.aidl
index 5f66d16..6b1cea8 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
+/**
+ * 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
+ *     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,
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.hotspot2;
 
-parcelable PublishConfig;
+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/nan/PublishConfig.aidl b/wifi/java/android/net/wifi/hotspot2/pps/Credential.aidl
similarity index 74%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to wifi/java/android/net/wifi/hotspot2/pps/Credential.aidl
index 5f66d16..3d8e833 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
+/**
+ * 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
+ *     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,
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.hotspot2.pps;
 
-parcelable PublishConfig;
+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/nan/PublishConfig.aidl b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
similarity index 75%
copy from wifi/java/android/net/wifi/nan/PublishConfig.aidl
copy to wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
index 5f66d16..62d5603 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.aidl
+++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
+/**
+ * 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
+ *     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,
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.net.wifi.nan;
+package android.net.wifi.hotspot2.pps;
 
-parcelable PublishConfig;
+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/java/android/net/wifi/nan/WifiNanAttachCallback.java b/wifi/java/android/net/wifi/nan/WifiNanAttachCallback.java
deleted file mode 100644
index d8c310b..0000000
--- a/wifi/java/android/net/wifi/nan/WifiNanAttachCallback.java
+++ /dev/null
@@ -1,47 +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 android.net.wifi.nan;
-
-/**
- * Base class for NAN attach callbacks. Should be extended by applications and set when calling
- * {@link WifiNanManager#attach(android.os.Handler, WifiNanAttachCallback)}. These are callbacks
- * applying to the NAN connection as a whole - not to specific publish or subscribe sessions -
- * for that see {@link WifiNanDiscoverySessionCallback}.
- *
- * @hide PROPOSED_NAN_API
- */
-public class WifiNanAttachCallback {
-    /**
-     * Called when NAN attach operation
-     * {@link WifiNanManager#attach(android.os.Handler, WifiNanAttachCallback)}
-     * is completed and that we can now start discovery sessions or connections.
-     *
-     * @param session The NAN object on which we can execute further NAN operations - e.g.
-     *                discovery, connections.
-     */
-    public void onAttached(WifiNanSession session) {
-        /* empty */
-    }
-
-    /**
-     * Called when NAN attach operation
-     * {@link WifiNanManager#attach(android.os.Handler, WifiNanAttachCallback)} failed.
-     */
-    public void onAttachFailed() {
-        /* empty */
-    }
-}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanCharacteristics.aidl b/wifi/java/android/net/wifi/nan/WifiNanCharacteristics.aidl
deleted file mode 100644
index e562a00..0000000
--- a/wifi/java/android/net/wifi/nan/WifiNanCharacteristics.aidl
+++ /dev/null
@@ -1,19 +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 android.net.wifi.nan;
-
-parcelable WifiNanCharacteristics;
diff --git a/wifi/java/android/net/wifi/nan/package.html b/wifi/java/android/net/wifi/nan/package.html
deleted file mode 100644
index ae3cf6c..0000000
--- a/wifi/java/android/net/wifi/nan/package.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides classes which allow applications to use Wi-Fi NAN to discover peers and create
-    connections to them.</p>
-<p>Using the Wi-Fi NAN APIs, applications can advertise services, discover peers which are
-    advertising services, and connect to them.
-    Wi-Fi NAN is independent of Wi-Fi infrastructure (i.e. a device may or may
-    not be associated with an AP concurrent to using Wi-Fi NAN). </p>
-<p>The primary entry point to Wi-Fi NAN capabilities is the
-    {@link android.net.wifi.nan.WifiNanManager} class, which is acquired by calling
-    {@link android.content.Context#getSystemService(String)
-    Context.getSystemService(Context.WIFI_NAN_SERVICE)}</p>
-
-<p>Some APIs may require the following user permissions:</p>
-<ul>
-    <li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
-    <li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
-    <li>{@link android.Manifest.permission#ACCESS_COARSE_LOCATION}</li>
-</ul>
-
-<p class="note"><strong>Note:</strong> Not all Android-powered devices support Wi-Fi NAN
-    functionality.
-    If your application only works with Wi-Fi NAN (i.e. it should only be installed on devices which
-    support Wi-Fi NAN), declare so with a <a
-            href="{@docRoot}guide/topics/manifest/uses-feature-element.html">
-        {@code &lt;uses-feature&gt;}</a>
-    element in the manifest file:</p>
-<pre>
-&lt;manifest ...>
-    &lt;uses-feature android:name="android.hardware.wifi.nan" />
-    ...
-&lt;/manifest>
-</pre>
-<p>Alternatively, if you application does not require Wi-Fi NAN but can take advantage of it if
-    available, you can perform
-    the check at run-time in your code using {@link
-    android.content.pm.PackageManager#hasSystemFeature(String)} with {@link
-    android.content.pm.PackageManager#FEATURE_WIFI_NAN}:</p>
-<pre>
-    getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_NAN)
-</pre>
-</BODY>
-</HTML>
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 8d5cf63..398308d 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -283,6 +283,13 @@
     public static final String EXTRA_HANDOVER_MESSAGE =
             "android.net.wifi.p2p.EXTRA_HANDOVER_MESSAGE";
 
+    /**
+     * The lookup key for a calling package returned by the WifiP2pService.
+     * @hide
+     */
+    public static final String CALLING_PACKAGE =
+            "android.net.wifi.p2p.CALLING_PACKAGE";
+
     IWifiP2pManager mService;
 
     private static final int BASE = Protocol.BASE_WIFI_P2P_MANAGER;
@@ -1271,7 +1278,10 @@
      */
     public void requestPeers(Channel c, PeerListListener listener) {
         checkChannel(c);
-        c.mAsyncChannel.sendMessage(REQUEST_PEERS, 0, c.putListener(listener));
+        Bundle callingPackage = new Bundle();
+        callingPackage.putString(CALLING_PACKAGE, c.mContext.getOpPackageName());
+        c.mAsyncChannel.sendMessage(REQUEST_PEERS, 0, c.putListener(listener),
+                callingPackage);
     }
 
     /**
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());
+    }
+}