Merge "TIF: add ASPECT_RATIO_4_3 for Preview/WatchNextPrograms" into oc-dev
diff --git a/Android.mk b/Android.mk
index b8b85ba..991d185 100644
--- a/Android.mk
+++ b/Android.mk
@@ -309,6 +309,7 @@
 	core/java/android/companion/IFindDeviceCallback.aidl \
 	core/java/android/service/dreams/IDreamManager.aidl \
 	core/java/android/service/dreams/IDreamService.aidl \
+	core/java/android/service/oemlock/IOemLockService.aidl \
 	core/java/android/service/persistentdata/IPersistentDataBlockService.aidl \
 	core/java/android/service/trust/ITrustAgentService.aidl \
 	core/java/android/service/trust/ITrustAgentServiceCallback.aidl \
@@ -569,11 +570,11 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES :=                          \
     framework-protos                                    \
-    android.hardware.health@1.0-java-constants          \
-    android.hardware.thermal@1.0-java-constants         \
-    android.hardware.tv.input@1.0-java-constants        \
-    android.hardware.usb@1.0-java-constants             \
-    android.hardware.vibrator@1.0-java-constants        \
+    android.hardware.health-V1.0-java-constants          \
+    android.hardware.thermal-V1.0-java-constants         \
+    android.hardware.tv.input-V1.0-java-constants        \
+    android.hardware.usb-V1.0-java-constants             \
+    android.hardware.vibrator-V1.0-java-constants        \
 
 # Loaded with System.loadLibrary by android.view.textclassifier
 LOCAL_REQUIRED_MODULES += libtextclassifier
diff --git a/api/current.txt b/api/current.txt
index 68f54ac..e1b826e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1541,6 +1541,7 @@
     field public static final int windowShowAnimation = 16842934; // 0x10100b6
     field public static final int windowShowWallpaper = 16843410; // 0x1010292
     field public static final int windowSoftInputMode = 16843307; // 0x101022b
+    field public static final int windowSplashscreenContent = 16844135; // 0x1010567
     field public static final int windowSwipeToDismiss = 16843763; // 0x10103f3
     field public static final int windowTitleBackgroundStyle = 16842844; // 0x101005c
     field public static final int windowTitleSize = 16842842; // 0x101005a
@@ -2999,6 +3000,7 @@
     method public android.accounts.AccountManagerFuture<android.os.Bundle> startAddAccountSession(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> startUpdateCredentialsSession(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> updateCredentials(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
+    field public static final java.lang.String ACTION_ACCOUNT_REMOVED = "android.accounts.action.ACCOUNT_REMOVED";
     field public static final java.lang.String ACTION_AUTHENTICATOR_INTENT = "android.accounts.AccountAuthenticator";
     field public static final java.lang.String AUTHENTICATOR_ATTRIBUTES_NAME = "account-authenticator";
     field public static final java.lang.String AUTHENTICATOR_META_DATA_NAME = "android.accounts.AccountAuthenticator";
@@ -4698,7 +4700,7 @@
   public abstract class FragmentContainer {
     ctor public FragmentContainer();
     method public android.app.Fragment instantiate(android.content.Context, java.lang.String, android.os.Bundle);
-    method public abstract android.view.View onFindViewById(int);
+    method public abstract <T extends android.view.View> T onFindViewById(int);
     method public abstract boolean onHasView();
   }
 
@@ -4749,7 +4751,7 @@
     ctor public FragmentHostCallback(android.content.Context, android.os.Handler, int);
     method public void onAttachFragment(android.app.Fragment);
     method public void onDump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
-    method public android.view.View onFindViewById(int);
+    method public <T extends android.view.View> T onFindViewById(int);
     method public abstract E onGetHost();
     method public android.view.LayoutInflater onGetLayoutInflater();
     method public int onGetWindowAnimations();
@@ -7606,9 +7608,11 @@
     field public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2; // 0x2
     field public static final int PAIRING_VARIANT_PIN = 0; // 0x0
     field public static final int PHY_LE_1M = 1; // 0x1
+    field public static final int PHY_LE_1M_MASK = 1; // 0x1
     field public static final int PHY_LE_2M = 2; // 0x2
-    field public static final int PHY_LE_ANY = 7; // 0x7
-    field public static final int PHY_LE_CODED = 4; // 0x4
+    field public static final int PHY_LE_2M_MASK = 2; // 0x2
+    field public static final int PHY_LE_CODED = 3; // 0x3
+    field public static final int PHY_LE_CODED_MASK = 4; // 0x4
     field public static final int PHY_OPTION_NO_PREFERRED = 0; // 0x0
     field public static final int PHY_OPTION_S2 = 1; // 0x1
     field public static final int PHY_OPTION_S8 = 2; // 0x2
@@ -8026,9 +8030,6 @@
     field public static final int INTERVAL_MAX = 16777215; // 0xffffff
     field public static final int INTERVAL_MEDIUM = 400; // 0x190
     field public static final int INTERVAL_MIN = 160; // 0xa0
-    field public static final int PHY_LE_1M = 1; // 0x1
-    field public static final int PHY_LE_2M = 2; // 0x2
-    field public static final int PHY_LE_CODED = 3; // 0x3
     field public static final int TX_POWER_HIGH = 1; // 0x1
     field public static final int TX_POWER_LOW = -15; // 0xfffffff1
     field public static final int TX_POWER_MAX = 1; // 0x1
@@ -8157,9 +8158,6 @@
     field public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanResult> CREATOR;
     field public static final int DATA_COMPLETE = 0; // 0x0
     field public static final int DATA_TRUNCATED = 2; // 0x2
-    field public static final int PHY_LE_1M = 1; // 0x1
-    field public static final int PHY_LE_2M = 2; // 0x2
-    field public static final int PHY_LE_CODED = 3; // 0x3
     field public static final int PHY_UNUSED = 0; // 0x0
     field public static final int SID_NOT_PRESENT = 255; // 0xff
   }
@@ -8182,9 +8180,7 @@
     field public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2; // 0x2
     field public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3; // 0x3
     field public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1; // 0x1
-    field public static final int PHY_LE_1M = 1; // 0x1
     field public static final int PHY_LE_ALL_SUPPORTED = 255; // 0xff
-    field public static final int PHY_LE_CODED = 3; // 0x3
     field public static final int SCAN_MODE_BALANCED = 1; // 0x1
     field public static final int SCAN_MODE_LOW_LATENCY = 2; // 0x2
     field public static final int SCAN_MODE_LOW_POWER = 0; // 0x0
@@ -9465,6 +9461,7 @@
     field public static final java.lang.String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP";
     field public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL";
     field public static final java.lang.String EXTRA_EXCLUDE_COMPONENTS = "android.intent.extra.EXCLUDE_COMPONENTS";
+    field public static final java.lang.String EXTRA_FROM_STORAGE = "android.intent.extra.FROM_STORAGE";
     field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
     field public static final java.lang.String EXTRA_INDEX = "android.intent.extra.INDEX";
     field public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
@@ -10362,12 +10359,10 @@
     ctor public LauncherApps.ShortcutQuery();
     method public android.content.pm.LauncherApps.ShortcutQuery setActivity(android.content.ComponentName);
     method public android.content.pm.LauncherApps.ShortcutQuery setChangedSince(long);
-    method public deprecated android.content.pm.LauncherApps.ShortcutQuery setIntent(android.content.Intent);
     method public android.content.pm.LauncherApps.ShortcutQuery setPackage(java.lang.String);
     method public android.content.pm.LauncherApps.ShortcutQuery setQueryFlags(int);
     method public android.content.pm.LauncherApps.ShortcutQuery setShortcutIds(java.util.List<java.lang.String>);
     field public static final int FLAG_GET_KEY_FIELDS_ONLY = 4; // 0x4
-    field public static final deprecated int FLAG_MATCH_CHOOSER = 16; // 0x10
     field public static final int FLAG_MATCH_DYNAMIC = 1; // 0x1
     field public static final int FLAG_MATCH_MANIFEST = 8; // 0x8
     field public static final int FLAG_MATCH_PINNED = 2; // 0x2
@@ -10921,9 +10916,6 @@
     method public int describeContents();
     method public android.content.ComponentName getActivity();
     method public java.util.Set<java.lang.String> getCategories();
-    method public deprecated android.content.ComponentName[] getChooserComponentNames();
-    method public deprecated android.os.PersistableBundle getChooserExtras();
-    method public deprecated android.content.IntentFilter[] getChooserIntentFilters();
     method public java.lang.CharSequence getDisabledMessage();
     method public android.os.PersistableBundle getExtras();
     method public java.lang.String getId();
@@ -10936,7 +10928,6 @@
     method public java.lang.CharSequence getShortLabel();
     method public android.os.UserHandle getUserHandle();
     method public boolean hasKeyFieldsOnly();
-    method public deprecated boolean isChooser();
     method public boolean isDeclaredInManifest();
     method public boolean isDynamic();
     method public boolean isEnabled();
@@ -10949,11 +10940,9 @@
 
   public static class ShortcutInfo.Builder {
     ctor public ShortcutInfo.Builder(android.content.Context, java.lang.String);
-    method public deprecated android.content.pm.ShortcutInfo.Builder addChooserIntentFilter(android.content.IntentFilter, android.content.ComponentName);
     method public android.content.pm.ShortcutInfo build();
     method public android.content.pm.ShortcutInfo.Builder setActivity(android.content.ComponentName);
     method public android.content.pm.ShortcutInfo.Builder setCategories(java.util.Set<java.lang.String>);
-    method public deprecated android.content.pm.ShortcutInfo.Builder setChooserExtras(android.os.PersistableBundle);
     method public android.content.pm.ShortcutInfo.Builder setDisabledMessage(java.lang.CharSequence);
     method public android.content.pm.ShortcutInfo.Builder setExtras(android.os.PersistableBundle);
     method public android.content.pm.ShortcutInfo.Builder setIcon(android.graphics.drawable.Icon);
@@ -14866,15 +14855,16 @@
     field public final int type;
   }
 
-  public final class SensorDirectChannel implements java.lang.AutoCloseable {
+  public final class SensorDirectChannel implements java.nio.channels.Channel {
     method public void close();
-    method public boolean isValid();
+    method public int configure(android.hardware.Sensor, int);
+    method public boolean isOpen();
     field public static final int RATE_FAST = 2; // 0x2
     field public static final int RATE_NORMAL = 1; // 0x1
     field public static final int RATE_STOP = 0; // 0x0
     field public static final int RATE_VERY_FAST = 3; // 0x3
-    field public static final int TYPE_ASHMEM = 1; // 0x1
     field public static final int TYPE_HARDWARE_BUFFER = 2; // 0x2
+    field public static final int TYPE_MEMORY_FILE = 1; // 0x1
   }
 
   public class SensorEvent {
@@ -14908,7 +14898,6 @@
 
   public abstract class SensorManager {
     method public boolean cancelTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor);
-    method public int configureDirectChannel(android.hardware.SensorDirectChannel, android.hardware.Sensor, int);
     method public android.hardware.SensorDirectChannel createDirectChannel(android.os.MemoryFile);
     method public android.hardware.SensorDirectChannel createDirectChannel(android.hardware.HardwareBuffer);
     method public boolean flush(android.hardware.SensorEventListener);
@@ -15757,7 +15746,6 @@
     method public void unregisterDisplayListener(android.hardware.display.DisplayManager.DisplayListener);
     field public static final java.lang.String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
     field public static final int VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR = 16; // 0x10
-    field public static final int VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 32; // 0x20
     field public static final int VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY = 8; // 0x8
     field public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 2; // 0x2
     field public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1; // 0x1
@@ -22356,7 +22344,7 @@
     method public void setOnKeyStatusChangeListener(android.media.MediaDrm.OnKeyStatusChangeListener, android.os.Handler);
     method public void setPropertyByteArray(java.lang.String, byte[]);
     method public void setPropertyString(java.lang.String, java.lang.String);
-    field public static final int EVENT_KEY_EXPIRED = 3; // 0x3
+    field public static final deprecated int EVENT_KEY_EXPIRED = 3; // 0x3
     field public static final int EVENT_KEY_REQUIRED = 2; // 0x2
     field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1
     field public static final int EVENT_SESSION_RECLAIMED = 5; // 0x5
@@ -37224,7 +37212,7 @@
     method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
     method public boolean dispatchTouchEvent(android.view.MotionEvent);
     method public boolean dispatchTrackballEvent(android.view.MotionEvent);
-    method public android.view.View findViewById(int);
+    method public <T extends android.view.View> T findViewById(int);
     method public final void finish();
     method public android.view.Window getWindow();
     method public android.view.WindowManager getWindowManager();
@@ -43892,7 +43880,6 @@
     method public boolean isValid();
     method public boolean isWideColorGamut();
     field public static final int DEFAULT_DISPLAY = 0; // 0x0
-    field public static final int FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 32; // 0x20
     field public static final int FLAG_PRESENTATION = 8; // 0x8
     field public static final int FLAG_PRIVATE = 4; // 0x4
     field public static final int FLAG_ROUND = 16; // 0x10
diff --git a/api/removed.txt b/api/removed.txt
index d20c08c..82705fd 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -100,6 +100,18 @@
 
 }
 
+package android.hardware {
+
+  public final class SensorDirectChannel implements java.nio.channels.Channel {
+    method public deprecated boolean isValid();
+  }
+
+  public abstract class SensorManager {
+    method public deprecated int configureDirectChannel(android.hardware.SensorDirectChannel, android.hardware.Sensor, int);
+  }
+
+}
+
 package android.media {
 
   public final class AudioFormat implements android.os.Parcelable {
diff --git a/api/system-current.txt b/api/system-current.txt
index 9918b5a..1225aef8 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -142,12 +142,14 @@
     field public static final java.lang.String MANAGE_APP_OPS_RESTRICTIONS = "android.permission.MANAGE_APP_OPS_RESTRICTIONS";
     field public static final java.lang.String MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS";
     field public static final java.lang.String MANAGE_AUTO_FILL = "android.permission.MANAGE_AUTO_FILL";
+    field public static final java.lang.String MANAGE_CARRIER_OEM_UNLOCK_STATE = "android.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE";
     field public static final java.lang.String MANAGE_CA_CERTIFICATES = "android.permission.MANAGE_CA_CERTIFICATES";
     field public static final java.lang.String MANAGE_DEVICE_ADMINS = "android.permission.MANAGE_DEVICE_ADMINS";
     field public static final java.lang.String MANAGE_DOCUMENTS = "android.permission.MANAGE_DOCUMENTS";
     field public static final java.lang.String MANAGE_OWN_CALLS = "android.permission.MANAGE_OWN_CALLS";
     field public static final java.lang.String MANAGE_USB = "android.permission.MANAGE_USB";
     field public static final java.lang.String MANAGE_USERS = "android.permission.MANAGE_USERS";
+    field public static final java.lang.String MANAGE_USER_OEM_UNLOCK_STATE = "android.permission.MANAGE_USER_OEM_UNLOCK_STATE";
     field public static final java.lang.String MASTER_CLEAR = "android.permission.MASTER_CLEAR";
     field public static final java.lang.String MEDIA_CONTENT_CONTROL = "android.permission.MEDIA_CONTENT_CONTROL";
     field public static final java.lang.String MODIFY_APPWIDGET_BIND_PERMISSIONS = "android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS";
@@ -1661,6 +1663,7 @@
     field public static final int windowShowAnimation = 16842934; // 0x10100b6
     field public static final int windowShowWallpaper = 16843410; // 0x1010292
     field public static final int windowSoftInputMode = 16843307; // 0x101022b
+    field public static final int windowSplashscreenContent = 16844135; // 0x1010567
     field public static final int windowSwipeToDismiss = 16843763; // 0x10103f3
     field public static final int windowTitleBackgroundStyle = 16842844; // 0x101005c
     field public static final int windowTitleSize = 16842842; // 0x101005a
@@ -3123,6 +3126,7 @@
     method public android.accounts.AccountManagerFuture<android.os.Bundle> startAddAccountSession(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> startUpdateCredentialsSession(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> updateCredentials(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
+    field public static final java.lang.String ACTION_ACCOUNT_REMOVED = "android.accounts.action.ACCOUNT_REMOVED";
     field public static final java.lang.String ACTION_AUTHENTICATOR_INTENT = "android.accounts.AccountAuthenticator";
     field public static final java.lang.String AUTHENTICATOR_ATTRIBUTES_NAME = "account-authenticator";
     field public static final java.lang.String AUTHENTICATOR_META_DATA_NAME = "android.accounts.AccountAuthenticator";
@@ -4861,7 +4865,7 @@
   public abstract class FragmentContainer {
     ctor public FragmentContainer();
     method public android.app.Fragment instantiate(android.content.Context, java.lang.String, android.os.Bundle);
-    method public abstract android.view.View onFindViewById(int);
+    method public abstract <T extends android.view.View> T onFindViewById(int);
     method public abstract boolean onHasView();
   }
 
@@ -4912,7 +4916,7 @@
     ctor public FragmentHostCallback(android.content.Context, android.os.Handler, int);
     method public void onAttachFragment(android.app.Fragment);
     method public void onDump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
-    method public android.view.View onFindViewById(int);
+    method public <T extends android.view.View> T onFindViewById(int);
     method public abstract E onGetHost();
     method public android.view.LayoutInflater onGetLayoutInflater();
     method public int onGetWindowAnimations();
@@ -8076,9 +8080,11 @@
     field public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2; // 0x2
     field public static final int PAIRING_VARIANT_PIN = 0; // 0x0
     field public static final int PHY_LE_1M = 1; // 0x1
+    field public static final int PHY_LE_1M_MASK = 1; // 0x1
     field public static final int PHY_LE_2M = 2; // 0x2
-    field public static final int PHY_LE_ANY = 7; // 0x7
-    field public static final int PHY_LE_CODED = 4; // 0x4
+    field public static final int PHY_LE_2M_MASK = 2; // 0x2
+    field public static final int PHY_LE_CODED = 3; // 0x3
+    field public static final int PHY_LE_CODED_MASK = 4; // 0x4
     field public static final int PHY_OPTION_NO_PREFERRED = 0; // 0x0
     field public static final int PHY_OPTION_S2 = 1; // 0x1
     field public static final int PHY_OPTION_S8 = 2; // 0x2
@@ -8496,9 +8502,6 @@
     field public static final int INTERVAL_MAX = 16777215; // 0xffffff
     field public static final int INTERVAL_MEDIUM = 400; // 0x190
     field public static final int INTERVAL_MIN = 160; // 0xa0
-    field public static final int PHY_LE_1M = 1; // 0x1
-    field public static final int PHY_LE_2M = 2; // 0x2
-    field public static final int PHY_LE_CODED = 3; // 0x3
     field public static final int TX_POWER_HIGH = 1; // 0x1
     field public static final int TX_POWER_LOW = -15; // 0xfffffff1
     field public static final int TX_POWER_MAX = 1; // 0x1
@@ -8640,9 +8643,6 @@
     field public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanResult> CREATOR;
     field public static final int DATA_COMPLETE = 0; // 0x0
     field public static final int DATA_TRUNCATED = 2; // 0x2
-    field public static final int PHY_LE_1M = 1; // 0x1
-    field public static final int PHY_LE_2M = 2; // 0x2
-    field public static final int PHY_LE_CODED = 3; // 0x3
     field public static final int PHY_UNUSED = 0; // 0x0
     field public static final int SID_NOT_PRESENT = 255; // 0xff
   }
@@ -8665,9 +8665,7 @@
     field public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2; // 0x2
     field public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3; // 0x3
     field public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1; // 0x1
-    field public static final int PHY_LE_1M = 1; // 0x1
     field public static final int PHY_LE_ALL_SUPPORTED = 255; // 0xff
-    field public static final int PHY_LE_CODED = 3; // 0x3
     field public static final int SCAN_MODE_BALANCED = 1; // 0x1
     field public static final int SCAN_MODE_LOW_LATENCY = 2; // 0x2
     field public static final int SCAN_MODE_LOW_POWER = 0; // 0x0
@@ -9435,6 +9433,7 @@
     field public static final java.lang.String NFC_SERVICE = "nfc";
     field public static final java.lang.String NOTIFICATION_SERVICE = "notification";
     field public static final java.lang.String NSD_SERVICE = "servicediscovery";
+    field public static final java.lang.String OEM_LOCK_SERVICE = "oem_lock";
     field public static final java.lang.String PERSISTENT_DATA_BLOCK_SERVICE = "persistent_data_block";
     field public static final java.lang.String POWER_SERVICE = "power";
     field public static final java.lang.String PRINT_SERVICE = "print";
@@ -10013,6 +10012,7 @@
     field public static final deprecated java.lang.String EXTRA_EMERGENCY_ONLY = "emergencyOnly";
     field public static final java.lang.String EXTRA_EXCLUDE_COMPONENTS = "android.intent.extra.EXCLUDE_COMPONENTS";
     field public static final java.lang.String EXTRA_FORCE_FACTORY_RESET = "android.intent.extra.FORCE_FACTORY_RESET";
+    field public static final java.lang.String EXTRA_FROM_STORAGE = "android.intent.extra.FROM_STORAGE";
     field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
     field public static final java.lang.String EXTRA_INDEX = "android.intent.extra.INDEX";
     field public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
@@ -11021,12 +11021,10 @@
     ctor public LauncherApps.ShortcutQuery();
     method public android.content.pm.LauncherApps.ShortcutQuery setActivity(android.content.ComponentName);
     method public android.content.pm.LauncherApps.ShortcutQuery setChangedSince(long);
-    method public deprecated android.content.pm.LauncherApps.ShortcutQuery setIntent(android.content.Intent);
     method public android.content.pm.LauncherApps.ShortcutQuery setPackage(java.lang.String);
     method public android.content.pm.LauncherApps.ShortcutQuery setQueryFlags(int);
     method public android.content.pm.LauncherApps.ShortcutQuery setShortcutIds(java.util.List<java.lang.String>);
     field public static final int FLAG_GET_KEY_FIELDS_ONLY = 4; // 0x4
-    field public static final deprecated int FLAG_MATCH_CHOOSER = 16; // 0x10
     field public static final int FLAG_MATCH_DYNAMIC = 1; // 0x1
     field public static final int FLAG_MATCH_MANIFEST = 8; // 0x8
     field public static final int FLAG_MATCH_PINNED = 2; // 0x2
@@ -11674,9 +11672,6 @@
     method public int describeContents();
     method public android.content.ComponentName getActivity();
     method public java.util.Set<java.lang.String> getCategories();
-    method public deprecated android.content.ComponentName[] getChooserComponentNames();
-    method public deprecated android.os.PersistableBundle getChooserExtras();
-    method public deprecated android.content.IntentFilter[] getChooserIntentFilters();
     method public java.lang.CharSequence getDisabledMessage();
     method public android.os.PersistableBundle getExtras();
     method public java.lang.String getId();
@@ -11689,7 +11684,6 @@
     method public java.lang.CharSequence getShortLabel();
     method public android.os.UserHandle getUserHandle();
     method public boolean hasKeyFieldsOnly();
-    method public deprecated boolean isChooser();
     method public boolean isDeclaredInManifest();
     method public boolean isDynamic();
     method public boolean isEnabled();
@@ -11702,11 +11696,9 @@
 
   public static class ShortcutInfo.Builder {
     ctor public ShortcutInfo.Builder(android.content.Context, java.lang.String);
-    method public deprecated android.content.pm.ShortcutInfo.Builder addChooserIntentFilter(android.content.IntentFilter, android.content.ComponentName);
     method public android.content.pm.ShortcutInfo build();
     method public android.content.pm.ShortcutInfo.Builder setActivity(android.content.ComponentName);
     method public android.content.pm.ShortcutInfo.Builder setCategories(java.util.Set<java.lang.String>);
-    method public deprecated android.content.pm.ShortcutInfo.Builder setChooserExtras(android.os.PersistableBundle);
     method public android.content.pm.ShortcutInfo.Builder setDisabledMessage(java.lang.CharSequence);
     method public android.content.pm.ShortcutInfo.Builder setExtras(android.os.PersistableBundle);
     method public android.content.pm.ShortcutInfo.Builder setIcon(android.graphics.drawable.Icon);
@@ -15639,15 +15631,16 @@
     field public final int type;
   }
 
-  public final class SensorDirectChannel implements java.lang.AutoCloseable {
+  public final class SensorDirectChannel implements java.nio.channels.Channel {
     method public void close();
-    method public boolean isValid();
+    method public int configure(android.hardware.Sensor, int);
+    method public boolean isOpen();
     field public static final int RATE_FAST = 2; // 0x2
     field public static final int RATE_NORMAL = 1; // 0x1
     field public static final int RATE_STOP = 0; // 0x0
     field public static final int RATE_VERY_FAST = 3; // 0x3
-    field public static final int TYPE_ASHMEM = 1; // 0x1
     field public static final int TYPE_HARDWARE_BUFFER = 2; // 0x2
+    field public static final int TYPE_MEMORY_FILE = 1; // 0x1
   }
 
   public class SensorEvent {
@@ -15681,7 +15674,6 @@
 
   public abstract class SensorManager {
     method public boolean cancelTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor);
-    method public int configureDirectChannel(android.hardware.SensorDirectChannel, android.hardware.Sensor, int);
     method public android.hardware.SensorDirectChannel createDirectChannel(android.os.MemoryFile);
     method public android.hardware.SensorDirectChannel createDirectChannel(android.hardware.HardwareBuffer);
     method public boolean flush(android.hardware.SensorEventListener);
@@ -16543,7 +16535,6 @@
     method public void unregisterDisplayListener(android.hardware.display.DisplayManager.DisplayListener);
     field public static final java.lang.String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
     field public static final int VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR = 16; // 0x10
-    field public static final int VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 32; // 0x20
     field public static final int VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY = 8; // 0x8
     field public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 2; // 0x2
     field public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1; // 0x1
@@ -24185,7 +24176,7 @@
     method public void setOnKeyStatusChangeListener(android.media.MediaDrm.OnKeyStatusChangeListener, android.os.Handler);
     method public void setPropertyByteArray(java.lang.String, byte[]);
     method public void setPropertyString(java.lang.String, java.lang.String);
-    field public static final int EVENT_KEY_EXPIRED = 3; // 0x3
+    field public static final deprecated int EVENT_KEY_EXPIRED = 3; // 0x3
     field public static final int EVENT_KEY_REQUIRED = 2; // 0x2
     field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1
     field public static final int EVENT_SESSION_RECLAIMED = 5; // 0x5
@@ -26505,6 +26496,7 @@
     field public static final java.lang.String ACTION_REQUEST_CHANNEL_BROWSABLE = "android.media.tv.action.REQUEST_CHANNEL_BROWSABLE";
     field public static final java.lang.String ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED";
     field public static final java.lang.String AUTHORITY = "android.media.tv";
+    field public static final java.lang.String EXTRA_BLOCKED_PACKAGES = "android.media.tv.extra.BLOCKED_PACKAGES";
     field public static final java.lang.String EXTRA_CHANNEL_ID = "android.media.tv.extra.CHANNEL_ID";
     field public static final java.lang.String EXTRA_COLUMN_NAME = "android.media.tv.extra.COLUMN_NAME";
     field public static final java.lang.String EXTRA_DATA_TYPE = "android.media.tv.extra.DATA_TYPE";
@@ -26512,9 +26504,16 @@
     field public static final java.lang.String EXTRA_EXISTING_COLUMN_NAMES = "android.media.tv.extra.EXISTING_COLUMN_NAMES";
     field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.media.tv.extra.PACKAGE_NAME";
     field public static final java.lang.String EXTRA_PREVIEW_PROGRAM_ID = "android.media.tv.extra.PREVIEW_PROGRAM_ID";
+    field public static final java.lang.String EXTRA_RESULT_CODE = "android.media.tv.extra.RESULT_CODE";
     field public static final java.lang.String EXTRA_WATCH_NEXT_PROGRAM_ID = "android.media.tv.extra.WATCH_NEXT_PROGRAM_ID";
     field public static final java.lang.String METHOD_ADD_COLUMN = "add_column";
+    field public static final java.lang.String METHOD_BLOCK_PACKAGE = "block_package";
+    field public static final java.lang.String METHOD_GET_BLOCKED_PACKAGES = "get_blocked_packages";
     field public static final java.lang.String METHOD_GET_COLUMNS = "get_columns";
+    field public static final java.lang.String METHOD_UNBLOCK_PACKAGE = "unblock_package";
+    field public static final int RESULT_ERROR_INVALID_ARGUMENT = 2; // 0x2
+    field public static final int RESULT_ERROR_IO = 1; // 0x1
+    field public static final int RESULT_OK = 0; // 0x0
   }
 
   public static abstract interface TvContract.BaseTvColumns implements android.provider.BaseColumns {
@@ -26545,7 +26544,6 @@
     field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
     field public static final java.lang.String COLUMN_SERVICE_ID = "service_id";
     field public static final java.lang.String COLUMN_SERVICE_TYPE = "service_type";
-    field public static final java.lang.String COLUMN_SYSTEM_APPROVED = "system_approved";
     field public static final java.lang.String COLUMN_TRANSIENT = "transient";
     field public static final java.lang.String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
     field public static final java.lang.String COLUMN_TYPE = "type";
@@ -34666,7 +34664,7 @@
     field public static final java.lang.String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
     field public static final java.lang.String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media";
     field public static final java.lang.String DISALLOW_NETWORK_RESET = "no_network_reset";
-    field public static final java.lang.String DISALLOW_OEM_UNLOCK = "no_oem_unlock";
+    field public static final deprecated java.lang.String DISALLOW_OEM_UNLOCK = "no_oem_unlock";
     field public static final java.lang.String DISALLOW_OUTGOING_BEAM = "no_outgoing_beam";
     field public static final java.lang.String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls";
     field public static final java.lang.String DISALLOW_REMOVE_MANAGED_PROFILE = "no_remove_managed_profile";
@@ -40330,7 +40328,7 @@
     method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
     method public boolean dispatchTouchEvent(android.view.MotionEvent);
     method public boolean dispatchTrackballEvent(android.view.MotionEvent);
-    method public android.view.View findViewById(int);
+    method public <T extends android.view.View> T findViewById(int);
     method public final void finish();
     method public android.view.Window getWindow();
     method public android.view.WindowManager getWindowManager();
@@ -40624,15 +40622,26 @@
 
 }
 
+package android.service.oemlock {
+
+  public class OemLockManager {
+    method public boolean isOemUnlockAllowedByCarrier();
+    method public boolean isOemUnlockAllowedByUser();
+    method public void setOemUnlockAllowedByCarrier(boolean, byte[]);
+    method public void setOemUnlockAllowedByUser(boolean);
+  }
+
+}
+
 package android.service.persistentdata {
 
   public class PersistentDataBlockManager {
     method public int getDataBlockSize();
     method public int getFlashLockState();
     method public long getMaximumDataBlockSize();
-    method public boolean getOemUnlockEnabled();
+    method public deprecated boolean getOemUnlockEnabled();
     method public byte[] read();
-    method public void setOemUnlockEnabled(boolean);
+    method public deprecated void setOemUnlockEnabled(boolean);
     method public void wipe();
     method public int write(byte[]);
     field public static final int FLASH_LOCK_LOCKED = 1; // 0x1
@@ -43685,7 +43694,7 @@
     method public boolean isSmsCapable();
     method public boolean isTtyModeSupported();
     method public boolean isVideoCallingEnabled();
-    method public boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
+    method public deprecated boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
     method public boolean isVoiceCapable();
     method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle);
     method public boolean isWorldPhone();
@@ -43702,7 +43711,7 @@
     method public boolean setPreferredNetworkTypeToGlobal();
     method public boolean setRadio(boolean);
     method public boolean setRadioPower(boolean);
-    method public void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean);
+    method public deprecated void setVisualVoicemailEnabled(android.telecom.PhoneAccountHandle, boolean);
     method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
     method public void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
     method public void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean);
@@ -47451,7 +47460,6 @@
     method public boolean isValid();
     method public boolean isWideColorGamut();
     field public static final int DEFAULT_DISPLAY = 0; // 0x0
-    field public static final int FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 32; // 0x20
     field public static final int FLAG_PRESENTATION = 8; // 0x8
     field public static final int FLAG_PRIVATE = 4; // 0x4
     field public static final int FLAG_ROUND = 16; // 0x10
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 1effe9c..bdcafae 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -98,6 +98,18 @@
 
 }
 
+package android.hardware {
+
+  public final class SensorDirectChannel implements java.nio.channels.Channel {
+    method public deprecated boolean isValid();
+  }
+
+  public abstract class SensorManager {
+    method public deprecated int configureDirectChannel(android.hardware.SensorDirectChannel, android.hardware.Sensor, int);
+  }
+
+}
+
 package android.media {
 
   public final class AudioFormat implements android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index 1102ce0..dff8ee4 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1541,6 +1541,7 @@
     field public static final int windowShowAnimation = 16842934; // 0x10100b6
     field public static final int windowShowWallpaper = 16843410; // 0x1010292
     field public static final int windowSoftInputMode = 16843307; // 0x101022b
+    field public static final int windowSplashscreenContent = 16844135; // 0x1010567
     field public static final int windowSwipeToDismiss = 16843763; // 0x10103f3
     field public static final int windowTitleBackgroundStyle = 16842844; // 0x101005c
     field public static final int windowTitleSize = 16842842; // 0x101005a
@@ -2999,6 +3000,7 @@
     method public android.accounts.AccountManagerFuture<android.os.Bundle> startAddAccountSession(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> startUpdateCredentialsSession(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> updateCredentials(android.accounts.Account, java.lang.String, android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
+    field public static final java.lang.String ACTION_ACCOUNT_REMOVED = "android.accounts.action.ACCOUNT_REMOVED";
     field public static final java.lang.String ACTION_AUTHENTICATOR_INTENT = "android.accounts.AccountAuthenticator";
     field public static final java.lang.String AUTHENTICATOR_ATTRIBUTES_NAME = "account-authenticator";
     field public static final java.lang.String AUTHENTICATOR_META_DATA_NAME = "android.accounts.AccountAuthenticator";
@@ -4711,7 +4713,7 @@
   public abstract class FragmentContainer {
     ctor public FragmentContainer();
     method public android.app.Fragment instantiate(android.content.Context, java.lang.String, android.os.Bundle);
-    method public abstract android.view.View onFindViewById(int);
+    method public abstract <T extends android.view.View> T onFindViewById(int);
     method public abstract boolean onHasView();
   }
 
@@ -4762,7 +4764,7 @@
     ctor public FragmentHostCallback(android.content.Context, android.os.Handler, int);
     method public void onAttachFragment(android.app.Fragment);
     method public void onDump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
-    method public android.view.View onFindViewById(int);
+    method public <T extends android.view.View> T onFindViewById(int);
     method public abstract E onGetHost();
     method public android.view.LayoutInflater onGetLayoutInflater();
     method public int onGetWindowAnimations();
@@ -7637,9 +7639,11 @@
     field public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2; // 0x2
     field public static final int PAIRING_VARIANT_PIN = 0; // 0x0
     field public static final int PHY_LE_1M = 1; // 0x1
+    field public static final int PHY_LE_1M_MASK = 1; // 0x1
     field public static final int PHY_LE_2M = 2; // 0x2
-    field public static final int PHY_LE_ANY = 7; // 0x7
-    field public static final int PHY_LE_CODED = 4; // 0x4
+    field public static final int PHY_LE_2M_MASK = 2; // 0x2
+    field public static final int PHY_LE_CODED = 3; // 0x3
+    field public static final int PHY_LE_CODED_MASK = 4; // 0x4
     field public static final int PHY_OPTION_NO_PREFERRED = 0; // 0x0
     field public static final int PHY_OPTION_S2 = 1; // 0x1
     field public static final int PHY_OPTION_S8 = 2; // 0x2
@@ -8057,9 +8061,6 @@
     field public static final int INTERVAL_MAX = 16777215; // 0xffffff
     field public static final int INTERVAL_MEDIUM = 400; // 0x190
     field public static final int INTERVAL_MIN = 160; // 0xa0
-    field public static final int PHY_LE_1M = 1; // 0x1
-    field public static final int PHY_LE_2M = 2; // 0x2
-    field public static final int PHY_LE_CODED = 3; // 0x3
     field public static final int TX_POWER_HIGH = 1; // 0x1
     field public static final int TX_POWER_LOW = -15; // 0xfffffff1
     field public static final int TX_POWER_MAX = 1; // 0x1
@@ -8188,9 +8189,6 @@
     field public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanResult> CREATOR;
     field public static final int DATA_COMPLETE = 0; // 0x0
     field public static final int DATA_TRUNCATED = 2; // 0x2
-    field public static final int PHY_LE_1M = 1; // 0x1
-    field public static final int PHY_LE_2M = 2; // 0x2
-    field public static final int PHY_LE_CODED = 3; // 0x3
     field public static final int PHY_UNUSED = 0; // 0x0
     field public static final int SID_NOT_PRESENT = 255; // 0xff
   }
@@ -8213,9 +8211,7 @@
     field public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2; // 0x2
     field public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3; // 0x3
     field public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1; // 0x1
-    field public static final int PHY_LE_1M = 1; // 0x1
     field public static final int PHY_LE_ALL_SUPPORTED = 255; // 0xff
-    field public static final int PHY_LE_CODED = 3; // 0x3
     field public static final int SCAN_MODE_BALANCED = 1; // 0x1
     field public static final int SCAN_MODE_LOW_LATENCY = 2; // 0x2
     field public static final int SCAN_MODE_LOW_POWER = 0; // 0x0
@@ -9499,6 +9495,7 @@
     field public static final java.lang.String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP";
     field public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL";
     field public static final java.lang.String EXTRA_EXCLUDE_COMPONENTS = "android.intent.extra.EXCLUDE_COMPONENTS";
+    field public static final java.lang.String EXTRA_FROM_STORAGE = "android.intent.extra.FROM_STORAGE";
     field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
     field public static final java.lang.String EXTRA_INDEX = "android.intent.extra.INDEX";
     field public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
@@ -10399,12 +10396,10 @@
     ctor public LauncherApps.ShortcutQuery();
     method public android.content.pm.LauncherApps.ShortcutQuery setActivity(android.content.ComponentName);
     method public android.content.pm.LauncherApps.ShortcutQuery setChangedSince(long);
-    method public deprecated android.content.pm.LauncherApps.ShortcutQuery setIntent(android.content.Intent);
     method public android.content.pm.LauncherApps.ShortcutQuery setPackage(java.lang.String);
     method public android.content.pm.LauncherApps.ShortcutQuery setQueryFlags(int);
     method public android.content.pm.LauncherApps.ShortcutQuery setShortcutIds(java.util.List<java.lang.String>);
     field public static final int FLAG_GET_KEY_FIELDS_ONLY = 4; // 0x4
-    field public static final deprecated int FLAG_MATCH_CHOOSER = 16; // 0x10
     field public static final int FLAG_MATCH_DYNAMIC = 1; // 0x1
     field public static final int FLAG_MATCH_MANIFEST = 8; // 0x8
     field public static final int FLAG_MATCH_PINNED = 2; // 0x2
@@ -10962,9 +10957,6 @@
     method public int describeContents();
     method public android.content.ComponentName getActivity();
     method public java.util.Set<java.lang.String> getCategories();
-    method public deprecated android.content.ComponentName[] getChooserComponentNames();
-    method public deprecated android.os.PersistableBundle getChooserExtras();
-    method public deprecated android.content.IntentFilter[] getChooserIntentFilters();
     method public java.lang.CharSequence getDisabledMessage();
     method public android.os.PersistableBundle getExtras();
     method public java.lang.String getId();
@@ -10977,7 +10969,6 @@
     method public java.lang.CharSequence getShortLabel();
     method public android.os.UserHandle getUserHandle();
     method public boolean hasKeyFieldsOnly();
-    method public deprecated boolean isChooser();
     method public boolean isDeclaredInManifest();
     method public boolean isDynamic();
     method public boolean isEnabled();
@@ -10990,11 +10981,9 @@
 
   public static class ShortcutInfo.Builder {
     ctor public ShortcutInfo.Builder(android.content.Context, java.lang.String);
-    method public deprecated android.content.pm.ShortcutInfo.Builder addChooserIntentFilter(android.content.IntentFilter, android.content.ComponentName);
     method public android.content.pm.ShortcutInfo build();
     method public android.content.pm.ShortcutInfo.Builder setActivity(android.content.ComponentName);
     method public android.content.pm.ShortcutInfo.Builder setCategories(java.util.Set<java.lang.String>);
-    method public deprecated android.content.pm.ShortcutInfo.Builder setChooserExtras(android.os.PersistableBundle);
     method public android.content.pm.ShortcutInfo.Builder setDisabledMessage(java.lang.CharSequence);
     method public android.content.pm.ShortcutInfo.Builder setExtras(android.os.PersistableBundle);
     method public android.content.pm.ShortcutInfo.Builder setIcon(android.graphics.drawable.Icon);
@@ -14911,15 +14900,16 @@
     field public final int type;
   }
 
-  public final class SensorDirectChannel implements java.lang.AutoCloseable {
+  public final class SensorDirectChannel implements java.nio.channels.Channel {
     method public void close();
-    method public boolean isValid();
+    method public int configure(android.hardware.Sensor, int);
+    method public boolean isOpen();
     field public static final int RATE_FAST = 2; // 0x2
     field public static final int RATE_NORMAL = 1; // 0x1
     field public static final int RATE_STOP = 0; // 0x0
     field public static final int RATE_VERY_FAST = 3; // 0x3
-    field public static final int TYPE_ASHMEM = 1; // 0x1
     field public static final int TYPE_HARDWARE_BUFFER = 2; // 0x2
+    field public static final int TYPE_MEMORY_FILE = 1; // 0x1
   }
 
   public class SensorEvent {
@@ -14953,7 +14943,6 @@
 
   public abstract class SensorManager {
     method public boolean cancelTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor);
-    method public int configureDirectChannel(android.hardware.SensorDirectChannel, android.hardware.Sensor, int);
     method public android.hardware.SensorDirectChannel createDirectChannel(android.os.MemoryFile);
     method public android.hardware.SensorDirectChannel createDirectChannel(android.hardware.HardwareBuffer);
     method public boolean flush(android.hardware.SensorEventListener);
@@ -15806,7 +15795,6 @@
     method public void unregisterDisplayListener(android.hardware.display.DisplayManager.DisplayListener);
     field public static final java.lang.String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
     field public static final int VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR = 16; // 0x10
-    field public static final int VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 32; // 0x20
     field public static final int VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY = 8; // 0x8
     field public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 2; // 0x2
     field public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1; // 0x1
@@ -22463,7 +22451,7 @@
     method public void setOnKeyStatusChangeListener(android.media.MediaDrm.OnKeyStatusChangeListener, android.os.Handler);
     method public void setPropertyByteArray(java.lang.String, byte[]);
     method public void setPropertyString(java.lang.String, java.lang.String);
-    field public static final int EVENT_KEY_EXPIRED = 3; // 0x3
+    field public static final deprecated int EVENT_KEY_EXPIRED = 3; // 0x3
     field public static final int EVENT_KEY_REQUIRED = 2; // 0x2
     field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1
     field public static final int EVENT_SESSION_RECLAIMED = 5; // 0x5
@@ -37377,7 +37365,7 @@
     method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
     method public boolean dispatchTouchEvent(android.view.MotionEvent);
     method public boolean dispatchTrackballEvent(android.view.MotionEvent);
-    method public android.view.View findViewById(int);
+    method public <T extends android.view.View> T findViewById(int);
     method public final void finish();
     method public android.view.Window getWindow();
     method public android.view.WindowManager getWindowManager();
@@ -44255,7 +44243,6 @@
     method public boolean isValid();
     method public boolean isWideColorGamut();
     field public static final int DEFAULT_DISPLAY = 0; // 0x0
-    field public static final int FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 32; // 0x20
     field public static final int FLAG_PRESENTATION = 8; // 0x8
     field public static final int FLAG_PRIVATE = 4; // 0x4
     field public static final int FLAG_ROUND = 16; // 0x10
@@ -44326,6 +44313,7 @@
     method public android.view.View findNextFocusFromRect(android.view.ViewGroup, android.graphics.Rect, int);
     method public android.view.View findNextKeyboardNavigationCluster(android.view.View, android.view.View, int);
     method public static android.view.FocusFinder getInstance();
+    method public static void sort(android.view.View[], int, int, android.view.ViewGroup, boolean);
   }
 
   public final class FrameMetrics {
diff --git a/api/test-removed.txt b/api/test-removed.txt
index d20c08c..82705fd 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -100,6 +100,18 @@
 
 }
 
+package android.hardware {
+
+  public final class SensorDirectChannel implements java.nio.channels.Channel {
+    method public deprecated boolean isValid();
+  }
+
+  public abstract class SensorManager {
+    method public deprecated int configureDirectChannel(android.hardware.SensorDirectChannel, android.hardware.Sensor, int);
+  }
+
+}
+
 package android.media {
 
   public final class AudioFormat implements android.os.Parcelable {
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 8052288..b320d5d 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -335,6 +335,7 @@
      * are removed, or an account's credentials (saved password, etc) are changed.
      *
      * @see #addOnAccountsUpdatedListener
+     * @see #ACTION_ACCOUNT_REMOVED
      *
      * @deprecated use {@link #addOnAccountsUpdatedListener} to get account updates in runtime.
      */
@@ -344,6 +345,14 @@
         "android.accounts.LOGIN_ACCOUNTS_CHANGED";
 
     /**
+     * Action sent as a broadcast Intent by the AccountsService when any account is removed.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @BroadcastBehavior(includeBackground = true)
+    public static final String ACTION_ACCOUNT_REMOVED =
+        "android.accounts.action.ACCOUNT_REMOVED";
+
+    /**
      * Action sent as a broadcast Intent to specific package by the AccountsService
      * when account visibility or account's credentials (saved password, etc) are changed.
      *
diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java
index 16a45ba..9f2c39b 100644
--- a/core/java/android/accounts/ChooseAccountActivity.java
+++ b/core/java/android/accounts/ChooseAccountActivity.java
@@ -77,7 +77,7 @@
         setContentView(R.layout.choose_account);
 
         // Setup the list
-        ListView list = (ListView) findViewById(android.R.id.list);
+        ListView list = findViewById(android.R.id.list);
         // Use an existing ListAdapter that will map an array of strings to TextViews
         list.setAdapter(new AccountArrayAdapter(this,
                 android.R.layout.simple_list_item_1, mAccountInfos));
diff --git a/core/java/android/accounts/ChooseAccountTypeActivity.java b/core/java/android/accounts/ChooseAccountTypeActivity.java
index a3222d8..e3352bc 100644
--- a/core/java/android/accounts/ChooseAccountTypeActivity.java
+++ b/core/java/android/accounts/ChooseAccountTypeActivity.java
@@ -99,7 +99,7 @@
 
         setContentView(R.layout.choose_account_type);
         // Setup the list
-        ListView list = (ListView) findViewById(android.R.id.list);
+        ListView list = findViewById(android.R.id.list);
         // Use an existing ListAdapter that will map an array of strings to TextViews
         list.setAdapter(new AccountArrayAdapter(this,
                 android.R.layout.simple_list_item_1, mAuthenticatorInfosToDisplay));
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index 8442585..6680ce6 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -248,7 +248,7 @@
         populateUIAccountList(listItems);
 
         // Only enable "OK" button if something has been selected.
-        mOkButton = (Button) findViewById(android.R.id.button2);
+        mOkButton = findViewById(android.R.id.button2);
         mOkButton.setEnabled(mSelectedItemIndex != SELECTED_ITEM_NONE);
     }
 
@@ -592,7 +592,7 @@
      * If not specified then makes the description invisible.
      */
     private void overrideDescriptionIfSupplied(String descriptionOverride) {
-      TextView descriptionView = (TextView) findViewById(R.id.description);
+      TextView descriptionView = findViewById(R.id.description);
       if (!TextUtils.isEmpty(descriptionOverride)) {
           descriptionView.setText(descriptionOverride);
       } else {
@@ -605,7 +605,7 @@
      * based on {@code mSelectedItemIndex} member variable.
      */
     private final void populateUIAccountList(String[] listItems) {
-      ListView list = (ListView) findViewById(android.R.id.list);
+      ListView list = findViewById(android.R.id.list);
       list.setAdapter(new ArrayAdapter<String>(this,
               android.R.layout.simple_list_item_single_choice, listItems));
       list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
index 38eab29..af74b03 100644
--- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java
+++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
@@ -84,7 +84,7 @@
             return;
         }
 
-        final TextView authTokenTypeView = (TextView) findViewById(R.id.authtoken_type);
+        final TextView authTokenTypeView = findViewById(R.id.authtoken_type);
         authTokenTypeView.setVisibility(View.GONE);
 
         final AccountManagerCallback<String> callback = new AccountManagerCallback<String>() {
@@ -116,7 +116,7 @@
         findViewById(R.id.allow_button).setOnClickListener(this);
         findViewById(R.id.deny_button).setOnClickListener(this);
 
-        LinearLayout packagesListView = (LinearLayout) findViewById(R.id.packages_list);
+        LinearLayout packagesListView = findViewById(R.id.packages_list);
 
         for (String pkg : packages) {
             String packageLabel;
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 74822d1..950991b 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5941,7 +5941,7 @@
      */
     public void setTaskDescription(ActivityManager.TaskDescription taskDescription) {
         if (mTaskDescription != taskDescription) {
-            mTaskDescription.copyFrom(taskDescription);
+            mTaskDescription.copyFromPreserveHiddenFields(taskDescription);
             // Scale the icon down to something reasonable if it is provided
             if (taskDescription.getIconFilename() == null && taskDescription.getIcon() != null) {
                 final int size = ActivityManager.getLauncherLargeIconSizeInner(this);
@@ -7526,7 +7526,7 @@
 
         @Nullable
         @Override
-        public View onFindViewById(int id) {
+        public <T extends View> T onFindViewById(int id) {
             return Activity.this.findViewById(id);
         }
 
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 80482ca..8859831 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1222,6 +1222,27 @@
             mNavigationBarColor = other.mNavigationBarColor;
         }
 
+        /**
+         * Copies this the values from another TaskDescription, but preserves the hidden fields
+         * if they weren't set on {@code other}
+         * @hide
+         */
+        public void copyFromPreserveHiddenFields(TaskDescription other) {
+            mLabel = other.mLabel;
+            mIcon = other.mIcon;
+            mIconFilename = other.mIconFilename;
+            mColorPrimary = other.mColorPrimary;
+            if (other.mColorBackground != 0) {
+                mColorBackground = other.mColorBackground;
+            }
+            if (other.mStatusBarColor != 0) {
+                mStatusBarColor = other.mStatusBarColor;
+            }
+            if (other.mNavigationBarColor != 0) {
+                mNavigationBarColor = other.mNavigationBarColor;
+            }
+        }
+
         private TaskDescription(Parcel source) {
             readFromParcel(source);
         }
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index 9928512..7d81c4c 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -48,7 +48,7 @@
  * and add your view to it:
  *
  * <pre>
- * FrameLayout fl = (FrameLayout) findViewById(android.R.id.custom);
+ * FrameLayout fl = findViewById(android.R.id.custom);
  * fl.addView(myView, new LayoutParams(MATCH_PARENT, WRAP_CONTENT));
  * </pre>
  *
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 6487e67..c7bcc54 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -2527,7 +2527,7 @@
         mChildFragmentManager.attachController(mHost, new FragmentContainer() {
             @Override
             @Nullable
-            public View onFindViewById(int id) {
+            public <T extends View> T onFindViewById(int id) {
                 if (mView == null) {
                     throw new IllegalStateException("Fragment does not have a view");
                 }
diff --git a/core/java/android/app/FragmentContainer.java b/core/java/android/app/FragmentContainer.java
index 6ed54dc..77c9c31 100644
--- a/core/java/android/app/FragmentContainer.java
+++ b/core/java/android/app/FragmentContainer.java
@@ -31,7 +31,7 @@
      * view is not a child of this container.
      */
     @Nullable
-    public abstract View onFindViewById(@IdRes int id);
+    public abstract <T extends View> T onFindViewById(@IdRes int id);
 
     /**
      * Return {@code true} if the container holds any view.
diff --git a/core/java/android/app/FragmentHostCallback.java b/core/java/android/app/FragmentHostCallback.java
index fb60e07..5ef23e6 100644
--- a/core/java/android/app/FragmentHostCallback.java
+++ b/core/java/android/app/FragmentHostCallback.java
@@ -207,7 +207,7 @@
 
     @Nullable
     @Override
-    public View onFindViewById(int id) {
+    public <T extends View> T onFindViewById(int id) {
         return null;
     }
 
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 75d6295..91578a2 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1243,7 +1243,7 @@
                                                     + f
                                                     + " for a container view with no id"));
                                 }
-                                container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
+                                container = mContainer.onFindViewById(f.mContainerId);
                                 if (container == null && !f.mRestored) {
                                     String resName;
                                     try {
diff --git a/core/java/android/app/FragmentTransition.java b/core/java/android/app/FragmentTransition.java
index 780a922..9a920d7 100644
--- a/core/java/android/app/FragmentTransition.java
+++ b/core/java/android/app/FragmentTransition.java
@@ -193,7 +193,7 @@
             View nonExistentView, ArrayMap<String, String> nameOverrides) {
         ViewGroup sceneRoot = null;
         if (fragmentManager.mContainer.onHasView()) {
-            sceneRoot = (ViewGroup) fragmentManager.mContainer.onFindViewById(containerId);
+            sceneRoot = fragmentManager.mContainer.onFindViewById(containerId);
         }
         if (sceneRoot == null) {
             return;
@@ -265,7 +265,7 @@
             View nonExistentView, ArrayMap<String, String> nameOverrides) {
         ViewGroup sceneRoot = null;
         if (fragmentManager.mContainer.onHasView()) {
-            sceneRoot = (ViewGroup) fragmentManager.mContainer.onFindViewById(containerId);
+            sceneRoot = fragmentManager.mContainer.onFindViewById(containerId);
         }
         if (sceneRoot == null) {
             return;
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 9c18df8..4abca9a 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -165,7 +165,7 @@
         setContentView(com.android.internal.R.layout.search_bar);
 
         // get the view elements for local access
-        mSearchView = (SearchView) findViewById(com.android.internal.R.id.search_view);
+        mSearchView = findViewById(com.android.internal.R.id.search_view);
         mSearchView.setIconified(false);
         mSearchView.setOnCloseListener(mOnCloseListener);
         mSearchView.setOnQueryTextListener(mOnQueryChangeListener);
@@ -184,7 +184,7 @@
         mBadgeLabel = (TextView) mSearchView.findViewById(com.android.internal.R.id.search_badge);
         mSearchAutoComplete = (AutoCompleteTextView)
                 mSearchView.findViewById(com.android.internal.R.id.search_src_text);
-        mAppIcon = (ImageView) findViewById(com.android.internal.R.id.search_app_icon);
+        mAppIcon = findViewById(com.android.internal.R.id.search_app_icon);
         mSearchPlate = mSearchView.findViewById(com.android.internal.R.id.search_plate);
         mWorkingSpinner = getContext().getDrawable(com.android.internal.R.drawable.search_spinner);
         // TODO: Restore the spinner for slow suggestion lookups
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 19f7426..40fe6af 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -120,6 +120,8 @@
 import android.print.PrintManager;
 import android.view.autofill.AutofillManager;
 import android.view.autofill.IAutoFillManager;
+import android.service.oemlock.IOemLockService;
+import android.service.oemlock.OemLockManager;
 import android.service.persistentdata.IPersistentDataBlockService;
 import android.service.persistentdata.PersistentDataBlockManager;
 import android.service.vr.IVrManager;
@@ -752,6 +754,20 @@
                 }
             }});
 
+        registerService(Context.OEM_LOCK_SERVICE, OemLockManager.class,
+                new StaticServiceFetcher<OemLockManager>() {
+            @Override
+            public OemLockManager createService() throws ServiceNotFoundException {
+                IBinder b = ServiceManager.getServiceOrThrow(Context.OEM_LOCK_SERVICE);
+                IOemLockService oemLockService = IOemLockService.Stub.asInterface(b);
+                if (oemLockService != null) {
+                    return new OemLockManager(oemLockService);
+                } else {
+                    // not supported
+                    return null;
+                }
+            }});
+
         registerService(Context.MEDIA_PROJECTION_SERVICE, MediaProjectionManager.class,
                 new CachedServiceFetcher<MediaProjectionManager>() {
             @Override
diff --git a/core/java/android/app/TabActivity.java b/core/java/android/app/TabActivity.java
index 637c8c1..ad8b0db 100644
--- a/core/java/android/app/TabActivity.java
+++ b/core/java/android/app/TabActivity.java
@@ -108,7 +108,7 @@
     @Override
     public void onContentChanged() {
         super.onContentChanged();
-        mTabHost = (TabHost) findViewById(com.android.internal.R.id.tabhost);
+        mTabHost = findViewById(com.android.internal.R.id.tabhost);
 
         if (mTabHost == null) {
             throw new RuntimeException(
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index cb6fa05..e6cebc0 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -593,24 +593,34 @@
     public static final int TRANSPORT_LE = 2;
 
     /**
-     * 1M initiating PHY.
+     * Bluetooth LE 1M PHY.
      */
     public static final int PHY_LE_1M = 1;
 
     /**
-     * 2M initiating PHY.
+     * Bluetooth LE 2M PHY.
      */
     public static final int PHY_LE_2M = 2;
 
     /**
-     * LE Coded initiating PHY.
+     * Bluetooth LE Coded PHY.
      */
-    public static final int PHY_LE_CODED = 4;
+    public static final int PHY_LE_CODED = 3;
 
     /**
-     * Any LE PHY.
+     * Bluetooth LE 1M PHY mask.
      */
-    public static final int PHY_LE_ANY = PHY_LE_1M | PHY_LE_2M | PHY_LE_CODED;
+    public static final int PHY_LE_1M_MASK = 1;
+
+    /**
+     * Bluetooth LE 2M PHY mask.
+     */
+    public static final int PHY_LE_2M_MASK = 2;
+
+    /**
+     * Bluetooth LE Coded PHY mask.
+     */
+    public static final int PHY_LE_CODED_MASK = 4;
 
     /**
      * No preferred coding when transmitting on the LE Coded PHY.
@@ -1651,7 +1661,7 @@
      */
     public BluetoothGatt connectGatt(Context context, boolean autoConnect,
                                      BluetoothGattCallback callback, int transport) {
-        return (connectGatt(context, autoConnect,callback, TRANSPORT_AUTO, PHY_LE_1M));
+        return (connectGatt(context, autoConnect,callback, TRANSPORT_AUTO, PHY_LE_1M_MASK));
     }
 
     /**
@@ -1668,8 +1678,8 @@
      *             {@link BluetoothDevice#TRANSPORT_AUTO} or
      *             {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
      * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of
-     *             {@link BluetoothDevice#PHY_LE_1M}, {@link BluetoothDevice#PHY_LE_2M},
-     *             and {@link BluetoothDevice#PHY_LE_CODED}. This option does not take effect if
+     *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
+     *             and {@link BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if
      *             {@code autoConnect} is set to true.
      * @throws IllegalArgumentException if callback is null
      */
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 5d1e8ec..4aaf6bd 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -785,11 +785,11 @@
      * if no PHY change happens. It is also triggered when remote device updates the PHY.
      *
      * @param txPhy preferred transmitter PHY. Bitwise OR of any of
-     *             {@link BluetoothDevice#PHY_LE_1M}, {@link BluetoothDevice#PHY_LE_2M}, and
-     *             {@link BluetoothDevice#PHY_LE_CODED}.
+     *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
+     *             and {@link BluetoothDevice#PHY_LE_CODED_MASK}.
      * @param rxPhy preferred receiver PHY. Bitwise OR of any of
-     *             {@link BluetoothDevice#PHY_LE_1M}, {@link BluetoothDevice#PHY_LE_2M}, and
-     *             {@link BluetoothDevice#PHY_LE_CODED}.
+     *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
+     *             and {@link BluetoothDevice#PHY_LE_CODED_MASK}.
      * @param phyOptions preferred coding to use when transmitting on the LE Coded PHY. Can be one
      *             of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED},
      *             {@link BluetoothDevice#PHY_OPTION_S2} or {@link BluetoothDevice#PHY_OPTION_S8}
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index 2df2ed8..eddc278 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -558,11 +558,11 @@
      *
      * @param device The remote device to send this response to
      * @param txPhy preferred transmitter PHY. Bitwise OR of any of
-     *             {@link BluetoothDevice#PHY_LE_1M}, {@link BluetoothDevice#PHY_LE_2M}, and
-     *             {@link BluetoothDevice#PHY_LE_CODED}.
+     *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
+     *             and {@link BluetoothDevice#PHY_LE_CODED_MASK}.
      * @param rxPhy preferred receiver PHY. Bitwise OR of any of
-     *             {@link BluetoothDevice#PHY_LE_1M}, {@link BluetoothDevice#PHY_LE_2M}, and
-     *             {@link BluetoothDevice#PHY_LE_CODED}.
+     *             {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
+     *             and {@link BluetoothDevice#PHY_LE_CODED_MASK}.
      * @param phyOptions preferred coding to use when transmitting on the LE Coded PHY. Can be one
      *             of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED},
      *             {@link BluetoothDevice#PHY_OPTION_S2} or {@link BluetoothDevice#PHY_OPTION_S8}
diff --git a/core/java/android/bluetooth/le/AdvertisingSetParameters.java b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
index 4e9fac3..31d8f48 100644
--- a/core/java/android/bluetooth/le/AdvertisingSetParameters.java
+++ b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
@@ -17,6 +17,7 @@
 package android.bluetooth.le;
 
 import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -30,21 +31,6 @@
 public final class AdvertisingSetParameters implements Parcelable {
 
     /**
-     * 1M advertiser PHY.
-     */
-    public static final int PHY_LE_1M = 1;
-
-    /**
-     * 2M advertiser PHY.
-     */
-    public static final int PHY_LE_2M = 2;
-
-    /**
-     * LE Coded advertiser PHY.
-     */
-    public static final int PHY_LE_CODED = 3;
-
-    /**
     * Advertise on low frequency, around every 1000ms. This is the default and
     * preferred advertising mode as it consumes the least power.
     */
@@ -246,8 +232,8 @@
         private boolean isLegacy = false;
         private boolean isAnonymous = false;
         private boolean includeTxPower = false;
-        private int primaryPhy = PHY_LE_1M;
-        private int secondaryPhy = PHY_LE_1M;
+        private int primaryPhy = BluetoothDevice.PHY_LE_1M;
+        private int secondaryPhy = BluetoothDevice.PHY_LE_1M;
         private int interval = INTERVAL_LOW;
         private int txPowerLevel = TX_POWER_MEDIUM;
 
@@ -321,12 +307,13 @@
          * Use {@link BluetoothAdapter#isLeCodedPhySupported} to determine if LE Coded PHY is
          * supported on this device.
          * @param primaryPhy Primary advertising physical channel, can only be
-         *            {@link AdvertisingSetParameters#PHY_LE_1M} or
-         *            {@link AdvertisingSetParameters#PHY_LE_CODED}.
+         *            {@link BluetoothDevice#PHY_LE_1M} or
+         *            {@link BluetoothDevice#PHY_LE_CODED}.
          * @throws IllegalArgumentException If the primaryPhy is invalid.
          */
         public Builder setPrimaryPhy(int primaryPhy) {
-            if (primaryPhy != PHY_LE_1M && primaryPhy != PHY_LE_CODED) {
+            if (primaryPhy != BluetoothDevice.PHY_LE_1M &&
+                primaryPhy != BluetoothDevice.PHY_LE_CODED) {
                throw new IllegalArgumentException("bad primaryPhy " + primaryPhy);
             }
             this.primaryPhy = primaryPhy;
@@ -343,14 +330,15 @@
          * supported on this device.
          *
          * @param secondaryPhy Secondary advertising physical channel, can only be
-         *            one of {@link AdvertisingSetParameters#PHY_LE_1M},
-         *            {@link AdvertisingSetParameters#PHY_LE_2M} or
-         *            {@link AdvertisingSetParameters#PHY_LE_CODED}.
+         *            one of {@link BluetoothDevice#PHY_LE_1M},
+         *            {@link BluetoothDevice#PHY_LE_2M} or
+         *            {@link BluetoothDevice#PHY_LE_CODED}.
          * @throws IllegalArgumentException If the secondaryPhy is invalid.
          */
         public Builder setSecondaryPhy(int secondaryPhy) {
-            if (secondaryPhy != PHY_LE_1M && secondaryPhy !=PHY_LE_2M &&
-                secondaryPhy != PHY_LE_CODED) {
+            if (secondaryPhy != BluetoothDevice.PHY_LE_1M &&
+                secondaryPhy != BluetoothDevice.PHY_LE_2M &&
+                secondaryPhy != BluetoothDevice.PHY_LE_CODED) {
                throw new IllegalArgumentException("bad secondaryPhy " + secondaryPhy);
             }
             this.secondaryPhy = secondaryPhy;
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index 73fc133..ea3031b 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -17,6 +17,7 @@
 package android.bluetooth.le;
 
 import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothGatt;
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.IBluetoothGatt;
@@ -363,12 +364,12 @@
             boolean support2MPhy = mBluetoothAdapter.isLe2MPhySupported();
             int pphy = parameters.getPrimaryPhy();
             int sphy = parameters.getSecondaryPhy();
-            if (pphy == AdvertisingSetParameters.PHY_LE_CODED && !supportCodedPhy) {
+            if (pphy == BluetoothDevice.PHY_LE_CODED && !supportCodedPhy) {
                 throw new IllegalArgumentException("Unsupported primary PHY selected");
             }
 
-            if ((sphy == AdvertisingSetParameters.PHY_LE_CODED && !supportCodedPhy)
-                || (sphy == AdvertisingSetParameters.PHY_LE_2M && !support2MPhy)) {
+            if ((sphy == BluetoothDevice.PHY_LE_CODED && !supportCodedPhy)
+                || (sphy == BluetoothDevice.PHY_LE_2M && !support2MPhy)) {
                 throw new IllegalArgumentException("Unsupported secondary PHY selected");
             }
 
diff --git a/core/java/android/bluetooth/le/ScanResult.java b/core/java/android/bluetooth/le/ScanResult.java
index 745cd16..5b2fa40 100644
--- a/core/java/android/bluetooth/le/ScanResult.java
+++ b/core/java/android/bluetooth/le/ScanResult.java
@@ -47,21 +47,6 @@
     public static final int PHY_UNUSED = 0x00;
 
     /**
-     * Bluetooth LE 1Mbit advertiser PHY.
-     */
-    public static final int PHY_LE_1M = 0x01;
-
-    /**
-     * Bluetooth LE 2Mbit advertiser PHY.
-     */
-    public static final int PHY_LE_2M = 0x02;
-
-    /**
-     * Bluetooth LE Coded advertiser PHY.
-     */
-    public static final int PHY_LE_CODED = 0x03;
-
-    /**
      * Advertising Set ID is not present in the packet.
      */
     public static final int SID_NOT_PRESENT = 0xFF;
@@ -112,7 +97,7 @@
         mRssi = rssi;
         mTimestampNanos = timestampNanos;
         mEventType = (DATA_COMPLETE << 5) | ET_LEGACY_MASK | ET_CONNECTABLE_MASK;
-        mPrimaryPhy = PHY_LE_1M;
+        mPrimaryPhy = BluetoothDevice.PHY_LE_1M;
         mSecondaryPhy = PHY_UNUSED;
         mAdvertisingSid = SID_NOT_PRESENT;
         mTxPower = 127;
@@ -256,16 +241,16 @@
     /**
      * Returns the primary Physical Layer
      * on which this advertisment was received.
-     * Can be one of {@link ScanResult#PHY_LE_1M} or
-     * {@link ScanResult#PHY_LE_CODED}.
+     * Can be one of {@link BluetoothDevice#PHY_LE_1M} or
+     * {@link BluetoothDevice#PHY_LE_CODED}.
      */
     public int getPrimaryPhy() { return mPrimaryPhy; }
 
     /**
      * Returns the secondary Physical Layer
      * on which this advertisment was received.
-     * Can be one of {@link ScanResult#PHY_LE_1M},
-     * {@link ScanResult#PHY_LE_2M}, {@link ScanResult#PHY_LE_CODED}
+     * Can be one of {@link BluetoothDevice#PHY_LE_1M},
+     * {@link BluetoothDevice#PHY_LE_2M}, {@link BluetoothDevice#PHY_LE_CODED}
      * or {@link ScanResult#PHY_UNUSED} - if the advertisement
      * was not received on a secondary physical channel.
      */
diff --git a/core/java/android/bluetooth/le/ScanSettings.java b/core/java/android/bluetooth/le/ScanSettings.java
index 69c9a8c..36e48e9 100644
--- a/core/java/android/bluetooth/le/ScanSettings.java
+++ b/core/java/android/bluetooth/le/ScanSettings.java
@@ -17,6 +17,7 @@
 package android.bluetooth.le;
 
 import android.annotation.SystemApi;
+import android.bluetooth.BluetoothDevice;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -123,16 +124,6 @@
     public static final int SCAN_RESULT_TYPE_ABBREVIATED = 1;
 
     /**
-     * Use the Bluetooth LE 1Mbit PHY for scanning.
-     */
-    public static final int PHY_LE_1M = 1;
-
-    /**
-     * Use Bluetooth LE Coded PHY for scanning.
-     */
-    public static final int PHY_LE_CODED = 3;
-
-    /**
      * Use all supported PHYs for scanning.
      * This will check the controller capabilities, and start
      * the scan on 1Mbit and LE Coded PHYs if supported, or on
@@ -412,8 +403,8 @@
          * Selecting an unsupported phy will result in failure to start scan.
          *
          * @param phy Can be one of
-         *   {@link ScanSettings#PHY_LE_1M},
-         *   {@link ScanSettings#PHY_LE_CODED} or
+         *   {@link BluetoothDevice#PHY_LE_1M},
+         *   {@link BluetoothDevice#PHY_LE_CODED} or
          *   {@link ScanSettings#PHY_LE_ALL_SUPPORTED}
          */
         public Builder setPhy(int phy) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 6375775..18120c7 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2897,6 +2897,7 @@
             BATTERY_SERVICE,
             JOB_SCHEDULER_SERVICE,
             //@hide: PERSISTENT_DATA_BLOCK_SERVICE,
+            //@hide: OEM_LOCK_SERVICE,
             MEDIA_PROJECTION_SERVICE,
             MIDI_SERVICE,
             RADIO_SERVICE,
@@ -3819,6 +3820,17 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a {@link
+     * android.service.oemlock.OemLockManager} instance for managing the OEM lock.
+     *
+     * @see #getSystemService
+     * @see android.service.oemlock.OemLockManager
+     * @hide
+     */
+    @SystemApi
+    public static final String OEM_LOCK_SERVICE = "oem_lock";
+
+    /**
+     * Use with {@link #getSystemService} to retrieve a {@link
      * android.media.projection.MediaProjectionManager} instance for managing
      * media projection sessions.
      * @see #getSystemService
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 52a8760..2485bb8 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -657,6 +657,16 @@
     public static final String ACTION_VIEW = "android.intent.action.VIEW";
 
     /**
+     * Extra that can be included on activity intents coming from the storage UI
+     * when it launches sub-activities to manage various types of storage.  For example,
+     * it may use {@link #ACTION_VIEW} with a "image/*" MIME type to have an app show
+     * the images on the device, and in that case also include this extra to tell the
+     * app it is coming from the storage UI so should help the user manage storage of
+     * this type.
+     */
+    public static final String EXTRA_FROM_STORAGE = "android.intent.extra.FROM_STORAGE";
+
+    /**
      * A synonym for {@link #ACTION_VIEW}, the "standard" action that is
      * performed on a piece of data.
      */
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 4d76755..c3bdde5 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -275,10 +275,6 @@
         @Deprecated
         public static final int FLAG_GET_MANIFEST = FLAG_MATCH_MANIFEST;
 
-        /** @deprecated punted, don't use. */
-        @Deprecated
-        public static final int FLAG_MATCH_CHOOSER = 1 << 4;
-
         /**
          * Does not retrieve CHOOSER only shortcuts.
          * TODO: Add another flag for MATCH_ALL_PINNED
@@ -375,12 +371,6 @@
             return this;
         }
 
-        /** @deprecated punted, don't use. */
-        @Deprecated
-        public ShortcutQuery setIntent(@Nullable Intent intent) {
-            return this;
-        }
-
         /**
          * Set query options.  At least one of the {@code MATCH} flags should be set.  Otherwise,
          * no shortcuts will be returned.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 11c658a..430d8b1 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -4273,7 +4273,7 @@
                     a.intents.add(intent);
                 }
                 // adjust activity flags when we implicitly expose it via a browsable filter
-                intent.setVisibleToInstantApp(visibleToEphemeral || isWebBrowsableIntent(intent));
+                intent.setVisibleToInstantApp(visibleToEphemeral || isImplicitlyExposedIntent(intent));
                 if (intent.isVisibleToInstantApp()) {
                     a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
                 }
@@ -4306,7 +4306,7 @@
                     owner.preferredActivityFilters.add(intent);
                 }
                 // adjust activity flags when we implicitly expose it via a browsable filter
-                intent.setVisibleToInstantApp(visibleToEphemeral || isWebBrowsableIntent(intent));
+                intent.setVisibleToInstantApp(visibleToEphemeral || isImplicitlyExposedIntent(intent));
                 if (intent.isVisibleToInstantApp()) {
                     a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
                 }
@@ -4634,7 +4634,7 @@
                             + parser.getPositionDescription());
                 } else {
                     intent.setVisibleToInstantApp(
-                            visibleToEphemeral || isWebBrowsableIntent(intent));
+                            visibleToEphemeral || isImplicitlyExposedIntent(intent));
                     a.intents.add(intent);
                 }
                 // adjust activity flags when we implicitly expose it via a browsable filter
@@ -4836,7 +4836,7 @@
                 }
                 outInfo.intents.add(intent);
                 // adjust provider flags when we implicitly expose it via a browsable filter
-                intent.setVisibleToInstantApp(visibleToEphemeral || isWebBrowsableIntent(intent));
+                intent.setVisibleToInstantApp(visibleToEphemeral || isImplicitlyExposedIntent(intent));
                 if (intent.isVisibleToInstantApp()) {
                     outInfo.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL;
                 }
@@ -5141,7 +5141,7 @@
                     return null;
                 }
                 // adjust activity flags when we implicitly expose it via a browsable filter
-                intent.setVisibleToInstantApp(visibleToEphemeral || isWebBrowsableIntent(intent));
+                intent.setVisibleToInstantApp(visibleToEphemeral || isImplicitlyExposedIntent(intent));
                 if (intent.isVisibleToInstantApp()) {
                     s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL;
                 }
@@ -5182,8 +5182,11 @@
         return s;
     }
 
-    private boolean isWebBrowsableIntent(IntentInfo intent) {
-        return intent.hasCategory(Intent.CATEGORY_BROWSABLE);
+    private boolean isImplicitlyExposedIntent(IntentInfo intent) {
+        return intent.hasCategory(Intent.CATEGORY_BROWSABLE)
+                || intent.hasAction(Intent.ACTION_SEND)
+                || intent.hasAction(Intent.ACTION_SENDTO)
+                || intent.hasAction(Intent.ACTION_SEND_MULTIPLE);
     }
 
     private boolean parseAllMetaData(Resources res, XmlResourceParser parser, String tag,
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index 3f4a090..2b76ae2 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -1032,20 +1032,6 @@
             return this;
         }
 
-        /** @deprecated punted, don't use. */
-        @Deprecated
-        @NonNull
-        public Builder setChooserExtras(@NonNull PersistableBundle extras) {
-            return this;
-        }
-
-        /** @deprecated punted, don't use. */
-        @Deprecated
-        public Builder addChooserIntentFilter(@NonNull IntentFilter filter,
-                @NonNull ComponentName name) {
-            return this;
-        }
-
         /**
          * Creates a {@link ShortcutInfo} instance.
          */
@@ -1246,27 +1232,6 @@
         return mIntentPersistableExtrases;
     }
 
-    /** @deprecated punted, don't use. */
-    @Deprecated
-    @NonNull
-    public PersistableBundle getChooserExtras() {
-        return new PersistableBundle();
-    }
-
-    /** @deprecated punted, don't use. */
-    @Deprecated
-    @NonNull
-    public IntentFilter[] getChooserIntentFilters() {
-        return new IntentFilter[0];
-    }
-
-    /** @deprecated punted, don't use. */
-    @Deprecated
-    @NonNull
-    public ComponentName[] getChooserComponentNames() {
-        return new ComponentName[0];
-    }
-
     /**
      * "Rank" of a shortcut, which is a non-negative, sequential value that's unique for each
      * {@link #getActivity} for each of the two types of shortcuts (static and dynamic).
@@ -1388,12 +1353,6 @@
         return hasFlags(FLAG_PINNED);
     }
 
-    /** @deprecated punted, don't use. */
-    @Deprecated
-    public boolean isChooser() {
-        return false;
-    }
-
     /**
      * Return whether a shortcut is static; that is, whether a shortcut is
      * published from AndroidManifest.xml.  If {@code true}, the shortcut is
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index c8353c9..88c1627 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -127,7 +127,7 @@
      */
     public static final int COLOR_MODE_WIDE_COLOR_GAMUT_YES = 0x2;
 
-    /** Constant for {@link #colorMode}: bits that encode whether the dynamic range of the screen. */
+    /** Constant for {@link #colorMode}: bits that encode the dynamic range of the screen. */
     public static final int COLOR_MODE_HDR_MASK = 0xc;
     /** Constant for {@link #colorMode}: bits shift to get the screen dynamic range. */
     public static final int COLOR_MODE_HDR_SHIFT = 2;
@@ -155,7 +155,7 @@
             COLOR_MODE_HDR_UNDEFINED;
 
     /**
-     * Bit mask of for color capabilities of the screen. Currently there are two fields:
+     * Bit mask of color capabilities of the screen. Currently there are two fields:
      * <p>The {@link #COLOR_MODE_WIDE_COLOR_GAMUT_MASK} bits define the color gamut of
      * the screen. They may be one of
      * {@link #COLOR_MODE_WIDE_COLOR_GAMUT_NO} or {@link #COLOR_MODE_WIDE_COLOR_GAMUT_YES}.</p>
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index 0218cb5..a895f82 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -836,16 +836,16 @@
     }
 
     /**
-     * Test if sensor support direct channel backed by a specific type of shared memory.
+     * Test if a sensor supports a specified direct channel type.
      *
      * @param sharedMemType type of shared memory used by direct channel.
-     * @return <code>true</code> if the shared memory type is supported.
-     * @see SensorDirectChannel#TYPE_ASHMEM
+     * @return <code>true</code> if the specified shared memory type is supported.
+     * @see SensorDirectChannel#TYPE_MEMORY_FILE
      * @see SensorDirectChannel#TYPE_HARDWARE_BUFFER
      */
     public boolean isDirectChannelTypeSupported(@SensorDirectChannel.MemoryType int sharedMemType) {
         switch (sharedMemType) {
-            case SensorDirectChannel.TYPE_ASHMEM:
+            case SensorDirectChannel.TYPE_MEMORY_FILE:
                 return (mFlags & (1 << DIRECT_CHANNEL_SHIFT)) > 0;
             case SensorDirectChannel.TYPE_HARDWARE_BUFFER:
                 return (mFlags & (1 << DIRECT_CHANNEL_SHIFT + 1)) > 0;
diff --git a/core/java/android/hardware/SensorDirectChannel.java b/core/java/android/hardware/SensorDirectChannel.java
index a65d57d..bd7f9cf 100644
--- a/core/java/android/hardware/SensorDirectChannel.java
+++ b/core/java/android/hardware/SensorDirectChannel.java
@@ -23,26 +23,31 @@
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.nio.channels.Channel;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
- * Class representing a sensor direct channel. Use {@link
- * SensorManager#createDirectChannel(android.os.MemoryFile)} to obtain object.
+ * Class representing a sensor direct channel. Use
+ * {@link SensorManager#createDirectChannel(android.os.MemoryFile)} or
+ * {@link SensorManager#createDirectChannel(android.hardware.HardwareBuffer)}
+ * to obtain an object. The channel object can be then configured
+ * (see {@link #configure(Sensor, int)})
+ * to start delivery of sensor events into shared memory buffer.
  */
-public final class SensorDirectChannel implements AutoCloseable {
+public final class SensorDirectChannel implements Channel {
 
     // shared memory types
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(flag = true, value = {TYPE_ASHMEM, TYPE_HARDWARE_BUFFER})
+    @IntDef(flag = true, value = {TYPE_MEMORY_FILE, TYPE_HARDWARE_BUFFER})
     public @interface MemoryType {};
     /**
      * Shared memory type ashmem, wrapped in MemoryFile object.
      *
      * @see SensorManager#createDirectChannel(MemoryFile)
      */
-    public static final int TYPE_ASHMEM = 1;
+    public static final int TYPE_MEMORY_FILE = 1;
 
     /**
      * Shared memory type wrapped by HardwareBuffer object.
@@ -61,7 +66,7 @@
     /**
      * Sensor stopped (no event output).
      *
-     * @see SensorManager#configureDirectChannel(SensorDirectChannel, Sensor, int)
+     * @see #configure(Sensor, int)
      */
     public static final int RATE_STOP = 0;
     /**
@@ -70,7 +75,7 @@
      * The actual rate is expected to be between 55% to 220% of nominal rate, thus between 27.5Hz to
      * 110Hz.
      *
-     * @see SensorManager#configureDirectChannel(SensorDirectChannel, Sensor, int)
+     * @see #configure(Sensor, int)
      */
     public static final int RATE_NORMAL = 1; //50Hz
     /**
@@ -79,7 +84,7 @@
      * The actual rate is expected to be between 55% to 220% of nominal rate, thus between 110Hz to
      * 440Hz.
      *
-     * @see SensorManager#configureDirectChannel(SensorDirectChannel, Sensor, int)
+     * @see #configure(Sensor, int)
      */
     public static final int RATE_FAST = 2; // ~200Hz
     /**
@@ -88,7 +93,7 @@
      * The actual rate is expected to be between 55% to 220% of nominal rate, thus between 440Hz to
      * 1760Hz.
      *
-     * @see SensorManager#configureDirectChannel(SensorDirectChannel, Sensor, int)
+     * @see #configure(Sensor, int)
      */
     public static final int RATE_VERY_FAST = 3; // ~800Hz
 
@@ -98,10 +103,17 @@
      *
      * @return <code>true</code> if channel is valid.
      */
-    public boolean isValid() {
+    @Override
+    public boolean isOpen() {
         return !mClosed.get();
     }
 
+    /** @removed */
+    @Deprecated
+    public boolean isValid() {
+        return isOpen();
+    }
+
     /**
      * Close sensor direct channel.
      *
@@ -113,13 +125,61 @@
      */
     @Override
     public void close() {
-        mCloseGuard.close();
         if (mClosed.compareAndSet(false, true)) {
+            mCloseGuard.close();
             // actual close action
             mManager.destroyDirectChannel(this);
         }
     }
 
+    /**
+     * Configure sensor rate or stop sensor report.
+     *
+     * To start event report of a sensor, or change rate of existing report, call this function with
+     * rateLevel other than {@link android.hardware.SensorDirectChannel#RATE_STOP}. Sensor events
+     * will be added into a queue formed by the shared memory used in creation of direction channel.
+     * Each element of the queue has size of 104 bytes and represents a sensor event. Data
+     * structure of an element (all fields in little-endian):
+     *
+     * <pre>
+     *   offset   type                    name
+     * ------------------------------------------------------------------------
+     *   0x0000   int32_t                 size (always 104)
+     *   0x0004   int32_t                 sensor report token
+     *   0x0008   int32_t                 type (see SensorType)
+     *   0x000C   uint32_t                atomic counter
+     *   0x0010   int64_t                 timestamp (see Event)
+     *   0x0018   float[16]/int64_t[8]    data (data type depends on sensor type)
+     *   0x0058   int32_t[4]              reserved (set to zero)
+     * </pre>
+     *
+     * There are no head or tail pointers. The sequence and frontier of new sensor events is
+     * determined by the atomic counter, which counts from 1 after creation of direct channel and
+     * increments 1 for each new event. Atomic counter will wrap back to 1 after it reaches
+     * UINT32_MAX, skipping value 0 to avoid confusion with uninitialized memory. The writer in
+     * sensor system will wrap around from the start of shared memory region when it reaches the
+     * end. If size of memory region is not a multiple of size of element (104 bytes), the residual
+     * is not used at the end.  Function returns a positive sensor report token on success. This
+     * token can be used to differentiate sensor events from multiple sensor of the same type. For
+     * example, if there are two accelerometers in the system A and B, it is guaranteed different
+     * report tokens will be returned when starting sensor A and B.
+     *
+     * To stop a sensor, call this function with rateLevel equal {@link
+     * android.hardware.SensorDirectChannel#RATE_STOP}. If the sensor parameter is left to be null,
+     * this will stop all active sensor report associated with the direct channel specified.
+     * Function return 1 on success or 0 on failure.
+     *
+     * @param sensor A {@link android.hardware.Sensor} object to denote sensor to be operated.
+     * @param rateLevel rate level defined in {@link android.hardware.SensorDirectChannel}.
+     * @return * starting report or changing rate: positive sensor report token on success,
+     *                                             0 on failure;
+     *         * stopping report: 1 on success, 0 on failure.
+     * @throws NullPointerException when channel is null.
+     */
+    public int configure(Sensor sensor, @RateLevel int rateLevel) {
+        return mManager.configureDirectChannelImpl(this, sensor, rateLevel);
+    }
+
     /** @hide */
     SensorDirectChannel(SensorManager manager, int id, int type, long size) {
         mManager = manager;
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 1dc6478..ed56391 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -882,7 +882,12 @@
 
 
     /**
-     * Create a sensor direct channel backed by shared memory wrapped by MemoryFile object.
+     * Create a sensor direct channel backed by shared memory wrapped in MemoryFile object.
+     *
+     * The resulting channel can be used for delivering sensor events to native code, other
+     * processes, GPU/DSP or other co-processors without CPU intervention. This is the recommanded
+     * for high performance sensor applications that use high sensor rates (e.g. greater than 200Hz)
+     * and cares about sensor event latency.
      *
      * Use the returned {@link android.hardware.SensorDirectChannel} object to configure direct
      * report of sensor events. After use, call {@link android.hardware.SensorDirectChannel#close()}
@@ -890,7 +895,7 @@
      *
      * @param mem A {@link android.os.MemoryFile} shared memory object.
      * @return A {@link android.hardware.SensorDirectChannel} object if successful, null otherwise.
-     * @throws IllegalArgumentException when mem is null.
+     * @throws NullPointerException when mem is null.
      * @see SensorDirectChannel#close()
      * @see #configureDirectChannel(SensorDirectChannel, Sensor, int)
      */
@@ -899,7 +904,12 @@
     }
 
     /**
-     * Create a sensor direct channel backed by shared memory wrapped by HardwareBuffer object.
+     * Create a sensor direct channel backed by shared memory wrapped in HardwareBuffer object.
+     *
+     * The resulting channel can be used for delivering sensor events to native code, other
+     * processes, GPU/DSP or other co-processors without CPU intervention. This is the recommanded
+     * for high performance sensor applications that use high sensor rates (e.g. greater than 200Hz)
+     * and cares about sensor event latency.
      *
      * Use the returned {@link android.hardware.SensorDirectChannel} object to configure direct
      * report of sensor events. After use, call {@link android.hardware.SensorDirectChannel#close()}
@@ -908,7 +918,7 @@
      * @param mem A {@link android.hardware.HardwareBuffer} shared memory object.
      * @return A {@link android.hardware.SensorDirectChannel} object if successful,
      *         null otherwise.
-     * @throws IllegalArgumentException when mem is null.
+     * @throws NullPointerException when mem is null.
      * @see SensorDirectChannel#close()
      * @see #configureDirectChannel(SensorDirectChannel, Sensor, int)
      */
@@ -928,50 +938,9 @@
     /** @hide */
     protected abstract void destroyDirectChannelImpl(SensorDirectChannel channel);
 
-    /**
-     * Configure sensor rate or stop sensor report on a direct report channel specified.
-     *
-     * To start event report of a sensor, or change rate of existing report, call this function with
-     * rateLevel other than {@link android.hardware.SensorDirectChannel#RATE_STOP}. Sensor events
-     * will be added into a queue formed by the shared memory used in creation of direction channel.
-     * Each element of the queue has size of 104 bytes and represents a sensor event. Data
-     * structure of an element (all fields in little-endian):
-     *
-     *   offset   type                    name
-     *-  ---------------------------------------------
-     *   0x0000   int32_t                 size (always 104)
-     *   0x0004   int32_t                 sensor report token
-     *   0x0008   int32_t                 type (see SensorType)
-     *   0x000C   uint32_t                atomic counter
-     *   0x0010   int64_t                 timestamp (see Event)
-     *   0x0018   float[16]/int64_t[8]    data (data type depends on sensor type)
-     *   0x0058   int32_t[4]              reserved (set to zero)
-     *
-     * There is no head or tail pointers. The sequence and frontier of new sensor events is
-     * determined by the atomic counter, which counts from 1 after creation of direct channel and
-     * increments 1 for each new event. The writer in sensor system will wrap around from to
-     * start of shared memory region when it reaches the end. If size of memory region is not
-     * a multiple of size of element (104 bytes), the residual is not used at the end.
-     * Function returns a positive sensor report token on success. This token can be used for
-     * differentiate sensor events from multiple sensor of the same type. For example, if there are
-     * two accelerometer in the system A and B, it is guaranteed different report tokens will be
-     * returned when starting sensor A and B.
-     *
-     * To stop a sensor, call this function with rateLevel equal {@link
-     * android.hardware.SensorDirectChannel#RATE_STOP}. If the sensor parameter is left to be null,
-     * this will stop all active sensor report associated with the direct channel specified.
-     * Function return 1 on success or 0 on failure.
-     *
-     * @param channel A {@link android.hardware.SensorDirectChannel} object representing direct
-     *                channel to be configured.
-     * @param sensor A {@link android.hardware.Sensor} object to denote sensor to be operated.
-     * @param rateLevel rate level defined in {@link android.hardware.SensorDirectChannel}.
-     * @return starting report or changing rate: positive sensor report token on success, 0 on failure;
-     *         stopping report: 1 on success, 0 on failure.
-     * @throws IllegalArgumentException when SensorDirectChannel is null.
-     */
-    public int configureDirectChannel(SensorDirectChannel channel, Sensor sensor,
-            @SensorDirectChannel.RateLevel int rateLevel) {
+    /** @removed */
+    @Deprecated
+    public int configureDirectChannel(SensorDirectChannel channel, Sensor sensor, int rateLevel) {
         return configureDirectChannelImpl(channel, sensor, rateLevel);
     }
 
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 0677179..10c4cb3 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -35,6 +35,7 @@
 import com.android.internal.annotations.GuardedBy;
 
 import java.io.IOException;
+import java.io.UncheckedIOException;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -500,10 +501,8 @@
     /** @hide */
     protected int configureDirectChannelImpl(
             SensorDirectChannel channel, Sensor sensor, int rate) {
-        if (channel == null) throw new IllegalArgumentException("channel cannot be null");
-
-        if (!channel.isValid()) {
-            throw new IllegalStateException("channel is invalid");
+        if (!channel.isOpen()) {
+            throw new IllegalStateException("channel is closed");
         }
 
         if (rate < SensorDirectChannel.RATE_STOP
@@ -532,7 +531,8 @@
     /** @hide */
     protected SensorDirectChannel createDirectChannelImpl(
             MemoryFile memoryFile, HardwareBuffer hardwareBuffer) {
-        SensorDirectChannel ch = null;
+        int id;
+        int type;
         long size;
         if (memoryFile != null) {
             int fd;
@@ -549,11 +549,13 @@
             }
 
             size = memoryFile.length();
-            int id = nativeCreateDirectChannel(
-                    mNativeInstance, size, SensorDirectChannel.TYPE_ASHMEM, fd, null);
-            if (id > 0) {
-                ch = new SensorDirectChannel(this, id, SensorDirectChannel.TYPE_ASHMEM, size);
+            id = nativeCreateDirectChannel(
+                    mNativeInstance, size, SensorDirectChannel.TYPE_MEMORY_FILE, fd, null);
+            if (id <= 0) {
+                throw new UncheckedIOException(
+                        new IOException("create MemoryFile direct channel failed " + id));
             }
+            type = SensorDirectChannel.TYPE_MEMORY_FILE;
         } else if (hardwareBuffer != null) {
             if (hardwareBuffer.getFormat() != HardwareBuffer.BLOB) {
                 throw new IllegalArgumentException("Format of HardwareBuffer must be BLOB");
@@ -571,18 +573,18 @@
                         "HardwareBuffer must set usage flag USAGE0_SENSOR_DIRECT_DATA");
             }
             size = hardwareBuffer.getWidth();
-            int id = nativeCreateDirectChannel(
+            id = nativeCreateDirectChannel(
                     mNativeInstance, size, SensorDirectChannel.TYPE_HARDWARE_BUFFER,
                     -1, hardwareBuffer);
-            if (id > 0) {
-                ch = new SensorDirectChannel(
-                        this, id, SensorDirectChannel.TYPE_HARDWARE_BUFFER, size);
+            if (id <= 0) {
+                throw new UncheckedIOException(
+                        new IOException("create HardwareBuffer direct channel failed " + id));
             }
+            type = SensorDirectChannel.TYPE_HARDWARE_BUFFER;
         } else {
-            throw new IllegalArgumentException("Invalid parameter");
+            throw new NullPointerException("shared memory object cannot be null");
         }
-
-        return ch;
+        return new SensorDirectChannel(this, id, type, size);
     }
 
     /** @hide */
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index a529c2f..3267172 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -247,6 +247,7 @@
      * </p>
      *
      * @see #createVirtualDisplay
+     * @hide
      */
     public static final int VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 5;
 
diff --git a/core/java/android/inputmethodservice/ExtractEditLayout.java b/core/java/android/inputmethodservice/ExtractEditLayout.java
index 37ca4b4..af69f0f 100644
--- a/core/java/android/inputmethodservice/ExtractEditLayout.java
+++ b/core/java/android/inputmethodservice/ExtractEditLayout.java
@@ -41,6 +41,6 @@
     @Override
     public void onFinishInflate() {
         super.onFinishInflate();
-        mExtractActionButton = (Button) findViewById(com.android.internal.R.id.inputExtractAction);
+        mExtractActionButton = findViewById(com.android.internal.R.id.inputExtractAction);
     }
 }
diff --git a/core/java/android/net/ConnectivityMetricsEvent.java b/core/java/android/net/ConnectivityMetricsEvent.java
index 63ccaae..46bb346 100644
--- a/core/java/android/net/ConnectivityMetricsEvent.java
+++ b/core/java/android/net/ConnectivityMetricsEvent.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import com.android.internal.util.BitUtils;
 
 /**
  * Represents a core networking event defined in package android.net.metrics.
@@ -78,13 +79,15 @@
     public String toString() {
         StringBuilder buffer = new StringBuilder("ConnectivityMetricsEvent(");
         buffer.append(String.format("%tT.%tL", timestamp, timestamp));
-        // TODO: add transports
         if (netId != 0) {
             buffer.append(", ").append(netId);
         }
         if (ifname != null) {
             buffer.append(", ").append(ifname);
         }
+        for (int t : BitUtils.unpackBits(transports)) {
+            buffer.append(", ").append(NetworkCapabilities.transportNameOf(t));
+        }
         buffer.append("): ").append(data.toString());
         return buffer.toString();
     }
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 8665b9c..a594bef 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -19,7 +19,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
-import java.lang.IllegalArgumentException;
+import com.android.internal.util.BitUtils;
 
 /**
  * This class represents the capabilities of a network.  This is used both to specify
@@ -289,7 +289,7 @@
      * @hide
      */
     public int[] getCapabilities() {
-        return enumerateBits(mNetworkCapabilities);
+        return BitUtils.unpackBits(mNetworkCapabilities);
     }
 
     /**
@@ -305,19 +305,6 @@
         return ((mNetworkCapabilities & (1 << capability)) != 0);
     }
 
-    private int[] enumerateBits(long val) {
-        int size = Long.bitCount(val);
-        int[] result = new int[size];
-        int index = 0;
-        int resource = 0;
-        while (val > 0) {
-            if ((val & 1) == 1) result[index++] = resource;
-            val = val >> 1;
-            resource++;
-        }
-        return result;
-    }
-
     private void combineNetCapabilities(NetworkCapabilities nc) {
         this.mNetworkCapabilities |= nc.mNetworkCapabilities;
     }
@@ -428,6 +415,15 @@
     /** @hide */
     public static final int MAX_TRANSPORT = TRANSPORT_WIFI_AWARE;
 
+    private static final String[] TRANSPORT_NAMES = {
+        "CELLULAR",
+        "WIFI",
+        "BLUETOOTH",
+        "ETHERNET",
+        "VPN",
+        "WIFI_AWARE"
+    };
+
     /**
      * Adds the given transport type to this {@code NetworkCapability} instance.
      * Multiple transports may be applied sequentially.  Note that when searching
@@ -474,18 +470,7 @@
      * @hide
      */
     public int[] getTransportTypes() {
-        return enumerateBits(mTransportTypes);
-    }
-
-    /**
-     * Gets all the transports set on this {@code NetworkCapability} instance.
-     *
-     * @return a bit field composed of up bits at indexes defined by
-     * {@code NetworkCapabilities.TRANSPORT_*} values for this instance.
-     * @hide
-     */
-    public long getTransports() {
-        return mTransportTypes;
+        return BitUtils.unpackBits(mTransportTypes);
     }
 
     /**
@@ -899,18 +884,23 @@
      * @hide
      */
     public static String transportNamesOf(int[] types) {
-        String transports = "";
-        for (int i = 0; i < types.length;) {
-            switch (types[i]) {
-                case TRANSPORT_CELLULAR:    transports += "CELLULAR"; break;
-                case TRANSPORT_WIFI:        transports += "WIFI"; break;
-                case TRANSPORT_BLUETOOTH:   transports += "BLUETOOTH"; break;
-                case TRANSPORT_ETHERNET:    transports += "ETHERNET"; break;
-                case TRANSPORT_VPN:         transports += "VPN"; break;
-                case TRANSPORT_WIFI_AWARE:  transports += "WIFI_AWARE"; break;
-            }
-            if (++i < types.length) transports += "|";
+        if (types == null || types.length == 0) {
+            return "";
         }
-        return transports;
+        StringBuilder transports = new StringBuilder();
+        for (int t : types) {
+            transports.append("|").append(transportNameOf(t));
+        }
+        return transports.substring(1);
+    }
+
+    /**
+     * @hide
+     */
+    public static String transportNameOf(int transport) {
+        if (transport < 0 || TRANSPORT_NAMES.length <= transport) {
+            return "UNKNOWN";
+        }
+        return TRANSPORT_NAMES[transport];
     }
 }
diff --git a/core/java/android/net/metrics/ConnectStats.java b/core/java/android/net/metrics/ConnectStats.java
index 214edee..30b2656 100644
--- a/core/java/android/net/metrics/ConnectStats.java
+++ b/core/java/android/net/metrics/ConnectStats.java
@@ -16,53 +16,47 @@
 
 package android.net.metrics;
 
+import android.net.NetworkCapabilities;
 import android.system.OsConstants;
 import android.util.IntArray;
 import android.util.SparseIntArray;
+import com.android.internal.util.BitUtils;
 import com.android.internal.util.TokenBucket;
-import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.ConnectStatistics;
-import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.Pair;
 
 /**
- * A class that aggregates connect() statistics and helps build
- * IpConnectivityLogClass.ConnectStatistics instances.
- *
+ * A class that aggregates connect() statistics.
  * {@hide}
  */
 public class ConnectStats {
     private final static int EALREADY     = OsConstants.EALREADY;
     private final static int EINPROGRESS  = OsConstants.EINPROGRESS;
 
+    /** Network id of the network associated with the event, or 0 if unspecified. */
+    public final int netId;
+    /** Transports of the network associated with the event, as defined in NetworkCapabilities. */
+    public final long transports;
     /** How many events resulted in a given errno. */
-    private final SparseIntArray mErrnos = new SparseIntArray();
-    /** Latencies of blocking connects. TODO: add non-blocking connects latencies. */
-    private final IntArray mLatencies = new IntArray();
+    public final SparseIntArray errnos = new SparseIntArray();
+    /** Latencies of successful blocking connects. TODO: add non-blocking connects latencies. */
+    public final IntArray latencies = new IntArray();
     /** TokenBucket for rate limiting latency recording. */
-    private final TokenBucket mLatencyTb;
+    public final TokenBucket mLatencyTb;
     /** Maximum number of latency values recorded. */
-    private final int mMaxLatencyRecords;
+    public final int mMaxLatencyRecords;
     /** Total count of successful connects. */
-    private int mConnectCount = 0;
+    public int connectCount = 0;
     /** Total count of successful connects done in blocking mode. */
-    private int mConnectBlockingCount = 0;
+    public int connectBlockingCount = 0;
     /** Total count of successful connects with IPv6 socket address. */
-    private int mIpv6ConnectCount = 0;
+    public int ipv6ConnectCount = 0;
 
-    public ConnectStats(TokenBucket tb, int maxLatencyRecords) {
+    public ConnectStats(int netId, long transports, TokenBucket tb, int maxLatencyRecords) {
+        this.netId = netId;
+        this.transports = transports;
         mLatencyTb = tb;
         mMaxLatencyRecords = maxLatencyRecords;
     }
 
-    public ConnectStatistics toProto() {
-        ConnectStatistics stats = new ConnectStatistics();
-        stats.connectCount = mConnectCount;
-        stats.connectBlockingCount = mConnectBlockingCount;
-        stats.ipv6AddrCount = mIpv6ConnectCount;
-        stats.latenciesMs = mLatencies.toArray();
-        stats.errnosCounters = toPairArrays(mErrnos);
-        return stats;
-    }
-
     public void addEvent(int errno, int latencyMs, String ipAddr) {
         if (isSuccess(errno)) {
             countConnect(errno, ipAddr);
@@ -73,12 +67,12 @@
     }
 
     private void countConnect(int errno, String ipAddr) {
-        mConnectCount++;
+        connectCount++;
         if (!isNonBlocking(errno)) {
-            mConnectBlockingCount++;
+            connectBlockingCount++;
         }
         if (isIPv6(ipAddr)) {
-            mIpv6ConnectCount++;
+            ipv6ConnectCount++;
         }
     }
 
@@ -91,16 +85,16 @@
             // Rate limited
             return;
         }
-        if (mLatencies.size() >= mMaxLatencyRecords) {
+        if (latencies.size() >= mMaxLatencyRecords) {
             // Hard limit the total number of latency measurements.
             return;
         }
-        mLatencies.add(ms);
+        latencies.add(ms);
     }
 
     private void countError(int errno) {
-        final int newcount = mErrnos.get(errno, 0) + 1;
-        mErrnos.put(errno, newcount);
+        final int newcount = errnos.get(errno, 0) + 1;
+        errnos.put(errno, newcount);
     }
 
     private static boolean isSuccess(int errno) {
@@ -117,27 +111,18 @@
         return ipAddr.contains(":");
     }
 
-    private static Pair[] toPairArrays(SparseIntArray counts) {
-        final int s = counts.size();
-        Pair[] pairs = new Pair[s];
-        for (int i = 0; i < s; i++) {
-            Pair p = new Pair();
-            p.key = counts.keyAt(i);
-            p.value = counts.valueAt(i);
-            pairs[i] = p;
-        }
-        return pairs;
-    }
-
     @Override
     public String toString() {
-        StringBuilder builder = new StringBuilder("ConnectStats(")
-                .append(String.format("%d success, ", mConnectCount))
-                .append(String.format("%d blocking, ", mConnectBlockingCount))
-                .append(String.format("%d IPv6 dst", mIpv6ConnectCount));
-        for (int i = 0; i < mErrnos.size(); i++) {
-            String errno = OsConstants.errnoName(mErrnos.keyAt(i));
-            int count = mErrnos.valueAt(i);
+        StringBuilder builder = new StringBuilder("ConnectStats(").append(netId).append(", ");
+        for (int t : BitUtils.unpackBits(transports)) {
+            builder.append(NetworkCapabilities.transportNameOf(t)).append(", ");
+        }
+        builder.append(String.format("%d success, ", connectCount));
+        builder.append(String.format("%d blocking, ", connectBlockingCount));
+        builder.append(String.format("%d IPv6 dst", ipv6ConnectCount));
+        for (int i = 0; i < errnos.size(); i++) {
+            String errno = OsConstants.errnoName(errnos.keyAt(i));
+            int count = errnos.valueAt(i);
             builder.append(String.format(", %s: %d", errno, count));
         }
         return builder.append(")").toString();
diff --git a/core/java/android/net/metrics/DnsEvent.java b/core/java/android/net/metrics/DnsEvent.java
index 89ae1c2..a4970e4 100644
--- a/core/java/android/net/metrics/DnsEvent.java
+++ b/core/java/android/net/metrics/DnsEvent.java
@@ -16,67 +16,70 @@
 
 package android.net.metrics;
 
-import android.os.Parcel;
-import android.os.Parcelable;
+import android.net.NetworkCapabilities;
+import java.util.Arrays;
+import com.android.internal.util.BitUtils;
 
 /**
  * A DNS event recorded by NetdEventListenerService.
  * {@hide}
  */
-final public class DnsEvent implements Parcelable {
-    public final int netId;
+final public class DnsEvent {
 
-    // The event type is currently only 1 or 2, so we store it as a byte.
-    public final byte[] eventTypes;
+    private static final int SIZE_LIMIT = 20000;
+
+    // Network id of the network associated with the event, or 0 if unspecified.
+    public final int netId;
+    // Transports of the network associated with the event, as defined in NetworkCapabilities.
+    // It is the caller responsability to ensure the value of transports does not change between
+    // calls to addResult.
+    public final long transports;
+    // The number of DNS queries recorded. Queries are stored in the structure-of-array style where
+    // the eventTypes, returnCodes, and latenciesMs arrays have the same length and the i-th event
+    // is spread across the three array at position i.
+    public int eventCount;
+    // The types of DNS queries as defined in INetdEventListener.
+    public byte[] eventTypes;
     // Current getaddrinfo codes go from 1 to EAI_MAX = 15. gethostbyname returns errno, but there
     // are fewer than 255 errno values. So we store the result code in a byte as well.
-    public final byte[] returnCodes;
-    // The latency is an integer because a) short arrays aren't parcelable and b) a short can only
-    // store a maximum latency of 32757 or 65535 ms, which is too short for pathologically slow
-    // queries.
-    public final int[] latenciesMs;
+    public byte[] returnCodes;
+    // Latencies in milliseconds of queries, stored as ints.
+    public int[] latenciesMs;
 
-    public DnsEvent(int netId, byte[] eventTypes, byte[] returnCodes, int[] latenciesMs) {
+    public DnsEvent(int netId, long transports, int initialCapacity) {
         this.netId = netId;
-        this.eventTypes = eventTypes;
-        this.returnCodes = returnCodes;
-        this.latenciesMs = latenciesMs;
+        this.transports = transports;
+        eventTypes = new byte[initialCapacity];
+        returnCodes = new byte[initialCapacity];
+        latenciesMs = new int[initialCapacity];
     }
 
-    private DnsEvent(Parcel in) {
-        this.netId = in.readInt();
-        this.eventTypes = in.createByteArray();
-        this.returnCodes = in.createByteArray();
-        this.latenciesMs = in.createIntArray();
+    public void addResult(byte eventType, byte returnCode, int latencyMs) {
+        if (eventCount >= SIZE_LIMIT) {
+            // TODO: implement better rate limiting that does not biases metrics.
+            return;
+        }
+        if (eventCount == eventTypes.length) {
+            resize((int) (1.4 * eventCount));
+        }
+        eventTypes[eventCount] = eventType;
+        returnCodes[eventCount] = returnCode;
+        latenciesMs[eventCount] = latencyMs;
+        eventCount++;
     }
 
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(netId);
-        out.writeByteArray(eventTypes);
-        out.writeByteArray(returnCodes);
-        out.writeIntArray(latenciesMs);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
+    public void resize(int newLength) {
+        eventTypes = Arrays.copyOf(eventTypes, newLength);
+        returnCodes = Arrays.copyOf(returnCodes, newLength);
+        latenciesMs = Arrays.copyOf(latenciesMs, newLength);
     }
 
     @Override
     public String toString() {
-        return String.format("DnsEvent(%d, %d events)", netId, eventTypes.length);
+        StringBuilder builder = new StringBuilder("DnsEvent(").append(netId).append(", ");
+        for (int t : BitUtils.unpackBits(transports)) {
+            builder.append(NetworkCapabilities.transportNameOf(t)).append(", ");
+        }
+        return builder.append(eventCount).append(" events)").toString();
     }
-
-    public static final Parcelable.Creator<DnsEvent> CREATOR = new Parcelable.Creator<DnsEvent>() {
-        @Override
-        public DnsEvent createFromParcel(Parcel in) {
-            return new DnsEvent(in);
-        }
-
-        @Override
-        public DnsEvent[] newArray(int size) {
-            return new DnsEvent[size];
-        }
-    };
 }
diff --git a/core/java/android/net/metrics/IpConnectivityLog.java b/core/java/android/net/metrics/IpConnectivityLog.java
index ac727ca..4e57efa 100644
--- a/core/java/android/net/metrics/IpConnectivityLog.java
+++ b/core/java/android/net/metrics/IpConnectivityLog.java
@@ -23,6 +23,7 @@
 import android.os.ServiceManager;
 import android.util.Log;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.BitUtils;
 
 /**
  * Class for logging IpConnectvity events with IpConnectivityMetrics
@@ -117,10 +118,10 @@
      * @param data is a Parcelable instance representing the event.
      * @return true if the event was successfully logged.
      */
-    public boolean log(int netid, long transports, Parcelable data) {
+    public boolean log(int netid, int[] transports, Parcelable data) {
         ConnectivityMetricsEvent ev = makeEv(data);
         ev.netId = netid;
-        ev.transports = transports;
+        ev.transports = BitUtils.packBits(transports);
         return log(ev);
     }
 
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a6bf2d2..6f4c9cf 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -682,8 +682,10 @@
      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
      * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
      * @see #getUserRestrictions()
+     * @deprecated use {@link OemLockManager#setOemUnlockAllowedByCarrier(boolean, byte[])} instead.
      * @hide
      */
+    @Deprecated
     @SystemApi
     public static final String DISALLOW_OEM_UNLOCK = "no_oem_unlock";
 
diff --git a/core/java/android/os/VintfObject.java b/core/java/android/os/VintfObject.java
new file mode 100644
index 0000000..1ef3916
--- /dev/null
+++ b/core/java/android/os/VintfObject.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 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;
+
+import java.util.ArrayList;
+
+import android.util.Log;
+
+/** @hide */
+public class VintfObject {
+
+    private static final String LOG_TAG = "VintfObject";
+
+    /**
+     * Slurps all device information (both manifests)
+     * and report it.
+     * If any error in getting one of the manifests, it is not included in
+     * the list.
+     */
+    public static String[] report() {
+        ArrayList<String> ret = new ArrayList<>();
+        put(ret, getDeviceManifest(), "device manifest");
+        put(ret, getFrameworkManifest(), "framework manifest");
+        return ret.toArray(new String[0]);
+    }
+
+    /**
+     * Verify that the given metadata for an OTA package is compatible with
+     * this device.
+     *
+     * @param packageInfo a list of serialized form of HalMaanifest's /
+     * CompatibilityMatri'ces (XML).
+     * @return = 0 if success (compatible)
+     *         > 0 if incompatible
+     *         < 0 if any error (mount partition fails, illformed XML, etc.)
+     */
+    public static native int verify(String[] packageInfo);
+
+    // return null if any error, otherwise XML string.
+    private static native String getDeviceManifest();
+    private static native String getFrameworkManifest();
+
+    private static void put(ArrayList<String> list, String content, String message) {
+        if (content == null || content.length() == 0) {
+            Log.e(LOG_TAG, "Cannot get;" + message + "; check native logs for details.");
+            return;
+        }
+        list.add(content);
+    }
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 05bacae..539559d 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8844,6 +8844,15 @@
         public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
 
         /**
+         * A comma separated list of URLs used for captive portal detection in addition to the
+         * fallback HTTP url associated with the CAPTIVE_PORTAL_FALLBACK_URL settings.
+         *
+         * @hide
+         */
+        public static final String CAPTIVE_PORTAL_OTHER_FALLBACK_URLS =
+                "captive_portal_other_fallback_urls";
+
+        /**
          * Whether to use HTTPS for network validation. This is enabled by default and the setting
          * needs to be set to 0 to disable it. This setting is a misnomer because captive portals
          * don't actually use HTTPS, but it's consistent with the other settings.
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 94505d3..6a15ade 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -462,7 +462,7 @@
      * @return The view if found or null otherwise.
      */
     @Nullable
-    public View findViewById(@IdRes int id) {
+    public <T extends View> T findViewById(@IdRes int id) {
         return getWindow().findViewById(id);
     }
 
diff --git a/core/java/android/service/oemlock/IOemLockService.aidl b/core/java/android/service/oemlock/IOemLockService.aidl
new file mode 100644
index 0000000..2c606f9
--- /dev/null
+++ b/core/java/android/service/oemlock/IOemLockService.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 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.service.oemlock;
+
+/**
+ * Interface for communication with the OemLockService.
+ *
+ * @hide
+ */
+interface IOemLockService {
+    void setOemUnlockAllowedByCarrier(boolean allowed, in byte[] signature);
+    boolean isOemUnlockAllowedByCarrier();
+
+    void setOemUnlockAllowedByUser(boolean allowed);
+    boolean isOemUnlockAllowedByUser();
+}
diff --git a/core/java/android/service/oemlock/OemLockManager.java b/core/java/android/service/oemlock/OemLockManager.java
new file mode 100644
index 0000000..c4fbe5e
--- /dev/null
+++ b/core/java/android/service/oemlock/OemLockManager.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2017 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.service.oemlock;
+
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.RemoteException;
+
+/**
+ * Interface for managing the OEM lock on the device.
+ *
+ * This will only be available if the device implements OEM lock protection.
+ *
+ * Multiple actors have an opinion on whether the device can be OEM unlocked and they must all be in
+ * agreement for unlock to be possible.
+ *
+ * @hide
+ */
+@SystemApi
+public class OemLockManager {
+    private IOemLockService mService;
+
+    /** @hide */
+    public OemLockManager(IOemLockService service) {
+        mService = service;
+    }
+
+    /**
+     * Sets whether the carrier has allowed this device to be OEM unlocked.
+     *
+     * Depending on the implementation, the validity of the request might need to be proved. This
+     * can be acheived by passing a signature that the system will use to verify the request is
+     * legitimate.
+     *
+     * All actors involved must agree for OEM unlock to be possible.
+     *
+     * @param allowed Whether the device should be allowed to be unlocked.
+     * @param signature Optional proof of request validity, {@code null} for none.
+     * @throws IllegalArgumentException if a signature is required but was not provided.
+     * @throws SecurityException if the wrong signature was provided.
+     *
+     * @see #isOemUnlockAllowedByCarrier()
+     */
+    public void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) {
+        try {
+            mService.setOemUnlockAllowedByCarrier(allowed, signature);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns whether the carrier has allowed this device to be OEM unlocked.
+     * @return Whether OEM unlock is allowed by the carrier, or true if no OEM lock is present.
+     *
+     * @see #setOemUnlockAllowedByCarrier(boolean, byte[])
+     */
+    public boolean isOemUnlockAllowedByCarrier() {
+        try {
+            return mService.isOemUnlockAllowedByCarrier();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Sets whether the user has allowed this device to be unlocked.
+     *
+     * All actors involved must agree for OEM unlock to be possible.
+     *
+     * @param unlocked Whether the device should be made OEM unlocked.
+     *
+     * @see #isOemUnlockAllowedByUser()
+     */
+    public void setOemUnlockAllowedByUser(boolean allowed) {
+        try {
+            mService.setOemUnlockAllowedByUser(allowed);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns whether, or not, the user has allowed this device to be OEM unlocked.
+     * @return Whether OEM unlock is allowed by the user, or true if no OEM lock is present.
+     *
+     * @see #setOemUnlockAllowedByUser(boolean)
+     */
+    public boolean isOemUnlockAllowedByUser() {
+        try {
+            return mService.isOemUnlockAllowedByUser();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+}
diff --git a/core/java/android/service/persistentdata/PersistentDataBlockManager.java b/core/java/android/service/persistentdata/PersistentDataBlockManager.java
index cb021bc..326796a 100644
--- a/core/java/android/service/persistentdata/PersistentDataBlockManager.java
+++ b/core/java/android/service/persistentdata/PersistentDataBlockManager.java
@@ -146,6 +146,8 @@
 
     /**
      * Writes a byte enabling or disabling the ability to "OEM unlock" the device.
+     *
+     * @deprecated use {@link OemLockManager#setOemUnlockAllowedByUser(boolean)} instead.
      */
     public void setOemUnlockEnabled(boolean enabled) {
         try {
@@ -157,6 +159,8 @@
 
     /**
      * Returns whether or not "OEM unlock" is enabled or disabled on this device.
+     *
+     * @deprecated use {@link OemLockManager#isOemUnlockAllowedByUser()} instead.
      */
     public boolean getOemUnlockEnabled() {
         try {
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 6dedbde..3e9fab1 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -205,6 +205,7 @@
      * </p>
      *
      * @see #getFlags
+     * @hide
      */
     public static final int FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 5;
 
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index 7792939..f47c355 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -18,14 +18,17 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.content.pm.PackageManager;
 import android.graphics.Rect;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -58,7 +61,7 @@
     private final UserSpecifiedFocusComparator mUserSpecifiedClusterComparator =
             new UserSpecifiedFocusComparator((r, v) -> isValidId(v.getNextClusterForwardId())
                     ? v.findUserSetNextKeyboardNavigationCluster(r, View.FOCUS_FORWARD) : null);
-    private final FocusComparator mFocusComparator = new FocusComparator();
+    private final FocusSorter mFocusSorter = new FocusSorter();
 
     private final ArrayList<View> mTempList = new ArrayList<View>();
 
@@ -760,66 +763,102 @@
         return id != 0 && id != View.NO_ID;
     }
 
-    static FocusComparator getFocusComparator(ViewGroup root, boolean isRtl) {
-        FocusComparator comparator = getInstance().mFocusComparator;
-        comparator.setRoot(root);
-        comparator.setIsLayoutRtl(isRtl);
-        return comparator;
-    }
+    static final class FocusSorter {
+        private ArrayList<Rect> mRectPool = new ArrayList<>();
+        private int mLastPoolRect;
+        private int mRtlMult;
+        private HashMap<View, Rect> mRectByView = null;
 
-    static final class FocusComparator implements Comparator<View> {
-        private final Rect mFirstRect = new Rect();
-        private final Rect mSecondRect = new Rect();
-        private ViewGroup mRoot = null;
-        private boolean mIsLayoutRtl;
-
-        public void setIsLayoutRtl(boolean b) {
-            mIsLayoutRtl = b;
-        }
-
-        public void setRoot(ViewGroup root) {
-            mRoot = root;
-        }
-
-        public int compare(View first, View second) {
+        private Comparator<View> mTopsComparator = (first, second) -> {
             if (first == second) {
                 return 0;
             }
 
-            getRect(first, mFirstRect);
-            getRect(second, mSecondRect);
+            Rect firstRect = mRectByView.get(first);
+            Rect secondRect = mRectByView.get(second);
 
-            if (mFirstRect.top < mSecondRect.top) {
-                return -1;
-            } else if (mFirstRect.top > mSecondRect.top) {
-                return 1;
-            } else if (mFirstRect.left < mSecondRect.left) {
-                return mIsLayoutRtl ? 1 : -1;
-            } else if (mFirstRect.left > mSecondRect.left) {
-                return mIsLayoutRtl ? -1 : 1;
-            } else if (mFirstRect.bottom < mSecondRect.bottom) {
-                return -1;
-            } else if (mFirstRect.bottom > mSecondRect.bottom) {
-                return 1;
-            } else if (mFirstRect.right < mSecondRect.right) {
-                return mIsLayoutRtl ? 1 : -1;
-            } else if (mFirstRect.right > mSecondRect.right) {
-                return mIsLayoutRtl ? -1 : 1;
-            } else {
-                // The view are distinct but completely coincident so we consider
-                // them equal for our purposes.  Since the sort is stable, this
-                // means that the views will retain their layout order relative to one another.
+            int result = firstRect.top - secondRect.top;
+            if (result == 0) {
+                return firstRect.bottom - secondRect.bottom;
+            }
+            return result;
+        };
+
+        private Comparator<View> mSidesComparator = (first, second) -> {
+            if (first == second) {
                 return 0;
             }
-        }
 
-        private void getRect(View view, Rect rect) {
-            view.getDrawingRect(rect);
-            mRoot.offsetDescendantRectToMyCoords(view, rect);
+            Rect firstRect = mRectByView.get(first);
+            Rect secondRect = mRectByView.get(second);
+
+            int result = firstRect.left - secondRect.left;
+            if (result == 0) {
+                return firstRect.right - secondRect.right;
+            }
+            return mRtlMult * result;
+        };
+
+        public void sort(View[] views, int start, int end, ViewGroup root, boolean isRtl) {
+            int count = end - start;
+            if (count < 2) {
+                return;
+            }
+            if (mRectByView == null) {
+                mRectByView = new HashMap<>();
+            }
+            mRtlMult = isRtl ? -1 : 1;
+            for (int i = mRectPool.size(); i < count; ++i) {
+                mRectPool.add(new Rect());
+            }
+            for (int i = start; i < end; ++i) {
+                Rect next = mRectPool.get(mLastPoolRect++);
+                views[i].getDrawingRect(next);
+                root.offsetDescendantRectToMyCoords(views[i], next);
+                mRectByView.put(views[i], next);
+            }
+
+            // Sort top-to-bottom
+            Arrays.sort(views, start, count, mTopsComparator);
+            // Sweep top-to-bottom to identify rows
+            int sweepBottom = mRectByView.get(views[start]).bottom;
+            int rowStart = start;
+            int sweepIdx = start + 1;
+            for (; sweepIdx < end; ++sweepIdx) {
+                Rect currRect = mRectByView.get(views[sweepIdx]);
+                if (currRect.top >= sweepBottom) {
+                    // Next view is on a new row, sort the row we've just finished left-to-right.
+                    if ((sweepIdx - rowStart) > 1) {
+                        Arrays.sort(views, rowStart, sweepIdx, mSidesComparator);
+                    }
+                    sweepBottom = currRect.bottom;
+                    rowStart = sweepIdx;
+                } else {
+                    // Next view vertically overlaps, we need to extend our "row height"
+                    sweepBottom = Math.max(sweepBottom, currRect.bottom);
+                }
+            }
+            // Sort whatever's left (final row) left-to-right
+            if ((sweepIdx - rowStart) > 1) {
+                Arrays.sort(views, rowStart, sweepIdx, mSidesComparator);
+            }
+
+            mLastPoolRect = 0;
+            mRectByView.clear();
         }
     }
 
     /**
+     * Public for testing.
+     *
+     * @hide
+     */
+    @TestApi
+    public static void sort(View[] views, int start, int end, ViewGroup root, boolean isRtl) {
+        getInstance().mFocusSorter.sort(views, start, end, root, isRtl);
+    }
+
+    /**
      * Sorts views according to any explicitly-specified focus-chains. If there are no explicitly
      * specified focus chains (eg. no nextFocusForward attributes defined), this should be a no-op.
      */
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index fe91978..20f7ace 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -94,8 +94,8 @@
         super.onFinishInflate();
         mAppName = findViewById(com.android.internal.R.id.app_name_text);
         mHeaderText = findViewById(com.android.internal.R.id.header_text);
-        mExpandButton = (ImageView) findViewById(com.android.internal.R.id.expand_button);
-        mIcon = (CachingIconView) findViewById(com.android.internal.R.id.icon);
+        mExpandButton = findViewById(com.android.internal.R.id.expand_button);
+        mIcon = findViewById(com.android.internal.R.id.icon);
         mProfileBadge = findViewById(com.android.internal.R.id.profile_badge);
     }
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 9072bf9..a522652 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -321,7 +321,7 @@
  * </pre></li>
  * <li>From the onCreate method of an Activity, find the Button
  * <pre class="prettyprint">
- *      Button myButton = (Button) findViewById(R.id.my_button);
+ *      Button myButton = findViewById(R.id.my_button);
  * </pre></li>
  * </ul>
  * <p>
@@ -6970,7 +6970,10 @@
             dispatchPopulateAccessibilityEvent(event);
         }
         // In the beginning we called #isShown(), so we know that getParent() is not null.
-        getParent().requestSendAccessibilityEvent(this, event);
+        ViewParent parent = getParent();
+        if (parent != null) {
+            getParent().requestSendAccessibilityEvent(this, event);
+        }
     }
 
     /**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 9e1ceee..f9eb25d 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -61,7 +61,6 @@
 import com.android.internal.R;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
@@ -1216,7 +1215,7 @@
                 children[count++] = child;
             }
         }
-        Arrays.sort(children, 0, count, FocusFinder.getFocusComparator(this, false));
+        FocusFinder.sort(children, 0, count, this, isLayoutRtl());
         for (int i = 0; i < count; ++i) {
             children[i].addFocusables(views, direction, focusableMode);
         }
@@ -1266,7 +1265,7 @@
                 visibleChildren[count++] = child;
             }
         }
-        Arrays.sort(visibleChildren, 0, count, FocusFinder.getFocusComparator(this, false));
+        FocusFinder.sort(visibleChildren, 0, count, this, isLayoutRtl());
         for (int i = 0; i < count; ++i) {
             visibleChildren[i].addKeyboardNavigationClusters(views, direction);
         }
diff --git a/core/java/android/view/ViewStub.java b/core/java/android/view/ViewStub.java
index 85d10f1..e9d1b87 100644
--- a/core/java/android/view/ViewStub.java
+++ b/core/java/android/view/ViewStub.java
@@ -58,7 +58,7 @@
  * The preferred way to perform the inflation of the layout resource is the following:
  *
  * <pre>
- *     ViewStub stub = (ViewStub) findViewById(R.id.stub);
+ *     ViewStub stub = findViewById(R.id.stub);
  *     View inflated = stub.inflate();
  * </pre>
  *
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index e85a658..41c209c 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -1068,5 +1068,19 @@
                 });
             }
         }
+
+        @Override
+        public void startIntentSender(IntentSender intentSender) {
+            final AutofillManager afm = mAfm.get();
+            if (afm != null) {
+                afm.mContext.getMainThreadHandler().post(() -> {
+                    try {
+                        afm.mContext.startIntentSender(intentSender, null, 0, 0, 0);
+                    } catch (IntentSender.SendIntentException e) {
+                        Log.e(TAG, "startIntentSender() failed for intent:" + intentSender, e);
+                    }
+                });
+            }
+        }
     }
 }
diff --git a/core/java/android/view/autofill/IAutoFillManagerClient.aidl b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
index 7bea174..176eaac 100644
--- a/core/java/android/view/autofill/IAutoFillManagerClient.aidl
+++ b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
@@ -59,7 +59,12 @@
     void requestHideFillUi(in IBinder windowToken, in AutofillId id);
 
     /**
-     * Nitifies no fill UI will be shown.
+     * Notifies no fill UI will be shown.
      */
     void notifyNoFillUi(in IBinder windowToken, in AutofillId id);
+
+    /**
+     * Starts the provided intent sender
+     */
+    void startIntentSender(in IntentSender intentSender);
 }
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 06d4868..6df76fa 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -151,8 +151,8 @@
             mShowRevokeUI = showRevokeUI;
             mPackageName = packageName;
 
-            ImageView permGrpIcon = (ImageView) findViewById(R.id.perm_icon);
-            TextView permNameView = (TextView) findViewById(R.id.perm_name);
+            ImageView permGrpIcon = findViewById(R.id.perm_icon);
+            TextView permNameView = findViewById(R.id.perm_name);
 
             PackageManager pm = getContext().getPackageManager();
             Drawable icon = null;
diff --git a/core/java/android/widget/Button.java b/core/java/android/widget/Button.java
index 09e09b7..09ba553 100644
--- a/core/java/android/widget/Button.java
+++ b/core/java/android/widget/Button.java
@@ -37,7 +37,7 @@
  *
  *         setContentView(R.layout.content_layout_id);
  *
- *         final Button button = (Button) findViewById(R.id.button_id);
+ *         final Button button = findViewById(R.id.button_id);
  *         button.setOnClickListener(new View.OnClickListener() {
  *             public void onClick(View v) {
  *                 // Perform action on click
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index 0f0e6c3..be0967f 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -124,13 +124,13 @@
             addView(child);
         }
 
-        mPrevButton = (ImageButton) findViewById(R.id.prev);
+        mPrevButton = findViewById(R.id.prev);
         mPrevButton.setOnClickListener(mOnClickListener);
 
-        mNextButton = (ImageButton) findViewById(R.id.next);
+        mNextButton = findViewById(R.id.next);
         mNextButton.setOnClickListener(mOnClickListener);
 
-        mViewPager = (ViewPager) findViewById(R.id.day_picker_view_pager);
+        mViewPager = findViewById(R.id.day_picker_view_pager);
         mViewPager.setAdapter(mAdapter);
         mViewPager.setOnPageChangeListener(mOnPageChangedListener);
 
diff --git a/core/java/android/widget/MultiAutoCompleteTextView.java b/core/java/android/widget/MultiAutoCompleteTextView.java
index 2152e43..f348d73 100644
--- a/core/java/android/widget/MultiAutoCompleteTextView.java
+++ b/core/java/android/widget/MultiAutoCompleteTextView.java
@@ -43,7 +43,7 @@
  *
  *         ArrayAdapter&lt;String&gt; adapter = new ArrayAdapter&lt;String&gt;(this,
  *                 android.R.layout.simple_dropdown_item_1line, COUNTRIES);
- *         MultiAutoCompleteTextView textView = (MultiAutoCompleteTextView) findViewById(R.id.edit);
+ *         MultiAutoCompleteTextView textView = findViewById(R.id.edit);
  *         textView.setAdapter(adapter);
  *         textView.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
  *     }
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 662e640..7bdd6da 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -706,7 +706,7 @@
 
         // increment button
         if (!mHasSelectorWheel) {
-            mIncrementButton = (ImageButton) findViewById(R.id.increment);
+            mIncrementButton = findViewById(R.id.increment);
             mIncrementButton.setOnClickListener(onClickListener);
             mIncrementButton.setOnLongClickListener(onLongClickListener);
         } else {
@@ -715,7 +715,7 @@
 
         // decrement button
         if (!mHasSelectorWheel) {
-            mDecrementButton = (ImageButton) findViewById(R.id.decrement);
+            mDecrementButton = findViewById(R.id.decrement);
             mDecrementButton.setOnClickListener(onClickListener);
             mDecrementButton.setOnLongClickListener(onLongClickListener);
         } else {
@@ -723,7 +723,7 @@
         }
 
         // input text
-        mInputText = (EditText) findViewById(R.id.numberpicker_input);
+        mInputText = findViewById(R.id.numberpicker_input);
         mInputText.setOnFocusChangeListener(new OnFocusChangeListener() {
             public void onFocusChange(View v, boolean hasFocus) {
                 if (hasFocus) {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 5505f2f..9245134 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1787,7 +1787,7 @@
 
         @Override
         public Action initActionAsync(ViewTree root, ViewGroup rootParent, OnClickHandler handler) {
-            final TextView target = (TextView) root.findViewById(viewId);
+            final TextView target = root.findViewById(viewId);
             if (target == null) return ACTION_NOOP;
 
             TextViewDrawableAction copy = useIcons ?
@@ -3688,12 +3688,12 @@
             createTree();
         }
 
-        public View findViewById(int id) {
+        public <T extends View> T findViewById(int id) {
             if (mChildren == null) {
                 return mRoot.findViewById(id);
             }
             ViewTree tree = findViewTreeById(id);
-            return tree == null ? null : tree.mRoot;
+            return tree == null ? null : (T) tree.mRoot;
         }
 
         public void addChild(ViewTree child) {
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index 7e2cadf..8de17c0 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -136,7 +136,7 @@
 mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
       */
     public void setup() {
-        mTabWidget = (TabWidget) findViewById(com.android.internal.R.id.tabs);
+        mTabWidget = findViewById(com.android.internal.R.id.tabs);
         if (mTabWidget == null) {
             throw new RuntimeException(
                     "Your TabHost must have a TabWidget whose id attribute is 'android.R.id.tabs'");
@@ -171,7 +171,7 @@
             }
         });
 
-        mTabContent = (FrameLayout) findViewById(com.android.internal.R.id.tabcontent);
+        mTabContent = findViewById(com.android.internal.R.id.tabcontent);
         if (mTabContent == null) {
             throw new RuntimeException(
                     "Your TabHost must have a FrameLayout whose id attribute is "
diff --git a/core/java/android/widget/TextInputTimePickerView.java b/core/java/android/widget/TextInputTimePickerView.java
index 0183343..11b7514d 100644
--- a/core/java/android/widget/TextInputTimePickerView.java
+++ b/core/java/android/widget/TextInputTimePickerView.java
@@ -76,12 +76,12 @@
 
         inflate(context, R.layout.time_picker_text_input_material, this);
 
-        mHourEditText = (EditText) findViewById(R.id.input_hour);
-        mMinuteEditText = (EditText) findViewById(R.id.input_minute);
-        mInputSeparatorView = (TextView) findViewById(R.id.input_separator);
-        mErrorLabel = (TextView) findViewById(R.id.label_error);
-        mHourLabel = (TextView) findViewById(R.id.label_hour);
-        mMinuteLabel = (TextView) findViewById(R.id.label_minute);
+        mHourEditText = findViewById(R.id.input_hour);
+        mMinuteEditText = findViewById(R.id.input_minute);
+        mInputSeparatorView = findViewById(R.id.input_separator);
+        mErrorLabel = findViewById(R.id.label_error);
+        mHourLabel = findViewById(R.id.label_hour);
+        mMinuteLabel = findViewById(R.id.label_minute);
 
         mHourEditText.addTextChangedListener(new TextWatcher() {
             @Override
@@ -109,7 +109,7 @@
             }
         });
 
-        mAmPmSpinner = (Spinner) findViewById(R.id.am_pm_spinner);
+        mAmPmSpinner = findViewById(R.id.am_pm_spinner);
         final String[] amPmStrings = TimePicker.getAmPmStrings(context);
         ArrayAdapter<CharSequence> adapter =
                 new ArrayAdapter<CharSequence>(context, R.layout.simple_spinner_dropdown_item);
diff --git a/core/java/android/widget/TwoLineListItem.java b/core/java/android/widget/TwoLineListItem.java
index 0445ebd..553b86e 100644
--- a/core/java/android/widget/TwoLineListItem.java
+++ b/core/java/android/widget/TwoLineListItem.java
@@ -70,8 +70,8 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
 
-        mText1 = (TextView) findViewById(com.android.internal.R.id.text1);
-        mText2 = (TextView) findViewById(com.android.internal.R.id.text2);
+        mText1 = findViewById(com.android.internal.R.id.text1);
+        mText2 = findViewById(com.android.internal.R.id.text2);
     }
 
     /**
diff --git a/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java b/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java
index ee5d339..032c775 100644
--- a/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java
+++ b/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java
@@ -59,13 +59,13 @@
         String component = Settings.Secure.getString(getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT);
         if (TextUtils.isEmpty(component)) {
-            TextView prompt = (TextView) findViewById(R.id.accessibility_button_prompt);
+            TextView prompt = findViewById(R.id.accessibility_button_prompt);
             prompt.setVisibility(View.VISIBLE);
         }
 
         mMagnificationTarget = new AccessibilityButtonTarget(this, MAGNIFICATION_COMPONENT_ID,
                 R.string.accessibility_magnification_chooser_text,
-                R.drawable.resolver_icon_placeholder);
+                R.drawable.ic_accessibility_magnification);
 
         mTargets = getServiceAccessibilityButtonTargets(this);
         if (Settings.Secure.getInt(getContentResolver(),
@@ -78,7 +78,7 @@
             finish();
         }
 
-        GridView gridview = (GridView) findViewById(R.id.accessibility_button_chooser_grid);
+        GridView gridview = findViewById(R.id.accessibility_button_chooser_grid);
         gridview.setAdapter(new TargetAdapter());
         gridview.setOnItemClickListener((parent, view, position, id) -> {
             onTargetSelected(mTargets.get(position));
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 622b708..b596678 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -287,7 +287,7 @@
             return;
         }
 
-        final ResolverDrawerLayout rdl = (ResolverDrawerLayout) findViewById(R.id.contentPanel);
+        final ResolverDrawerLayout rdl = findViewById(R.id.contentPanel);
         if (rdl != null) {
             rdl.setOnDismissedListener(new ResolverDrawerLayout.OnDismissedListener() {
                 @Override
@@ -922,10 +922,10 @@
         }
 
 
-        mAdapterView = (AbsListView) findViewById(R.id.resolver_list);
+        mAdapterView = findViewById(R.id.resolver_list);
 
         if (count == 0 && mAdapter.mPlaceholderCount == 0) {
-            final TextView emptyView = (TextView) findViewById(R.id.empty);
+            final TextView emptyView = findViewById(R.id.empty);
             emptyView.setVisibility(View.VISIBLE);
             mAdapterView.setVisibility(View.GONE);
         } else {
@@ -959,7 +959,7 @@
 
     public void setTitleAndIcon() {
         if (mAdapter.getCount() == 0 && mAdapter.mPlaceholderCount == 0) {
-            final TextView titleView = (TextView) findViewById(R.id.title);
+            final TextView titleView = findViewById(R.id.title);
             if (titleView != null) {
                 titleView.setVisibility(View.GONE);
             }
@@ -970,14 +970,14 @@
                 : getTitleForAction(getTargetIntent().getAction(), mDefaultTitleResId);
 
         if (!TextUtils.isEmpty(title)) {
-            final TextView titleView = (TextView) findViewById(R.id.title);
+            final TextView titleView = findViewById(R.id.title);
             if (titleView != null) {
                 titleView.setText(title);
             }
             setTitle(title);
 
             // Try to initialize the title icon if we have a view for it and a title to match
-            final ImageView titleIcon = (ImageView) findViewById(R.id.title_icon);
+            final ImageView titleIcon = findViewById(R.id.title_icon);
             if (titleIcon != null) {
                 ApplicationInfo ai = null;
                 try {
@@ -994,7 +994,7 @@
             }
         }
 
-        final ImageView iconView = (ImageView) findViewById(R.id.icon);
+        final ImageView iconView = findViewById(R.id.icon);
         final DisplayResolveInfo iconInfo = mAdapter.getFilteredItem();
         if (iconView != null && iconInfo != null) {
             new LoadIconIntoViewTask(iconInfo, iconView).execute();
@@ -1003,7 +1003,7 @@
 
     public void resetAlwaysOrOnceButtonBar() {
         if (mSupportsAlwaysUseOption) {
-            final ViewGroup buttonLayout = (ViewGroup) findViewById(R.id.button_bar);
+            final ViewGroup buttonLayout = findViewById(R.id.button_bar);
             if (buttonLayout != null) {
                 buttonLayout.setVisibility(View.VISIBLE);
                 mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always);
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 44fa99d..142effb 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -186,8 +186,8 @@
 
     private static void preloadOpenGL() {
         String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
-        if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) ||
-                driverPackageName == null || driverPackageName.isEmpty()) {
+        if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) &&
+                (driverPackageName == null || driverPackageName.isEmpty())) {
             EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
         }
     }
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index c4540f5..baf6db9 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1688,7 +1688,7 @@
                     }
                 };
             } else {
-                ViewStub stub = (ViewStub) findViewById(R.id.action_mode_bar_stub);
+                ViewStub stub = findViewById(R.id.action_mode_bar_stub);
                 if (stub != null) {
                     mPrimaryActionModeView = (ActionBarContextView) stub.inflate();
                     mPrimaryActionModePopup = null;
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 7b966de..243916b 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -1593,7 +1593,7 @@
         if (featureId == FEATURE_PROGRESS || featureId == FEATURE_INDETERMINATE_PROGRESS) {
             updateProgressBars(value);
         } else if (featureId == FEATURE_CUSTOM_TITLE) {
-            FrameLayout titleContainer = (FrameLayout) findViewById(R.id.title_container);
+            FrameLayout titleContainer = findViewById(R.id.title_container);
             if (titleContainer != null) {
                 mLayoutInflater.inflate(value, titleContainer);
             }
@@ -2690,7 +2690,7 @@
                     invalidatePanelMenu(FEATURE_ACTION_BAR);
                 }
             } else {
-                mTitleView = (TextView) findViewById(R.id.title);
+                mTitleView = findViewById(R.id.title);
                 if (mTitleView != null) {
                     if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) {
                         final View titleContainer = findViewById(R.id.title_container);
@@ -2967,7 +2967,7 @@
         if (mContentParent == null && shouldInstallDecor) {
             installDecor();
         }
-        mCircularProgressBar = (ProgressBar) findViewById(R.id.progress_circular);
+        mCircularProgressBar = findViewById(R.id.progress_circular);
         if (mCircularProgressBar != null) {
             mCircularProgressBar.setVisibility(View.INVISIBLE);
         }
@@ -2981,7 +2981,7 @@
         if (mContentParent == null && shouldInstallDecor) {
             installDecor();
         }
-        mHorizontalProgressBar = (ProgressBar) findViewById(R.id.progress_horizontal);
+        mHorizontalProgressBar = findViewById(R.id.progress_horizontal);
         if (mHorizontalProgressBar != null) {
             mHorizontalProgressBar.setVisibility(View.INVISIBLE);
         }
diff --git a/core/java/com/android/internal/util/BitUtils.java b/core/java/com/android/internal/util/BitUtils.java
index a208ccb..e349f3d 100644
--- a/core/java/com/android/internal/util/BitUtils.java
+++ b/core/java/com/android/internal/util/BitUtils.java
@@ -55,4 +55,25 @@
                 && maskedEquals(a.getMostSignificantBits(), b.getMostSignificantBits(),
                     mask.getMostSignificantBits());
     }
+
+    public static int[] unpackBits(long val) {
+        int size = Long.bitCount(val);
+        int[] result = new int[size];
+        int index = 0;
+        int bitPos = 0;
+        while (val > 0) {
+            if ((val & 1) == 1) result[index++] = bitPos;
+            val = val >> 1;
+            bitPos++;
+        }
+        return result;
+    }
+
+    public static long packBits(int[] bits) {
+        long packed = 0;
+        for (int b : bits) {
+            packed |= (1 << b);
+        }
+        return packed;
+    }
 }
diff --git a/core/java/com/android/internal/util/DumpUtils.java b/core/java/com/android/internal/util/DumpUtils.java
index 4659d3c..ce89501 100644
--- a/core/java/com/android/internal/util/DumpUtils.java
+++ b/core/java/com/android/internal/util/DumpUtils.java
@@ -121,12 +121,15 @@
         final String[] pkgs = context.getPackageManager().getPackagesForUid(uid);
         if (pkgs != null) {
             for (String pkg : pkgs) {
-                if (appOps.checkOpNoThrow(AppOpsManager.OP_GET_USAGE_STATS, uid,
-                        pkg) == AppOpsManager.MODE_ALLOWED) {
-                    appOps.noteOp(AppOpsManager.OP_GET_USAGE_STATS, uid, pkg);
-                    if (DEBUG) Slog.v(TAG, "Found package " + pkg + " with "
-                                + "android:get_usage_stats access");
-                    return true;
+                switch (appOps.checkOpNoThrow(AppOpsManager.OP_GET_USAGE_STATS, uid, pkg)) {
+                    case AppOpsManager.MODE_ALLOWED:
+                        if (DEBUG) Slog.v(TAG, "Found package " + pkg + " with "
+                                + "android:get_usage_stats allowed");
+                        return true;
+                    case AppOpsManager.MODE_DEFAULT:
+                        if (DEBUG) Slog.v(TAG, "Found package " + pkg + " with "
+                                + "android:get_usage_stats default");
+                        return true;
                 }
             }
         }
diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java
index 919cf99..83a2838 100644
--- a/core/java/com/android/internal/view/menu/ListMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java
@@ -89,14 +89,14 @@
         
         setBackgroundDrawable(mBackground);
         
-        mTitleView = (TextView) findViewById(com.android.internal.R.id.title);
+        mTitleView = findViewById(com.android.internal.R.id.title);
         if (mTextAppearance != -1) {
             mTitleView.setTextAppearance(mTextAppearanceContext,
                                          mTextAppearance);
         }
         
-        mShortcutView = (TextView) findViewById(com.android.internal.R.id.shortcut);
-        mSubMenuArrowView = (ImageView) findViewById(com.android.internal.R.id.submenuarrow);
+        mShortcutView = findViewById(com.android.internal.R.id.shortcut);
+        mSubMenuArrowView = findViewById(com.android.internal.R.id.submenuarrow);
         if (mSubMenuArrowView != null) {
             mSubMenuArrowView.setImageDrawable(mSubMenuArrow);
         }
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index c3a7460..65cd4fa2 100644
--- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
+++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
@@ -569,10 +569,10 @@
     void pullChildren() {
         if (mContent == null) {
             mContent = findViewById(com.android.internal.R.id.content);
-            mActionBarTop = (ActionBarContainer) findViewById(
+            mActionBarTop = findViewById(
                     com.android.internal.R.id.action_bar_container);
             mDecorToolbar = getDecorToolbar(findViewById(com.android.internal.R.id.action_bar));
-            mActionBarBottom = (ActionBarContainer) findViewById(
+            mActionBarBottom = findViewById(
                     com.android.internal.R.id.split_action_bar);
         }
     }
@@ -707,7 +707,7 @@
                 mDecorToolbar.setSplitToolbar(splitActionBar);
                 mDecorToolbar.setSplitWhenNarrow(splitWhenNarrow);
 
-                final ActionBarContextView cab = (ActionBarContextView) findViewById(
+                final ActionBarContextView cab = findViewById(
                         com.android.internal.R.id.action_context_bar);
                 cab.setSplitView(mActionBarBottom);
                 cab.setSplitToolbar(splitActionBar);
diff --git a/core/java/com/android/internal/widget/MediaNotificationView.java b/core/java/com/android/internal/widget/MediaNotificationView.java
index f63afad..afb2a5e 100644
--- a/core/java/com/android/internal/widget/MediaNotificationView.java
+++ b/core/java/com/android/internal/widget/MediaNotificationView.java
@@ -152,7 +152,7 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mRightIcon = (ImageView) findViewById(com.android.internal.R.id.right_icon);
+        mRightIcon = findViewById(com.android.internal.R.id.right_icon);
         mActions = findViewById(com.android.internal.R.id.media_actions);
         mHeader = findViewById(com.android.internal.R.id.notification_header);
         mMainColumn = findViewById(com.android.internal.R.id.notification_main_column);
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 33fabfc..96285cd 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -96,6 +96,7 @@
     android_os_SystemProperties.cpp \
     android_os_Trace.cpp \
     android_os_UEventObserver.cpp \
+    android_os_VintfObject.cpp \
     android_net_LocalSocketImpl.cpp \
     android_net_NetUtils.cpp \
     android_net_TrafficStats.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index e237ce9..8ca4794 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -159,6 +159,7 @@
 extern int register_android_os_MessageQueue(JNIEnv* env);
 extern int register_android_os_Parcel(JNIEnv* env);
 extern int register_android_os_SELinux(JNIEnv* env);
+extern int register_android_os_VintfObject(JNIEnv *env);
 extern int register_android_os_seccomp(JNIEnv* env);
 extern int register_android_os_SystemProperties(JNIEnv *env);
 extern int register_android_os_SystemClock(JNIEnv* env);
@@ -1302,6 +1303,7 @@
     REG_JNI(register_android_os_HwBlob),
     REG_JNI(register_android_os_HwParcel),
     REG_JNI(register_android_os_HwRemoteBinder),
+    REG_JNI(register_android_os_VintfObject),
     REG_JNI(register_android_nio_utils),
     REG_JNI(register_android_graphics_Canvas),
     REG_JNI(register_android_graphics_Graphics),
diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp
index 95d43c6..86c97a1 100644
--- a/core/jni/android/graphics/Typeface.cpp
+++ b/core/jni/android/graphics/Typeface.cpp
@@ -87,7 +87,8 @@
     return face->fBaseWeight;
 }
 
-static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray) {
+static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray,
+        int weight, int italic) {
     ScopedLongArrayRO families(env, familyArray);
     std::vector<std::shared_ptr<minikin::FontFamily>> familyVec;
     familyVec.reserve(families.size());
@@ -95,7 +96,8 @@
         FontFamilyWrapper* family = reinterpret_cast<FontFamilyWrapper*>(families[i]);
         familyVec.emplace_back(family->family);
     }
-    return reinterpret_cast<jlong>(Typeface::createFromFamilies(std::move(familyVec)));
+    return reinterpret_cast<jlong>(
+            Typeface::createFromFamilies(std::move(familyVec), weight, italic));
 }
 
 static void Typeface_setDefault(JNIEnv *env, jobject, jlong faceHandle) {
@@ -133,7 +135,7 @@
     { "nativeUnref",              "(J)V",  (void*)Typeface_unref },
     { "nativeGetStyle",           "(J)I",  (void*)Typeface_getStyle },
     { "nativeGetBaseWeight",      "(J)I",  (void*)Typeface_getBaseWeight },
-    { "nativeCreateFromArray",    "([J)J",
+    { "nativeCreateFromArray",    "([JII)J",
                                            (void*)Typeface_createFromArray },
     { "nativeSetDefault",         "(J)V",   (void*)Typeface_setDefault },
     { "nativeGetSupportedAxes",   "(J)[I",  (void*)Typeface_getSupportedAxes },
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
new file mode 100644
index 0000000..1883ecb
--- /dev/null
+++ b/core/jni/android_os_VintfObject.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "VintfObject"
+//#define LOG_NDEBUG 0
+
+#include <JNIHelp.h>
+#include <vintf/VintfObject.h>
+#include <vintf/parse_xml.h>
+
+#include "core_jni_helpers.h"
+
+namespace android {
+
+using vintf::HalManifest;
+using vintf::RuntimeInfo;
+using vintf::VintfObject;
+using vintf::gHalManifestConverter;
+
+static jstring android_os_VintfObject_getDeviceManifest(JNIEnv* env, jclass clazz)
+{
+    const HalManifest *manifest = VintfObject::GetDeviceHalManifest();
+    if (manifest == nullptr) {
+        return nullptr;
+    }
+    std::string xml = gHalManifestConverter(*manifest);
+    return env->NewStringUTF(xml.c_str());
+}
+
+static jstring android_os_VintfObject_getFrameworkManifest(JNIEnv* env, jclass clazz)
+{
+    const HalManifest *manifest = VintfObject::GetFrameworkHalManifest();
+    if (manifest == nullptr) {
+        return nullptr;
+    }
+    std::string xml = gHalManifestConverter(*manifest);
+    return env->NewStringUTF(xml.c_str());
+}
+
+static jint android_os_VintfObject_verify(JNIEnv *env, jclass clazz, jobjectArray packageInfo) {
+    size_t count = env->GetArrayLength(packageInfo);
+    std::vector<std::string> cPackageInfo{count};
+    for (size_t i = 0; i < count; ++i) {
+        jstring element = (jstring)env->GetObjectArrayElement(packageInfo, i);
+        const char *cString = env->GetStringUTFChars(element, NULL /* isCopy */);
+        cPackageInfo[i] = cString;
+        env->ReleaseStringUTFChars(element, cString);
+    }
+    int32_t status = VintfObject::CheckCompatibility(cPackageInfo, false /* mount */);
+    return status;
+}
+
+// ----------------------------------------------------------------------------
+
+static const JNINativeMethod gVintfObjectMethods[] = {
+    {"getDeviceManifest",    "()Ljava/lang/String;",   (void*)android_os_VintfObject_getDeviceManifest},
+    {"getFrameworkManifest", "()Ljava/lang/String;",   (void*)android_os_VintfObject_getFrameworkManifest},
+    {"verify",               "([Ljava/lang/String;)I", (void*)android_os_VintfObject_verify},
+};
+
+const char* const kVintfObjectPathName = "android/os/VintfObject";
+
+int register_android_os_VintfObject(JNIEnv* env)
+{
+    return RegisterMethodsOrDie(env, kVintfObjectPathName, gVintfObjectMethods,
+            NELEM(gVintfObjectMethods));
+}
+
+};
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7fc1f68..000c8c4 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -492,7 +492,9 @@
     <protected-broadcast android:name="android.intent.action.ACTION_RADIO_OFF" />
 
     <protected-broadcast android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" />
+    <protected-broadcast android:name="android.accounts.action.ACCOUNT_REMOVED" />
     <protected-broadcast android:name="android.accounts.action.VISIBLE_ACCOUNTS_CHANGED" />
+
     <protected-broadcast android:name="com.android.sync.SYNC_CONN_STATUS_CHANGED" />
 
     <protected-broadcast android:name="com.android.phone.SIP_INCOMING_CALL" />
@@ -1524,6 +1526,16 @@
     <permission android:name="android.permission.DVB_DEVICE"
         android:protectionLevel="signature|privileged" />
 
+    <!-- @SystemApi Allows reading and enabling/disabling the OEM unlock allowed by carrier state
+         @hide <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE"
+        android:protectionLevel="signature|privileged" />
+
+    <!-- @SystemApi Allows reading and enabling/disabling the OEM unlock allowed by user state
+         @hide <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.MANAGE_USER_OEM_UNLOCK_STATE"
+        android:protectionLevel="signature|privileged" />
+
     <!-- @SystemApi Allows reading the OEM unlock state
          @hide <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.READ_OEM_UNLOCK_STATE"
diff --git a/core/res/res/drawable-hdpi/ic_accessibility_magnification.png b/core/res/res/drawable-hdpi/ic_accessibility_magnification.png
new file mode 100755
index 0000000..a91bc6e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_accessibility_magnification.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_accessibility_magnification.png b/core/res/res/drawable-mdpi/ic_accessibility_magnification.png
new file mode 100755
index 0000000..9ec5107
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_accessibility_magnification.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_accessibility_magnification.png b/core/res/res/drawable-xhdpi/ic_accessibility_magnification.png
new file mode 100755
index 0000000..0b3a32e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_accessibility_magnification.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_accessibility_magnification.png b/core/res/res/drawable-xxhdpi/ic_accessibility_magnification.png
new file mode 100755
index 0000000..3eeb1c9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_accessibility_magnification.png
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/ic_accessibility_magnification.png b/core/res/res/drawable-xxxhdpi/ic_accessibility_magnification.png
new file mode 100755
index 0000000..7d37612
--- /dev/null
+++ b/core/res/res/drawable-xxxhdpi/ic_accessibility_magnification.png
Binary files differ
diff --git a/core/res/res/layout/autofill_dataset_picker.xml b/core/res/res/layout/autofill_dataset_picker.xml
index 5a835b7..528efca 100644
--- a/core/res/res/layout/autofill_dataset_picker.xml
+++ b/core/res/res/layout/autofill_dataset_picker.xml
@@ -15,6 +15,7 @@
 -->
 
 <FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/autofill_dataset_picker"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     style="@style/AutofillDatasetPicker">
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 5ede1c9..67f6d19 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -430,10 +430,9 @@
             <flag name="adjustNothing" value="0x30" />
         </attr>
 
-        <!-- Flag allowing you to disable the preview animation for a window.
-             The default value is false; if set to true, the system can never
-             use the window's theme to show a preview of it before your
-             actual instance is shown to the user. -->
+        <!-- Flag allowing you to disable the splash screen for a window. The default value is
+             false; if set to true, the system can never use the window's theme to show a splash
+             screen before your actual instance is shown to the user. -->
         <attr name="windowDisablePreview" format="boolean" />
 
         <!-- Flag indicating that this window should not be displayed at all.
@@ -2049,6 +2048,17 @@
              Corresponds to setting {@link android.view.View#SYSTEM_UI_FLAG_LIGHT_STATUS_BAR} on
              the decor view. -->
         <attr name="windowLightStatusBar" format="boolean" />
+
+        <!-- Reference to a drawable to be used as the splash screen content of the window. This
+             drawable will be placed on top of the {@link android.R.attr#windowBackground} with its
+             bounds inset by the system bars. If the drawable should not be inset by the system
+             bars, use a fullscreen theme.
+             <p>
+             Note that even if no splashscreen content is set on the theme, the system may still
+             show a splash screen using the other attributes on the theme, like the
+             {@link android.R.attr#windowBackground}.
+             -->
+        <attr name="windowSplashscreenContent" format="reference" />
     </declare-styleable>
 
     <!-- The set of attributes that describe a AlertDialog's theme. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 31ece50..d6ed178 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2816,6 +2816,7 @@
         <public name="iconSpaceReserved"/>
         <public name="defaultFocusHighlightEnabled" />
         <public name="persistentFeature"/>
+        <public name="windowSplashscreenContent" />
     </public-group>
 
     <public-group type="style" first-id="0x010302e0">
@@ -2835,7 +2836,6 @@
         <public name="paste_as_plain_text" />
     </public-group>
 
-
   <!-- ===============================================================
        DO NOT ADD UN-GROUPED ITEMS HERE
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 44a4af7..603e376 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2857,6 +2857,7 @@
   <java-symbol type="id" name="accessibility_button_target_icon" />
   <java-symbol type="id" name="accessibility_button_target_label" />
   <java-symbol type="string" name="accessibility_magnification_chooser_text" />
+  <java-symbol type="drawable" name="ic_accessibility_magnification" />
 
   <!-- com.android.internal.widget.RecyclerView -->
   <java-symbol type="id" name="item_touch_helper_previous_elevation"/>
@@ -2867,6 +2868,7 @@
   <!-- com.android.server.autofill -->
   <java-symbol type="layout" name="autofill_save"/>
   <java-symbol type="layout" name="autofill_dataset_picker"/>
+  <java-symbol type="id" name="autofill_dataset_picker"/>
   <java-symbol type="id" name="autofill_dataset_list"/>
   <java-symbol type="id" name="autofill" />
   <java-symbol type="id" name="autofill_save_title" />
diff --git a/core/tests/coretests/src/android/animation/BasicAnimatorActivity.java b/core/tests/coretests/src/android/animation/BasicAnimatorActivity.java
index 6bcf8fc..0e1e6ac 100644
--- a/core/tests/coretests/src/android/animation/BasicAnimatorActivity.java
+++ b/core/tests/coretests/src/android/animation/BasicAnimatorActivity.java
@@ -27,6 +27,6 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.animator_basic);
-        mAnimatingButton = (Button) findViewById(R.id.animatingButton);
+        mAnimatingButton = findViewById(R.id.animatingButton);
     }
 }
diff --git a/core/tests/coretests/src/android/os/BrightnessLimit.java b/core/tests/coretests/src/android/os/BrightnessLimit.java
index f4a5e09..43cd373 100644
--- a/core/tests/coretests/src/android/os/BrightnessLimit.java
+++ b/core/tests/coretests/src/android/os/BrightnessLimit.java
@@ -40,7 +40,7 @@
         
         setContentView(R.layout.brightness_limit);
         
-        Button b = (Button) findViewById(R.id.go);
+        Button b = findViewById(R.id.go);
         b.setOnClickListener(this);
     }
 
diff --git a/core/tests/coretests/src/android/os/VintfObjectTest.java b/core/tests/coretests/src/android/os/VintfObjectTest.java
new file mode 100644
index 0000000..aaaf55c
--- /dev/null
+++ b/core/tests/coretests/src/android/os/VintfObjectTest.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 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;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+public class VintfObjectTest extends TestCase {
+    public void testReport() {
+        String[] xmls = VintfObject.report();
+        assertTrue(xmls.length > 0);
+        // From /system/manifest.xml
+        assertTrue(String.join("", xmls).contains(
+                "<manifest version=\"1.0\" type=\"framework\">"));
+    }
+}
diff --git a/core/tests/coretests/src/android/view/Disabled.java b/core/tests/coretests/src/android/view/Disabled.java
index fa92107..d3c7470 100644
--- a/core/tests/coretests/src/android/view/Disabled.java
+++ b/core/tests/coretests/src/android/view/Disabled.java
@@ -34,16 +34,16 @@
         setContentView(R.layout.disabled);
 
         // Find our buttons
-        Button disabledButton = (Button) findViewById(R.id.disabledButton);
+        Button disabledButton = findViewById(R.id.disabledButton);
         disabledButton.setEnabled(false);
         
         // Find our buttons
-        Button disabledButtonA = (Button) findViewById(R.id.disabledButtonA);
+        Button disabledButtonA = findViewById(R.id.disabledButtonA);
         disabledButtonA.setOnClickListener(this);
     }
 
     public void onClick(View v) {
-        Button disabledButtonB = (Button) findViewById(R.id.disabledButtonB);
+        Button disabledButtonB = findViewById(R.id.disabledButtonB);
         disabledButtonB.setEnabled(!disabledButtonB.isEnabled());
     }
 }
diff --git a/core/tests/coretests/src/android/view/DrawableBgMinSize.java b/core/tests/coretests/src/android/view/DrawableBgMinSize.java
index a75b23a..58bfb8a 100644
--- a/core/tests/coretests/src/android/view/DrawableBgMinSize.java
+++ b/core/tests/coretests/src/android/view/DrawableBgMinSize.java
@@ -58,14 +58,14 @@
         mBackgroundDrawable = getResources().getDrawable(R.drawable.drawable_background);
         mBigBackgroundDrawable = getResources().getDrawable(R.drawable.big_drawable_background);
  
-        mChangeBackgroundsButton = (Button) findViewById(R.id.change_backgrounds);
+        mChangeBackgroundsButton = findViewById(R.id.change_backgrounds);
         mChangeBackgroundsButton.setOnClickListener(this);
         
-        mTextView = (TextView) findViewById(R.id.text_view);
-        mLinearLayout = (LinearLayout) findViewById(R.id.linear_layout);
-        mRelativeLayout = (RelativeLayout) findViewById(R.id.relative_layout);
-        mFrameLayout = (FrameLayout) findViewById(R.id.frame_layout);
-        mAbsoluteLayout = (AbsoluteLayout) findViewById(R.id.absolute_layout);
+        mTextView = findViewById(R.id.text_view);
+        mLinearLayout = findViewById(R.id.linear_layout);
+        mRelativeLayout = findViewById(R.id.relative_layout);
+        mFrameLayout = findViewById(R.id.frame_layout);
+        mAbsoluteLayout = findViewById(R.id.absolute_layout);
 
         changeBackgrounds(mBackgroundDrawable);
     }
diff --git a/core/tests/coretests/src/android/view/PopupWindowVisibility.java b/core/tests/coretests/src/android/view/PopupWindowVisibility.java
index 6e11ede..85ce04f 100644
--- a/core/tests/coretests/src/android/view/PopupWindowVisibility.java
+++ b/core/tests/coretests/src/android/view/PopupWindowVisibility.java
@@ -45,13 +45,13 @@
 
         mFrame = findViewById(R.id.frame);
         
-        mHide = (Button) findViewById(R.id.hide);
+        mHide = findViewById(R.id.hide);
         mHide.setOnClickListener(this);
         
-        mShow = (Button) findViewById(R.id.show);
+        mShow = findViewById(R.id.show);
         mShow.setOnClickListener(this);
         
-        Spinner spinner = (Spinner) findViewById(R.id.spinner);
+        Spinner spinner = findViewById(R.id.spinner);
         ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this,
                 android.R.layout.simple_spinner_item, mStrings);
         spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
@@ -59,7 +59,7 @@
         
         ArrayAdapter<String> autoAdapter = new ArrayAdapter<String>(this,
                 android.R.layout.simple_dropdown_item_1line, COUNTRIES);
-        AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.auto);
+        AutoCompleteTextView textView = findViewById(R.id.auto);
         textView.setAdapter(autoAdapter);
     }
 
diff --git a/core/tests/coretests/src/android/view/PreDrawListener.java b/core/tests/coretests/src/android/view/PreDrawListener.java
index 981c6c0..60bbee4 100644
--- a/core/tests/coretests/src/android/view/PreDrawListener.java
+++ b/core/tests/coretests/src/android/view/PreDrawListener.java
@@ -75,9 +75,9 @@
         super.onCreate(icicle);
         setContentView(R.layout.pre_draw_listener);
 
-        mFrame = (MyLinearLayout) findViewById(R.id.frame);
+        mFrame = findViewById(R.id.frame);
 
-        Button mGoButton = (Button) findViewById(R.id.go);
+        Button mGoButton = findViewById(R.id.go);
         mGoButton.setOnClickListener(this);
     }
 
diff --git a/core/tests/coretests/src/android/view/Visibility.java b/core/tests/coretests/src/android/view/Visibility.java
index 97ff252..031568c 100644
--- a/core/tests/coretests/src/android/view/Visibility.java
+++ b/core/tests/coretests/src/android/view/Visibility.java
@@ -37,9 +37,9 @@
         mVictim = findViewById(R.id.victim);
 
         // Find our buttons
-        Button visibleButton = (Button) findViewById(R.id.vis);
-        Button invisibleButton = (Button) findViewById(R.id.invis);
-        Button goneButton = (Button) findViewById(R.id.gone);
+        Button visibleButton = findViewById(R.id.vis);
+        Button invisibleButton = findViewById(R.id.invis);
+        Button goneButton = findViewById(R.id.gone);
 
         // Wire each button to a click listener
         visibleButton.setOnClickListener(mVisibleListener);
diff --git a/core/tests/coretests/src/android/view/VisibilityCallback.java b/core/tests/coretests/src/android/view/VisibilityCallback.java
index 7290a62..f98a0a8 100644
--- a/core/tests/coretests/src/android/view/VisibilityCallback.java
+++ b/core/tests/coretests/src/android/view/VisibilityCallback.java
@@ -45,9 +45,9 @@
         mVictim = (MonitoredTextView)findViewById(R.id.victim);
 
         // Find our buttons
-        Button visibleButton = (Button) findViewById(R.id.vis);
-        Button invisibleButton = (Button) findViewById(R.id.invis);
-        Button goneButton = (Button) findViewById(R.id.gone);
+        Button visibleButton = findViewById(R.id.vis);
+        Button invisibleButton = findViewById(R.id.invis);
+        Button goneButton = findViewById(R.id.gone);
 
         // Wire each button to a click listener
         visibleButton.setOnClickListener(mVisibleListener);
diff --git a/core/tests/coretests/src/android/widget/AutoCompleteTextViewSimple.java b/core/tests/coretests/src/android/widget/AutoCompleteTextViewSimple.java
index f6cec26..b4e05aa 100644
--- a/core/tests/coretests/src/android/widget/AutoCompleteTextViewSimple.java
+++ b/core/tests/coretests/src/android/widget/AutoCompleteTextViewSimple.java
@@ -47,7 +47,7 @@
 
         // setup layout & views
         setContentView(R.layout.autocompletetextview_simple);
-        mTextView = (AutoCompleteTextView) findViewById(R.id.autocompletetextview1);
+        mTextView = findViewById(R.id.autocompletetextview1);
         
         // configure callbacks used for monitoring
         mTextView.setOnItemClickListener(this);
diff --git a/core/tests/coretests/src/android/widget/focus/DescendantFocusability.java b/core/tests/coretests/src/android/widget/focus/DescendantFocusability.java
index f7d91aa..f6b0520 100644
--- a/core/tests/coretests/src/android/widget/focus/DescendantFocusability.java
+++ b/core/tests/coretests/src/android/widget/focus/DescendantFocusability.java
@@ -40,13 +40,13 @@
 
         setContentView(R.layout.descendant_focusability);
 
-        beforeDescendants = (ViewGroup) findViewById(R.id.beforeDescendants);
+        beforeDescendants = findViewById(R.id.beforeDescendants);
         beforeDescendantsChild = (Button) beforeDescendants.getChildAt(0);
 
-        afterDescendants = (ViewGroup) findViewById(R.id.afterDescendants);
+        afterDescendants = findViewById(R.id.afterDescendants);
         afterDescendantsChild = (Button) afterDescendants.getChildAt(0);
 
-        blocksDescendants = (ViewGroup) findViewById(R.id.blocksDescendants);
+        blocksDescendants = findViewById(R.id.blocksDescendants);
         blocksDescendantsChild = (Button) blocksDescendants.getChildAt(0);
     }
 
diff --git a/core/tests/coretests/src/android/widget/focus/FocusAfterRemoval.java b/core/tests/coretests/src/android/widget/focus/FocusAfterRemoval.java
index 93245e7..b3d5ec5 100644
--- a/core/tests/coretests/src/android/widget/focus/FocusAfterRemoval.java
+++ b/core/tests/coretests/src/android/widget/focus/FocusAfterRemoval.java
@@ -35,10 +35,10 @@
         super.onCreate(icicle);
         setContentView(R.layout.focus_after_removal);
 
-        final LinearLayout left = (LinearLayout) findViewById(R.id.leftLayout);
+        final LinearLayout left = findViewById(R.id.leftLayout);
 
         // top left makes parent layout GONE
-        Button topLeftButton = (Button) findViewById(R.id.topLeftButton);
+        Button topLeftButton = findViewById(R.id.topLeftButton);
         topLeftButton.setOnClickListener(new View.OnClickListener() {
 
             public void onClick(View v) {
@@ -48,7 +48,7 @@
 
         // bottom left makes parent layout INVISIBLE
         // top left makes parent layout GONE
-        Button bottomLeftButton = (Button) findViewById(R.id.bottomLeftButton);
+        Button bottomLeftButton = findViewById(R.id.bottomLeftButton);
         bottomLeftButton.setOnClickListener(new View.OnClickListener() {
 
             public void onClick(View v) {
@@ -57,7 +57,7 @@
         });
 
         // top right button makes top right button GONE
-        final Button topRightButton = (Button) findViewById(R.id.topRightButton);
+        final Button topRightButton = findViewById(R.id.topRightButton);
         topRightButton.setOnClickListener(new View.OnClickListener() {
 
             public void onClick(View v) {
@@ -66,7 +66,7 @@
         });
 
         // bottom right button makes bottom right button INVISIBLE
-        final Button bottomRightButton = (Button) findViewById(R.id.bottomRightButton);
+        final Button bottomRightButton = findViewById(R.id.bottomRightButton);
         bottomRightButton.setOnClickListener(new View.OnClickListener() {
 
             public void onClick(View v) {
diff --git a/core/tests/coretests/src/android/widget/focus/LinearLayoutGrid.java b/core/tests/coretests/src/android/widget/focus/LinearLayoutGrid.java
index db082ec..acd632f 100644
--- a/core/tests/coretests/src/android/widget/focus/LinearLayoutGrid.java
+++ b/core/tests/coretests/src/android/widget/focus/LinearLayoutGrid.java
@@ -33,7 +33,7 @@
     }
 
     public ViewGroup getRootView() {
-        return (ViewGroup) findViewById(R.id.layout);
+        return findViewById(R.id.layout);
     }
 
     public Button getButtonAt(int column, int row) {
@@ -51,11 +51,11 @@
     private LinearLayout getColumn(int column) {
         switch (column) {
             case 0:
-                return (LinearLayout) findViewById(R.id.column1);
+                return findViewById(R.id.column1);
             case 1:
-                return (LinearLayout) findViewById(R.id.column2);
+                return findViewById(R.id.column2);
             case 2:
-                return (LinearLayout) findViewById(R.id.column3);
+                return findViewById(R.id.column3);
             default:
                 throw new IllegalArgumentException("column out of range");
         }
diff --git a/core/tests/coretests/src/android/widget/focus/ListWithFooterViewAndNewLabels.java b/core/tests/coretests/src/android/widget/focus/ListWithFooterViewAndNewLabels.java
index ceb0e95..b908201 100644
--- a/core/tests/coretests/src/android/widget/focus/ListWithFooterViewAndNewLabels.java
+++ b/core/tests/coretests/src/android/widget/focus/ListWithFooterViewAndNewLabels.java
@@ -54,7 +54,7 @@
         setListAdapter(mMyAdapter);
 
         // not in list
-        Button topButton = (Button) findViewById(R.id.button);
+        Button topButton = findViewById(R.id.button);
         topButton.setText("click to add new item");
         topButton.setOnClickListener(new View.OnClickListener() {
 
diff --git a/core/tests/coretests/src/android/widget/focus/RequestFocus.java b/core/tests/coretests/src/android/widget/focus/RequestFocus.java
index 21d762a..4daf0b4 100644
--- a/core/tests/coretests/src/android/widget/focus/RequestFocus.java
+++ b/core/tests/coretests/src/android/widget/focus/RequestFocus.java
@@ -34,7 +34,7 @@
         setContentView(R.layout.focus_after_removal);
 
         // bottom right button starts with the focus.
-        final Button bottomRightButton = (Button) findViewById(R.id.bottomRightButton);
+        final Button bottomRightButton = findViewById(R.id.bottomRightButton);
         bottomRightButton.requestFocus();
         bottomRightButton.setText("I should have focus");
     }
diff --git a/core/tests/coretests/src/android/widget/gridview/GridPadding.java b/core/tests/coretests/src/android/widget/gridview/GridPadding.java
index 0b9e4c5..c3156dc 100644
--- a/core/tests/coretests/src/android/widget/gridview/GridPadding.java
+++ b/core/tests/coretests/src/android/widget/gridview/GridPadding.java
@@ -40,7 +40,7 @@
             values[i] = String.valueOf(i);
         }
 
-        mGridView = (GridView) findViewById(R.id.grid);
+        mGridView = findViewById(R.id.grid);
         mGridView.setAdapter(new ArrayAdapter<String>(this,
                 android.R.layout.simple_list_item_1, values));
     }
diff --git a/core/tests/coretests/src/android/widget/gridview/GridScrollListener.java b/core/tests/coretests/src/android/widget/gridview/GridScrollListener.java
index 4290941..0ce5a31 100644
--- a/core/tests/coretests/src/android/widget/gridview/GridScrollListener.java
+++ b/core/tests/coretests/src/android/widget/gridview/GridScrollListener.java
@@ -46,8 +46,8 @@
             values[i] = ((Integer)i).toString();
         }
         
-        mText = (TextView) findViewById(R.id.text);
-        mGridView = (GridView) findViewById(R.id.grid);
+        mText = findViewById(R.id.text);
+        mGridView = findViewById(R.id.grid);
         mGridView.setAdapter(new ArrayAdapter<String>(this,
                 android.R.layout.simple_list_item_1, values));
 
diff --git a/core/tests/coretests/src/android/widget/gridview/GridThrasher.java b/core/tests/coretests/src/android/widget/gridview/GridThrasher.java
index 0ef5db9..ad89bb6 100644
--- a/core/tests/coretests/src/android/widget/gridview/GridThrasher.java
+++ b/core/tests/coretests/src/android/widget/gridview/GridThrasher.java
@@ -115,9 +115,9 @@
         
         setContentView(R.layout.grid_thrasher);
         
-        mText = (TextView) findViewById(R.id.text);
+        mText = findViewById(R.id.text);
         mAdapter = new ThrashListAdapter(this);
-        GridView g = (GridView) findViewById(R.id.grid);
+        GridView g = findViewById(R.id.grid);
         g.setAdapter(mAdapter);
         
         mHandler.postDelayed(mThrash, 5000);
diff --git a/core/tests/coretests/src/android/widget/layout/linear/LLEditTextThenButton.java b/core/tests/coretests/src/android/widget/layout/linear/LLEditTextThenButton.java
index fe2525f..83331ca 100644
--- a/core/tests/coretests/src/android/widget/layout/linear/LLEditTextThenButton.java
+++ b/core/tests/coretests/src/android/widget/layout/linear/LLEditTextThenButton.java
@@ -36,9 +36,9 @@
 
         setContentView(R.layout.linear_layout_edittext_then_button);
 
-        mLayout = (LinearLayout) findViewById(R.id.layout);
-        mEditText = (EditText) findViewById(R.id.editText);
-        mButton = (Button) findViewById(R.id.button);
+        mLayout = findViewById(R.id.layout);
+        mEditText = findViewById(R.id.editText);
+        mButton = findViewById(R.id.button);
     }
 
     public LinearLayout getLayout() {
diff --git a/core/tests/coretests/src/android/widget/layout/linear/LLOfButtons1.java b/core/tests/coretests/src/android/widget/layout/linear/LLOfButtons1.java
index 3d0144f..ab2f060 100644
--- a/core/tests/coretests/src/android/widget/layout/linear/LLOfButtons1.java
+++ b/core/tests/coretests/src/android/widget/layout/linear/LLOfButtons1.java
@@ -37,7 +37,7 @@
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         setContentView(R.layout.linear_layout_buttons);
-        mFirstButton = (Button) findViewById(R.id.button1);
+        mFirstButton = findViewById(R.id.button1);
 
         mFirstButton.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
@@ -48,7 +48,7 @@
     }
 
     public LinearLayout getLayout() {
-        return (LinearLayout) findViewById(R.id.layout);
+        return findViewById(R.id.layout);
     }
 
     public Button getFirstButton() {
diff --git a/core/tests/coretests/src/android/widget/listview/ListDividers.java b/core/tests/coretests/src/android/widget/listview/ListDividers.java
index 3928c03..9b5a087 100644
--- a/core/tests/coretests/src/android/widget/listview/ListDividers.java
+++ b/core/tests/coretests/src/android/widget/listview/ListDividers.java
@@ -40,7 +40,7 @@
             values[i] = ((Integer) i).toString();
         }
 
-        mListView = (ListView) findViewById(android.R.id.list);
+        mListView = findViewById(android.R.id.list);
         mListView.setAdapter(new ArrayAdapter<String>(this,
                 android.R.layout.simple_list_item_1, values));
 
diff --git a/core/tests/coretests/src/android/widget/listview/ListFilter.java b/core/tests/coretests/src/android/widget/listview/ListFilter.java
index 9e9d1b0..c2ac90e 100644
--- a/core/tests/coretests/src/android/widget/listview/ListFilter.java
+++ b/core/tests/coretests/src/android/widget/listview/ListFilter.java
@@ -46,10 +46,10 @@
         getListView().setTextFilterEnabled(true);
         mFrame = findViewById(R.id.frame);
         
-        mHide = (Button) findViewById(R.id.hide);
+        mHide = findViewById(R.id.hide);
         mHide.setOnClickListener(this);
         
-        mShow = (Button) findViewById(R.id.show);
+        mShow = findViewById(R.id.show);
         mShow.setOnClickListener(this);
     }
     
diff --git a/core/tests/coretests/src/android/widget/listview/ListInHorizontal.java b/core/tests/coretests/src/android/widget/listview/ListInHorizontal.java
index 5f09ff6..a373a5b 100644
--- a/core/tests/coretests/src/android/widget/listview/ListInHorizontal.java
+++ b/core/tests/coretests/src/android/widget/listview/ListInHorizontal.java
@@ -43,7 +43,7 @@
             values[i] = ((Integer) i).toString();
         }
 
-        mListView = (ListView) findViewById(R.id.list);
+        mListView = findViewById(R.id.list);
         mListView.setAdapter(new ArrayAdapter<String>(this,
                 android.R.layout.simple_list_item_1, values));
 
diff --git a/core/tests/coretests/src/android/widget/listview/ListRecyclerProfiling.java b/core/tests/coretests/src/android/widget/listview/ListRecyclerProfiling.java
index d5d7261..76814fb 100644
--- a/core/tests/coretests/src/android/widget/listview/ListRecyclerProfiling.java
+++ b/core/tests/coretests/src/android/widget/listview/ListRecyclerProfiling.java
@@ -38,14 +38,14 @@
             values[i] = ((Integer) i).toString();
         }
 
-        ListView listView = (ListView) findViewById(R.id.list);
+        ListView listView = findViewById(R.id.list);
 
         ViewDebug.startRecyclerTracing("SimpleList", listView);
 
         listView.setAdapter(new ArrayAdapter<String>(this,
                 android.R.layout.simple_list_item_1, values));
 
-        ImageButton stopProfiling = (ImageButton) findViewById(R.id.pause);
+        ImageButton stopProfiling = findViewById(R.id.pause);
         stopProfiling.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
                 ViewDebug.stopRecyclerTracing();
diff --git a/core/tests/coretests/src/android/widget/listview/ListScrollListener.java b/core/tests/coretests/src/android/widget/listview/ListScrollListener.java
index 58a31dc..f349dc6 100644
--- a/core/tests/coretests/src/android/widget/listview/ListScrollListener.java
+++ b/core/tests/coretests/src/android/widget/listview/ListScrollListener.java
@@ -46,7 +46,7 @@
             values[i] = ((Integer)i).toString();
         }
         
-        mText = (TextView) findViewById(R.id.text);
+        mText = findViewById(R.id.text);
         setListAdapter(new ArrayAdapter<String>(this,
                 android.R.layout.simple_list_item_1, values));
 
diff --git a/core/tests/coretests/src/android/widget/listview/ListThrasher.java b/core/tests/coretests/src/android/widget/listview/ListThrasher.java
index ba3d590..0237a95 100644
--- a/core/tests/coretests/src/android/widget/listview/ListThrasher.java
+++ b/core/tests/coretests/src/android/widget/listview/ListThrasher.java
@@ -112,7 +112,7 @@
 
         setContentView(R.layout.list_thrasher);
 
-        mText = (TextView) findViewById(R.id.text);
+        mText = findViewById(R.id.text);
         mAdapter = new ThrashListAdapter(this);
         setListAdapter(mAdapter);
 
diff --git a/core/tests/coretests/src/android/widget/scroll/RequestRectangleVisible.java b/core/tests/coretests/src/android/widget/scroll/RequestRectangleVisible.java
index 9cc8544..afc275f 100644
--- a/core/tests/coretests/src/android/widget/scroll/RequestRectangleVisible.java
+++ b/core/tests/coretests/src/android/widget/scroll/RequestRectangleVisible.java
@@ -43,8 +43,8 @@
         final Rect rect = new Rect();
         final View childToMakeVisible = findViewById(R.id.childToMakeVisible);
 
-        final TextView topBlob = (TextView) findViewById(R.id.topBlob);
-        final TextView bottomBlob = (TextView) findViewById(R.id.bottomBlob);
+        final TextView topBlob = findViewById(R.id.topBlob);
+        final TextView bottomBlob = findViewById(R.id.bottomBlob);
 
         // estimate to get blobs larger than screen
         int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
diff --git a/core/tests/coretests/src/android/widget/scroll/RequestRectangleVisibleWithInternalScroll.java b/core/tests/coretests/src/android/widget/scroll/RequestRectangleVisibleWithInternalScroll.java
index 0e2586d..731b25a 100644
--- a/core/tests/coretests/src/android/widget/scroll/RequestRectangleVisibleWithInternalScroll.java
+++ b/core/tests/coretests/src/android/widget/scroll/RequestRectangleVisibleWithInternalScroll.java
@@ -53,11 +53,11 @@
 
         setContentView(R.layout.scroll_to_rect_with_internal_scroll);
 
-        mTextBlob = (TextView) findViewById(R.id.blob);
+        mTextBlob = findViewById(R.id.blob);
         mTextBlob.scrollBy(0, scrollYofBlob);
 
 
-        mScrollToBlob = (Button) findViewById(R.id.scrollToBlob);
+        mScrollToBlob = findViewById(R.id.scrollToBlob);
         mScrollToBlob.setOnClickListener(new View.OnClickListener() {
 
             public void onClick(View v) {
diff --git a/core/tests/coretests/src/android/widget/scroll/ScrollViewButtonsAndLabels.java b/core/tests/coretests/src/android/widget/scroll/ScrollViewButtonsAndLabels.java
index 4d0892c..027ea0f 100644
--- a/core/tests/coretests/src/android/widget/scroll/ScrollViewButtonsAndLabels.java
+++ b/core/tests/coretests/src/android/widget/scroll/ScrollViewButtonsAndLabels.java
@@ -66,8 +66,8 @@
         int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
         mNumGroups = screenHeight / 30;
 
-        mScrollView = (ScrollView) findViewById(R.id.scrollView);
-        mLinearLayout = (LinearLayout) findViewById(R.id.layout);
+        mScrollView = findViewById(R.id.scrollView);
+        mLinearLayout = findViewById(R.id.layout);
 
         LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
                 LinearLayout.LayoutParams.MATCH_PARENT,
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 3dab1f7..39b0bc7 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -277,6 +277,9 @@
         <font weight="400" style="normal">NotoSansCham-Regular.ttf</font>
         <font weight="700" style="normal">NotoSansCham-Bold.ttf</font>
     </family>
+    <family lang="und-Adlm">
+        <font weight="400" style="normal">NotoSansAdlam-Regular.ttf</font>
+    </family>
     <family lang="und-Avst">
         <font weight="400" style="normal">NotoSansAvestan-Regular.ttf</font>
     </family>
diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java
index 4fc63ea..8f78319 100644
--- a/graphics/java/android/graphics/ColorSpace.java
+++ b/graphics/java/android/graphics/ColorSpace.java
@@ -885,8 +885,32 @@
     }
 
     /**
-     * Returns the name of this color space. The name is never null
-     * and contains always at least 1 character.
+     * <p>Returns the name of this color space. The name is never null
+     * and contains always at least 1 character.</p>
+     *
+     * <p>Color space names are recommended to be unique but are not
+     * guaranteed to be. There is no defined format but the name usually
+     * falls in one of the following categories:</p>
+     * <ul>
+     *     <li>Generic names used to identify color spaces in non-RGB
+     *     color models. For instance: {@link Named#CIE_LAB Generic L*a*b*}.</li>
+     *     <li>Names tied to a particular specification. For instance:
+     *     {@link Named#SRGB sRGB IEC61966-2.1} or
+     *     {@link Named#ACES SMPTE ST 2065-1:2012 ACES}.</li>
+     *     <li>Ad-hoc names, often generated procedurally or by the user
+     *     during a calibration workflow. These names often contain the
+     *     make and model of the display.</li>
+     * </ul>
+     *
+     * <p>Because the format of color space names is not defined, it is
+     * not recommended to programmatically identify a color space by its
+     * name alone. Names can be used as a first approximation.</p>
+     *
+     * <p>It is however perfectly acceptable to display color space names to
+     * users in a UI, or in debuggers and logs. When displaying a color space
+     * name to the user, it is recommended to add extra information to avoid
+     * ambiguities: color model, a representation of the color space's gamut,
+     * white point, etc.</p>
      *
      * @return A non-null String of length >= 1
      */
@@ -2079,8 +2103,11 @@
                     throw new IllegalArgumentException("Parameters cannot be NaN");
                 }
 
-                if (!(d >= 0.0 && d <= 1.0 + Math.ulp(1.0))) {
-                    throw new IllegalArgumentException("Parameter d must be in the range [0..1]");
+                // Next representable float after 1.0
+                // We use doubles here but the representation inside our native code is often floats
+                if (!(d >= 0.0 && d <= 1.0f + Math.ulp(1.0f))) {
+                    throw new IllegalArgumentException("Parameter d must be in the range [0..1], " +
+                            "was " + d);
                 }
 
                 if (d == 0.0 && (a == 0.0 || g == 0.0)) {
@@ -2495,7 +2522,7 @@
                             x -> Math.pow(x < 0.0 ? 0.0 : x, gamma),
                     min, max, id);
             mTransferParameters = gamma == 1.0 ?
-                    new TransferParameters(0.0, 0.0, 1.0, 1.0 + Math.ulp(1.0), gamma) :
+                    new TransferParameters(0.0, 0.0, 1.0, 1.0 + Math.ulp(1.0f), gamma) :
                     new TransferParameters(1.0, 0.0, 0.0, 0.0, gamma);
         }
 
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 2aca782..56f9cc7 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -173,7 +173,8 @@
         if (sFallbackFonts != null) {
             synchronized (sDynamicTypefaceCache) {
                 final String key = Builder.createAssetUid(
-                        mgr, path, 0 /* ttcIndex */, null /* axes */);
+                        mgr, path, 0 /* ttcIndex */, null /* axes */,
+                        RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */);
                 Typeface typeface = sDynamicTypefaceCache.get(key);
                 if (typeface != null) return typeface;
 
@@ -186,7 +187,8 @@
                         return null;
                     }
                     FontFamily[] families = {fontFamily};
-                    typeface = createFromFamiliesWithDefault(families);
+                    typeface = createFromFamiliesWithDefault(families,
+                            RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
                     sDynamicTypefaceCache.put(key, typeface);
                     return typeface;
                 }
@@ -251,10 +253,12 @@
             fontFamily.allowUnsupportedFont();
             fontFamily.freeze();
             FontFamily[] familyChain = { fontFamily };
-            typeface = createFromFamiliesWithDefault(familyChain);
+            typeface = createFromFamiliesWithDefault(familyChain,
+                    RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
             synchronized (sDynamicTypefaceCache) {
                 final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */,
-                        null /* axes */);
+                        null /* axes */, RESOLVE_BY_FONT_TABLE /* weight */,
+                        RESOLVE_BY_FONT_TABLE /* italic */);
                 sDynamicTypefaceCache.put(key, typeface);
             }
             return typeface;
@@ -268,7 +272,8 @@
      */
     public static Typeface findFromCache(AssetManager mgr, String path) {
         synchronized (sDynamicTypefaceCache) {
-            final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */, null /* axes */);
+            final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */, null /* axes */,
+                    RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */);
             Typeface typeface = sDynamicTypefaceCache.get(key);
             if (typeface != null) {
                 return typeface;
@@ -406,7 +411,9 @@
                     FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR);
             return;
         }
-        Typeface typeface = Typeface.createFromFamiliesWithDefault(new FontFamily[] { fontFamily });
+        Typeface typeface = Typeface.createFromFamiliesWithDefault(
+                new FontFamily[] { fontFamily },
+                RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
         synchronized (sDynamicTypefaceCache) {
             String key = createProviderUid(request.getProviderAuthority(), request.getQuery());
             sDynamicTypefaceCache.put(key, typeface);
@@ -715,7 +722,7 @@
          * @return Unique id for a given AssetManager and asset path.
          */
         private static String createAssetUid(final AssetManager mgr, String path, int ttcIndex,
-                @Nullable FontVariationAxis[] axes) {
+                @Nullable FontVariationAxis[] axes, int weight, int italic) {
             final SparseArray<String> pkgs = mgr.getAssignedPackageIdentifiers();
             final StringBuilder builder = new StringBuilder();
             final int size = pkgs.size();
@@ -727,6 +734,10 @@
             builder.append("-");
             builder.append(Integer.toString(ttcIndex));
             builder.append("-");
+            builder.append(Integer.toString(weight));
+            builder.append("-");
+            builder.append(Integer.toString(italic));
+            builder.append("-");
             if (axes != null) {
                 for (FontVariationAxis axis : axes) {
                     builder.append(axis.getTag());
@@ -791,7 +802,7 @@
          * @return Newly created Typeface. May return null if some parameters are invalid.
          */
         public Typeface build() {
-            if (mFd != null) {  // set source by setSourceFromFile(FileDescriptor)
+            if (mFd != null) {  // Builder is created with file descriptor.
                 try (FileInputStream fis = new FileInputStream(mFd)) {
                     FileChannel channel = fis.getChannel();
                     long size = channel.size();
@@ -806,12 +817,13 @@
                         return resolveFallbackTypeface();
                     }
                     FontFamily[] families = { fontFamily };
-                    return createFromFamiliesWithDefault(families);
+                    return createFromFamiliesWithDefault(families, mWeight, mItalic);
                 } catch (IOException e) {
                     return resolveFallbackTypeface();
                 }
-            } else if (mAssetManager != null) {  // set source by setSourceFromAsset()
-                final String key = createAssetUid(mAssetManager, mPath, mTtcIndex, mAxes);
+            } else if (mAssetManager != null) {  // Builder is created with asset manager.
+                final String key = createAssetUid(
+                        mAssetManager, mPath, mTtcIndex, mAxes, mWeight, mItalic);
                 synchronized (sLock) {
                     Typeface typeface = sDynamicTypefaceCache.get(key);
                     if (typeface != null) return typeface;
@@ -825,11 +837,11 @@
                         return resolveFallbackTypeface();
                     }
                     FontFamily[] families = { fontFamily };
-                    typeface = createFromFamiliesWithDefault(families);
+                    typeface = createFromFamiliesWithDefault(families, mWeight, mItalic);
                     sDynamicTypefaceCache.put(key, typeface);
                     return typeface;
                 }
-            } else if (mPath != null) {  // set source by setSourceFromFile(File)
+            } else if (mPath != null) {  // Builder is created with file path.
                 final FontFamily fontFamily = new FontFamily();
                 if (!fontFamily.addFont(mPath, mTtcIndex, mAxes, mWeight, mItalic)) {
                     fontFamily.abortCreation();
@@ -839,7 +851,7 @@
                     return resolveFallbackTypeface();
                 }
                 FontFamily[] families = { fontFamily };
-                return createFromFamiliesWithDefault(families);
+                return createFromFamiliesWithDefault(families, mWeight, mItalic);
             } else if (mFonts != null) {
                 final FontFamily fontFamily = new FontFamily();
                 boolean atLeastOneFont = false;
@@ -865,7 +877,7 @@
                 }
                 fontFamily.freeze();
                 FontFamily[] families = { fontFamily };
-                return createFromFamiliesWithDefault(families);
+                return createFromFamiliesWithDefault(families, mWeight, mItalic);
             }
 
             // Must not reach here.
@@ -969,7 +981,7 @@
                 if (typeface != null) return typeface;
 
                 final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */,
-                        null /* axes */);
+                        null /* axes */, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
                 typeface = sDynamicTypefaceCache.get(key);
                 if (typeface != null) return typeface;
 
@@ -984,7 +996,8 @@
                     fontFamily.allowUnsupportedFont();
                     fontFamily.freeze();
                     final FontFamily[] families = { fontFamily };
-                    typeface = createFromFamiliesWithDefault(families);
+                    typeface = createFromFamiliesWithDefault(families, RESOLVE_BY_FONT_TABLE,
+                            RESOLVE_BY_FONT_TABLE);
                     sDynamicTypefaceCache.put(key, typeface);
                     return typeface;
                 } else {
@@ -1037,7 +1050,8 @@
                 fontFamily.allowUnsupportedFont();
                 fontFamily.freeze();
                 FontFamily[] families = { fontFamily };
-                return createFromFamiliesWithDefault(families);
+                return createFromFamiliesWithDefault(families, RESOLVE_BY_FONT_TABLE,
+                        RESOLVE_BY_FONT_TABLE);
             } else {
                 fontFamily.abortCreation();
             }
@@ -1055,16 +1069,25 @@
         for (int i = 0; i < families.length; i++) {
             ptrArray[i] = families[i].mNativePtr;
         }
-        return new Typeface(nativeCreateFromArray(ptrArray));
+        return new Typeface(nativeCreateFromArray(
+                ptrArray, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
     }
 
     /**
      * Create a new typeface from an array of font families, including
      * also the font families in the fallback list.
-     *
+     * @param weight the weight for this family. {@link RESOLVE_BY_FONT_TABLE} can be used. In that
+     *               case, the table information in the first family's font is used. If the first
+     *               family has multiple fonts, the closest to the regular weight and upright font
+     *               is used.
+     * @param italic the italic information for this family. {@link RESOLVE_BY_FONT_TABLE} can be
+     *               used. In that case, the table information in the first family's font is used.
+     *               If the first family has multiple fonts, the closest to the regular weight and
+     *               upright font is used.
      * @param families array of font families
      */
-    private static Typeface createFromFamiliesWithDefault(FontFamily[] families) {
+    private static Typeface createFromFamiliesWithDefault(FontFamily[] families,
+                int weight, int italic) {
         long[] ptrArray = new long[families.length + sFallbackFonts.length];
         for (int i = 0; i < families.length; i++) {
             ptrArray[i] = families[i].mNativePtr;
@@ -1072,7 +1095,7 @@
         for (int i = 0; i < sFallbackFonts.length; i++) {
             ptrArray[i + families.length] = sFallbackFonts[i].mNativePtr;
         }
-        return new Typeface(nativeCreateFromArray(ptrArray));
+        return new Typeface(nativeCreateFromArray(ptrArray, weight, italic));
     }
 
     // don't allow clients to call this directly
@@ -1155,7 +1178,8 @@
                     } else {
                         FontFamily fontFamily = makeFamilyFromParsed(f, bufferForPath);
                         FontFamily[] families = { fontFamily };
-                        typeface = Typeface.createFromFamiliesWithDefault(families);
+                        typeface = Typeface.createFromFamiliesWithDefault(families,
+                                RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
                     }
                     systemFonts.put(f.getName(), typeface);
                 }
@@ -1262,7 +1286,7 @@
     private static native void nativeUnref(long native_instance);
     private static native int  nativeGetStyle(long native_instance);
     private static native int  nativeGetBaseWeight(long native_instance);
-    private static native long nativeCreateFromArray(long[] familyArray);
+    private static native long nativeCreateFromArray(long[] familyArray, int weight, int italic);
     private static native void nativeSetDefault(long native_instance);
     private static native int[] nativeGetSupportedAxes(long native_instance);
 }
diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp
index 86709ee..4fb4b53 100644
--- a/libs/hwui/hwui/Typeface.cpp
+++ b/libs/hwui/hwui/Typeface.cpp
@@ -39,14 +39,22 @@
 
 namespace android {
 
-// Resolve the 1..9 weight based on base weight and bold flag
+// This indicates that the passed information should be resolved by OS/2 table.
+// This value must be the same as the android.graphics.Typeface$Builder.RESOLVE_BY_FONT_TABLE.
+constexpr int RESOLVE_BY_FONT_TABLE = -1;
+
+// Resolve the 1..10 weight based on base weight and bold flag
 static void resolveStyle(Typeface* typeface) {
-    int weight = typeface->fBaseWeight / 100;
+    // TODO: Better to use raw base weight value for font selection instead of dividing by 100.
+    int weight = (typeface->fBaseWeight + 50) / 100;
     if (typeface->fSkiaStyle & SkTypeface::kBold) {
         weight += 3;
     }
-    if (weight > 9) {
-        weight = 9;
+    if (weight > 10) {
+        weight = 10;
+    }
+    if (weight < 1) {
+        weight = 1;
     }
     bool italic = (typeface->fSkiaStyle & SkTypeface::kItalic) != 0;
     typeface->fStyle = minikin::FontStyle(weight, italic);
@@ -115,26 +123,50 @@
 }
 
 Typeface* Typeface::createFromFamilies(
-        std::vector<std::shared_ptr<minikin::FontFamily>>&& families) {
+        std::vector<std::shared_ptr<minikin::FontFamily>>&& families,
+        int weight, int italic) {
     Typeface* result = new Typeface;
     result->fFontCollection.reset(new minikin::FontCollection(families));
-    if (families.empty()) {
-        ALOGW("createFromFamilies creating empty collection");
-        result->fSkiaStyle = SkTypeface::kNormal;
-    } else {
+
+    if (weight == RESOLVE_BY_FONT_TABLE || italic == RESOLVE_BY_FONT_TABLE) {
+        int weightFromFont;
+        bool italicFromFont;
+
         const minikin::FontStyle defaultStyle;
-        const std::shared_ptr<minikin::FontFamily>& firstFamily = families[0];
-        const minikin::MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle).font;
+        const minikin::MinikinFont* mf =
+                families.empty() ?  nullptr : families[0]->getClosestMatch(defaultStyle).font;
         if (mf != nullptr) {
             SkTypeface* skTypeface = reinterpret_cast<const MinikinFontSkia*>(mf)->GetSkTypeface();
-            // TODO: probably better to query more precise style from family, will be important
-            // when we open up API to access 100..900 weights
-            result->fSkiaStyle = skTypeface->style();
+            const SkFontStyle& style = skTypeface->fontStyle();
+            weightFromFont = style.weight();
+            italicFromFont = style.slant() != SkFontStyle::kUpright_Slant;
         } else {
-            result->fSkiaStyle = SkTypeface::kNormal;
+            // We can't obtain any information from fonts. Just use default values.
+            weightFromFont = SkFontStyle::kNormal_Weight;
+            italicFromFont = false;
+        }
+
+        if (weight == RESOLVE_BY_FONT_TABLE) {
+            weight = weightFromFont;
+        }
+        if (italic == RESOLVE_BY_FONT_TABLE) {
+            italic = italicFromFont? 1 : 0;
         }
     }
-    result->fBaseWeight = 400;
+
+    // Sanitize the invalid value passed from public API.
+    if (weight < 0) {
+        weight = SkFontStyle::kNormal_Weight;
+    }
+
+    result->fBaseWeight = weight;
+    // This bold detection comes from SkTypefae.h
+    const bool isBold = weight >= SkFontStyle::kSemiBold_Weight;
+    const bool isItalic = italic == 1;
+    // TODO: remove fSkiaStyle
+    result->fSkiaStyle = isBold ?
+            (isItalic ? SkTypeface::kBoldItalic : SkTypeface::kBold) :
+            (isItalic ? SkTypeface::kItalic : SkTypeface::kNormal);
     resolveStyle(result);
     return result;
 }
@@ -165,7 +197,7 @@
     Typeface* hwTypeface = new Typeface();
     hwTypeface->fFontCollection = collection;
     hwTypeface->fSkiaStyle = SkTypeface::kNormal;
-    hwTypeface->fBaseWeight = 400;
+    hwTypeface->fBaseWeight = SkFontStyle::kSemiBold_Weight;
     hwTypeface->fStyle = minikin::FontStyle(4 /* weight */, false /* italic */);
 
     Typeface::setDefault(hwTypeface);
diff --git a/libs/hwui/hwui/Typeface.h b/libs/hwui/hwui/Typeface.h
index 27ee4a2..e35a7b4 100644
--- a/libs/hwui/hwui/Typeface.h
+++ b/libs/hwui/hwui/Typeface.h
@@ -50,7 +50,8 @@
     static Typeface* createWeightAlias(Typeface* src, int baseweight);
 
     static Typeface* createFromFamilies(
-            std::vector<std::shared_ptr<minikin::FontFamily>>&& families);
+            std::vector<std::shared_ptr<minikin::FontFamily>>&& families,
+            int weight, int italic);
 
     static void setDefault(Typeface* face);
 
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index b8d1d12..88b1c5f 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -474,6 +474,9 @@
     /**
      * This event type indicates that the licensed usage duration for keys in a session
      * has expired.  The keys are no longer valid.
+     * @deprecated Use {@link OnKeyStatusChangeListener#onKeyStatusChange}
+     * and check for {@link MediaDrm.KeyStatus#STATUS_EXPIRED} in the {@link MediaDrm.KeyStatus}
+     * instead.
      */
     public static final int EVENT_KEY_EXPIRED = 3;
 
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 330442c..1b55380 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -187,6 +187,38 @@
             "android.media.tv.extra.WATCH_NEXT_PROGRAM_ID";
 
     /**
+     * The key for a bundle parameter containing the result code of a method call as an integer.
+     *
+     * @see #RESULT_OK
+     * @see #RESULT_ERROR_IO
+     * @see #RESULT_ERROR_INVALID_ARGUMENT
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_RESULT_CODE = "android.media.tv.extra.RESULT_CODE";
+
+    /**
+     * The result code for a successful execution without error.
+     * @hide
+     */
+    @SystemApi
+    public static final int RESULT_OK = 0;
+
+    /**
+     * The result code for a failure from I/O operation.
+     * @hide
+     */
+    @SystemApi
+    public static final int RESULT_ERROR_IO = 1;
+
+    /**
+     * The result code for a failure from invalid argument.
+     * @hide
+     */
+    @SystemApi
+    public static final int RESULT_ERROR_INVALID_ARGUMENT = 2;
+
+    /**
      * The method name to get existing columns in the given table of the specified content provider.
      *
      * <p>The method caller must provide the following parameter:
@@ -235,6 +267,78 @@
     public static final String METHOD_ADD_COLUMN = "add_column";
 
     /**
+     * The method name to get all the blocked packages. When a package is blocked, all the data for
+     * preview programs/channels and watch next programs belonging to this package in the content
+     * provider will be cleared. Once a package is blocked, {@link SecurityException} will be thrown
+     * for all the requests to preview programs/channels and watch next programs via
+     * {@link android.content.ContentProvider} from it.
+     *
+     * <p>The returned {@link android.os.Bundle} will include all the blocked package names with the
+     * key {@link #EXTRA_BLOCKED_PACKAGES}.
+     *
+     * @see ContentResolver#call(Uri, String, String, Bundle)
+     * @see #EXTRA_BLOCKED_PACKAGES
+     * @see #METHOD_BLOCK_PACKAGE
+     * @see #METHOD_UNBLOCK_PACKAGE
+     * @hide
+     */
+    @SystemApi
+    public static final String METHOD_GET_BLOCKED_PACKAGES = "get_blocked_packages";
+
+    /**
+     * The method name to block the access from the given package. When a package is blocked, all
+     * the data for preview programs/channels and watch next programs belonging to this package in
+     * the content provider will be cleared. Once a package is blocked, {@link SecurityException}
+     * will be thrown for all the requests to preview programs/channels and watch next programs via
+     * {@link android.content.ContentProvider} from it.
+     *
+     * <p>The method caller must provide the following parameter:
+     * <ul>
+     *     <li>{@code arg}: The package name to be added as blocked package {@link String}.</li>
+     * </ul>
+     *
+     * <p>The returned {@link android.os.Bundle} will include an integer code denoting whether the
+     * execution is successful or not with the key {@link #EXTRA_RESULT_CODE}. If {@code arg} is
+     * empty, the result code will be {@link #RESULT_ERROR_INVALID_ARGUMENT}. If success, the result
+     * code will be {@link #RESULT_OK}. Otherwise, the result code will be {@link #RESULT_ERROR_IO}.
+     *
+     * @see ContentResolver#call(Uri, String, String, Bundle)
+     * @see #EXTRA_RESULT_CODE
+     * @see #METHOD_GET_BLOCKED_PACKAGES
+     * @see #METHOD_UNBLOCK_PACKAGE
+     * @hide
+     */
+    @SystemApi
+    public static final String METHOD_BLOCK_PACKAGE = "block_package";
+
+    /**
+     * The method name to unblock the access from the given package. When a package is blocked, all
+     * the data for preview programs/channels and watch next programs belonging to this package in
+     * the content provider will be cleared. Once a package is blocked, {@link SecurityException}
+     * will be thrown for all the requests to preview programs/channels and watch next programs via
+     * {@link android.content.ContentProvider} from it.
+     *
+     * <p>The method caller must provide the following parameter:
+     * <ul>
+     *     <li>{@code arg}: The package name to be removed from blocked list as a {@link String}.
+     *     </li>
+     * </ul>
+     *
+     * <p>The returned {@link android.os.Bundle} will include an integer code denoting whether the
+     * execution is successful or not with the key {@link #EXTRA_RESULT_CODE}. If {@code arg} is
+     * empty, the result code will be {@link #RESULT_ERROR_INVALID_ARGUMENT}. If success, the result
+     * code will be {@link #RESULT_OK}. Otherwise, the result code will be {@link #RESULT_ERROR_IO}.
+     *
+     * @see ContentResolver#call(Uri, String, String, Bundle)
+     * @see #EXTRA_RESULT_CODE
+     * @see #METHOD_GET_BLOCKED_PACKAGES
+     * @see #METHOD_BLOCK_PACKAGE
+     * @hide
+     */
+    @SystemApi
+    public static final String METHOD_UNBLOCK_PACKAGE = "unblock_package";
+
+    /**
      * The key for a returned {@link Bundle} value containing existing column names in the given
      * table as an {@link ArrayList} of {@link String}.
      *
@@ -279,6 +383,16 @@
     public static final String EXTRA_DEFAULT_VALUE = "android.media.tv.extra.DEFAULT_VALUE";
 
     /**
+     * The key for a returned {@link Bundle} value containing all the blocked package names as an
+     * {@link ArrayList} of {@link String}.
+     *
+     * @see #METHOD_GET_BLOCKED_PACKAGES
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_BLOCKED_PACKAGES = "android.media.tv.extra.BLOCKED_PACKAGES";
+
+    /**
      * An optional query, update or delete URI parameter that allows the caller to specify TV input
      * ID to filter channels.
      * @hide
@@ -2239,19 +2353,6 @@
          */
         public static final String COLUMN_TRANSIENT = "transient";
 
-        /**
-         * The flag indicating whether this TV channel is approved to be shown by the system.
-         *
-         * <p>A value of 1 indicates that the channel is approved to be shown by the system, and a
-         * value of 0 indicates that the channel is blocked by system. If not specified, this value
-         * is set to 0 (not approved) by default.
-         *
-         * <p>Type: INTEGER (boolean)
-         * @hide
-         */
-        @SystemApi
-        public static final String COLUMN_SYSTEM_APPROVED = "system_approved";
-
         private Channels() {}
 
         /**
diff --git a/media/mca/samples/CameraEffectsRecordingSample/java/android/media/filterfw/samples/CameraEffectsRecordingSample.java b/media/mca/samples/CameraEffectsRecordingSample/java/android/media/filterfw/samples/CameraEffectsRecordingSample.java
index c0c3034..0b62bca 100644
--- a/media/mca/samples/CameraEffectsRecordingSample/java/android/media/filterfw/samples/CameraEffectsRecordingSample.java
+++ b/media/mca/samples/CameraEffectsRecordingSample/java/android/media/filterfw/samples/CameraEffectsRecordingSample.java
@@ -45,8 +45,8 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
-        mRunButton = (Button) findViewById(R.id.runbutton);
-        mCameraView = (SurfaceView) findViewById(R.id.cameraview);
+        mRunButton = findViewById(R.id.runbutton);
+        mCameraView = findViewById(R.id.cameraview);
         mRunButton.setOnClickListener(mRunButtonClick);
 
         Intent intent = getIntent();
diff --git a/media/tests/EffectsTest/src/com/android/effectstest/BassBoostTest.java b/media/tests/EffectsTest/src/com/android/effectstest/BassBoostTest.java
index 1a10d64..cce2acc 100644
--- a/media/tests/EffectsTest/src/com/android/effectstest/BassBoostTest.java
+++ b/media/tests/EffectsTest/src/com/android/effectstest/BassBoostTest.java
@@ -70,7 +70,7 @@
 
         setContentView(R.layout.bassboosttest);
 
-        mSessionText = (EditText) findViewById(R.id.sessionEdit);
+        mSessionText = findViewById(R.id.sessionEdit);
         mSessionText.setOnKeyListener(mSessionKeyListener);
 
         mSessionText.setText(Integer.toString(sSession));
diff --git a/media/tests/EffectsTest/src/com/android/effectstest/EnvReverbTest.java b/media/tests/EffectsTest/src/com/android/effectstest/EnvReverbTest.java
index 594e844..1731dba 100644
--- a/media/tests/EffectsTest/src/com/android/effectstest/EnvReverbTest.java
+++ b/media/tests/EffectsTest/src/com/android/effectstest/EnvReverbTest.java
@@ -73,9 +73,9 @@
         ToggleButton button;
         setContentView(R.layout.envreverbtest);
 
-        ImageView playPause = (ImageView) findViewById(R.id.playPause1);
-        ImageView stop = (ImageView) findViewById(R.id.stop1);
-        textView = (TextView) findViewById(R.id.sessionText);
+        ImageView playPause = findViewById(R.id.playPause1);
+        ImageView stop = findViewById(R.id.stop1);
+        textView = findViewById(R.id.sessionText);
         if (sPlayerController == null) {
             sPlayerController = new SimplePlayer(this, R.id.playPause1, playPause,
                     R.id.stop1, stop, textView,
diff --git a/media/tests/EffectsTest/src/com/android/effectstest/EqualizerTest.java b/media/tests/EffectsTest/src/com/android/effectstest/EqualizerTest.java
index f30a26f..fd56956 100644
--- a/media/tests/EffectsTest/src/com/android/effectstest/EqualizerTest.java
+++ b/media/tests/EffectsTest/src/com/android/effectstest/EqualizerTest.java
@@ -72,7 +72,7 @@
 
         setContentView(R.layout.equalizertest);
 
-        mSessionText = (EditText) findViewById(R.id.sessionEdit);
+        mSessionText = findViewById(R.id.sessionEdit);
         mSessionText.setOnKeyListener(mSessionKeyListener);
 
         mSessionText.setText(Integer.toString(sSession));
diff --git a/media/tests/EffectsTest/src/com/android/effectstest/VirtualizerTest.java b/media/tests/EffectsTest/src/com/android/effectstest/VirtualizerTest.java
index bb32e6f..4f2180f 100644
--- a/media/tests/EffectsTest/src/com/android/effectstest/VirtualizerTest.java
+++ b/media/tests/EffectsTest/src/com/android/effectstest/VirtualizerTest.java
@@ -70,7 +70,7 @@
 
         setContentView(R.layout.virtualizertest);
 
-        mSessionText = (EditText) findViewById(R.id.sessionEdit);
+        mSessionText = findViewById(R.id.sessionEdit);
         mSessionText.setOnKeyListener(mSessionKeyListener);
         mSessionText.setText(Integer.toString(sSession));
 
diff --git a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java
index 60583e0..7db1d8d 100644
--- a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java
+++ b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java
@@ -72,7 +72,7 @@
 
         setContentView(R.layout.visualizertest);
 
-        mSessionText = (EditText) findViewById(R.id.sessionEdit);
+        mSessionText = findViewById(R.id.sessionEdit);
         mSessionText.setOnKeyListener(mSessionKeyListener);
         mSessionText.setText(Integer.toString(sSession));
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/Camera2SurfaceViewActivity.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/Camera2SurfaceViewActivity.java
index c3dd842..963b20d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/Camera2SurfaceViewActivity.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/Camera2SurfaceViewActivity.java
@@ -43,7 +43,7 @@
         super.onCreate(savedInstanceState);
 
         setContentView(R.layout.surface_view_2);
-        mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);
+        mSurfaceView = findViewById(R.id.surface_view);
         mSurfaceView.getHolder().addCallback(this);
 
         //Acquire the full wake lock to keep the device up
diff --git a/media/tests/NativeMidiDemo/java/com/example/android/nativemididemo/NativeMidi.java b/media/tests/NativeMidiDemo/java/com/example/android/nativemididemo/NativeMidi.java
index 0969b10..b0ca0bb 100644
--- a/media/tests/NativeMidiDemo/java/com/example/android/nativemididemo/NativeMidi.java
+++ b/media/tests/NativeMidiDemo/java/com/example/android/nativemididemo/NativeMidi.java
@@ -269,12 +269,12 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
 
-        mCallbackStatusTextView = (TextView) findViewById(R.id.callback_status);
-        mJavaMidiStatusTextView = (TextView) findViewById(R.id.java_midi_status);
-        mMessagesTextView = (TextView) findViewById(R.id.messages);
-        mMessagesContainer = (TouchableScrollView) findViewById(R.id.messages_scroll);
-        mMidiDevicesRadioGroup = (RadioGroup) findViewById(R.id.devices);
-        RadioButton deviceNone = (RadioButton) findViewById(R.id.device_none);
+        mCallbackStatusTextView = findViewById(R.id.callback_status);
+        mJavaMidiStatusTextView = findViewById(R.id.java_midi_status);
+        mMessagesTextView = findViewById(R.id.messages);
+        mMessagesContainer = findViewById(R.id.messages_scroll);
+        mMidiDevicesRadioGroup = findViewById(R.id.devices);
+        RadioButton deviceNone = findViewById(R.id.device_none);
         deviceNone.setOnClickListener(new MidiOutputPortSelector());
 
         AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
diff --git a/media/tests/ScoAudioTest/src/com/android/scoaudiotest/ScoAudioTest.java b/media/tests/ScoAudioTest/src/com/android/scoaudiotest/ScoAudioTest.java
index 7e21876..8427d16 100644
--- a/media/tests/ScoAudioTest/src/com/android/scoaudiotest/ScoAudioTest.java
+++ b/media/tests/ScoAudioTest/src/com/android/scoaudiotest/ScoAudioTest.java
@@ -97,8 +97,8 @@
         
         setContentView(R.layout.scoaudiotest);
 
-        mScoStateTxt = (TextView) findViewById(R.id.scoStateTxt);
-        mVdStateTxt = (TextView) findViewById(R.id.vdStateTxt);
+        mScoStateTxt = findViewById(R.id.scoStateTxt);
+        mVdStateTxt = findViewById(R.id.vdStateTxt);
 
         IntentFilter intentFilter =
             new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
@@ -112,7 +112,7 @@
         
         mMediaControllers[0] = new SimplePlayerController(this, R.id.playPause1, R.id.stop1,
                 R.raw.sine440_mo_16b_16k, AudioManager.STREAM_BLUETOOTH_SCO);
-        TextView name = (TextView) findViewById(R.id.playPause1Text);
+        TextView name = findViewById(R.id.playPause1Text);
         name.setText("VOICE_CALL stream");
         
         mScoButton = (ToggleButton)findViewById(R.id.ForceScoButton);
@@ -135,7 +135,7 @@
         mTtsParams.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,
                 UTTERANCE);
 
-        mSpeakText = (EditText) findViewById(R.id.speakTextEdit);        
+        mSpeakText = findViewById(R.id.speakTextEdit);
         mSpeakText.setOnKeyListener(mSpeakKeyListener);
         mSpeakText.setText("sco audio test sentence");
         mTtsToFileButton = (ToggleButton)findViewById(R.id.TtsToFileButton);
@@ -143,7 +143,7 @@
         mTtsToFile = true;
         mTtsToFileButton.setChecked(mTtsToFile);
 
-        mModeSpinner = (Spinner) findViewById(R.id.modeSpinner);
+        mModeSpinner = findViewById(R.id.modeSpinner);
         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                 android.R.layout.simple_spinner_item, mModeStrings);
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
@@ -208,12 +208,12 @@
                 mForceScoOn = isChecked;
                 AudioManager mngr = mAudioManager;
                 boolean useVirtualCall = false;
-                CheckBox box = (CheckBox) findViewById(R.id.useSecondAudioManager);
+                CheckBox box = findViewById(R.id.useSecondAudioManager);
                 if (box.isChecked()) {
                     Log.i(TAG, "Using 2nd audio manager");
                     mngr = mAudioManager2;
                 }
-                box = (CheckBox) findViewById(R.id.useVirtualCallCheckBox);
+                box = findViewById(R.id.useVirtualCallCheckBox);
                 useVirtualCall = box.isChecked();
 
                 if (mForceScoOn) {
@@ -278,8 +278,8 @@
             mPlayPauseButtonId = playPausebuttonId;
             mStopButtonId = stopButtonId;
             mFileNameBase = fileName;
-            mPlayPauseButton = (ImageButton) findViewById(playPausebuttonId);
-            ImageButton stop = (ImageButton) findViewById(stopButtonId);
+            mPlayPauseButton = findViewById(playPausebuttonId);
+            ImageButton stop = findViewById(stopButtonId);
 
             mPlayPauseButton.setOnClickListener(this);
             mPlayPauseButton.requestFocus();
@@ -294,8 +294,8 @@
             mStopButtonId = stopButtonId;
             mFileNameBase = "";
             mFileResId = fileResId;
-            mPlayPauseButton = (ImageButton) findViewById(playPausebuttonId);
-            ImageButton stop = (ImageButton) findViewById(stopButtonId);
+            mPlayPauseButton = findViewById(playPausebuttonId);
+            ImageButton stop = findViewById(stopButtonId);
 
             mPlayPauseButton.setOnClickListener(this);
             mPlayPauseButton.requestFocus();
diff --git a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
index 7fa5736..9fa7a664 100644
--- a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
+++ b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
@@ -173,13 +173,13 @@
         setContentView(layoutId);
 
         // Same resource IDs for each layout variant (backup / restore)
-        mStatusView = (TextView) findViewById(R.id.package_name);
-        mAllowButton = (Button) findViewById(R.id.button_allow);
-        mDenyButton = (Button) findViewById(R.id.button_deny);
+        mStatusView = findViewById(R.id.package_name);
+        mAllowButton = findViewById(R.id.button_allow);
+        mDenyButton = findViewById(R.id.button_deny);
 
-        mCurPassword = (TextView) findViewById(R.id.password);
-        mEncPassword = (TextView) findViewById(R.id.enc_password);
-        TextView curPwDesc = (TextView) findViewById(R.id.password_desc);
+        mCurPassword = findViewById(R.id.password);
+        mEncPassword = findViewById(R.id.enc_password);
+        TextView curPwDesc = findViewById(R.id.password_desc);
 
         mAllowButton.setOnClickListener(new View.OnClickListener() {
             @Override
@@ -214,7 +214,7 @@
             curPwDesc.setVisibility(View.GONE);
             mCurPassword.setVisibility(View.GONE);
             if (layoutId == R.layout.confirm_backup) {
-                TextView encPwDesc = (TextView) findViewById(R.id.enc_password_desc);
+                TextView encPwDesc = findViewById(R.id.enc_password_desc);
                 if (mIsEncrypted) {
                     encPwDesc.setText(R.string.backup_enc_password_required);
                     monitorEncryptionPassword();
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index 6394c64..5d20cf3 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -117,7 +117,7 @@
         }
         mCm.registerNetworkCallback(builder.build(), mNetworkCallback);
 
-        final WebView myWebView = (WebView) findViewById(R.id.webview);
+        final WebView myWebView = findViewById(R.id.webview);
         myWebView.clearCache(true);
         WebSettings webSettings = myWebView.getSettings();
         webSettings.setJavaScriptEnabled(true);
@@ -184,7 +184,7 @@
 
     @Override
     public void onBackPressed() {
-        WebView myWebView = (WebView) findViewById(R.id.webview);
+        WebView myWebView = findViewById(R.id.webview);
         if (myWebView.canGoBack() && mWebViewClient.allowBack()) {
             myWebView.goBack();
         } else {
@@ -326,7 +326,7 @@
             // For internally generated pages, leave URL bar listing prior URL as this is the URL
             // the page refers to.
             if (!url.startsWith(INTERNAL_ASSETS)) {
-                final TextView myUrlBar = (TextView) findViewById(R.id.url_bar);
+                final TextView myUrlBar = findViewById(R.id.url_bar);
                 myUrlBar.setText(url);
             }
             testForCaptivePortal();
@@ -407,7 +407,7 @@
     private class MyWebChromeClient extends WebChromeClient {
         @Override
         public void onProgressChanged(WebView view, int newProgress) {
-            final ProgressBar myProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
+            final ProgressBar myProgressBar = findViewById(R.id.progress_bar);
             myProgressBar.setProgress(newProgress);
         }
     }
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index a5820f2..6276ce3 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -91,7 +91,7 @@
         setContentView(R.layout.activity_captive_portal_login);
         getActionBar().setDisplayShowHomeEnabled(false);
 
-        mWebView = (WebView) findViewById(R.id.webview);
+        mWebView = findViewById(R.id.webview);
         mWebView.clearCache(true);
         WebSettings webSettings = mWebView.getSettings();
         webSettings.setJavaScriptEnabled(true);
@@ -113,7 +113,7 @@
 
     @Override
     public void onBackPressed() {
-        WebView myWebView = (WebView) findViewById(R.id.webview);
+        WebView myWebView = findViewById(R.id.webview);
         if (myWebView.canGoBack() && mWebViewClient.allowBack()) {
             myWebView.goBack();
         } else {
@@ -328,7 +328,7 @@
             // For internally generated pages, leave URL bar listing prior URL as this is the URL
             // the page refers to.
             if (!url.startsWith(INTERNAL_ASSETS)) {
-                final TextView myUrlBar = (TextView) findViewById(R.id.url_bar);
+                final TextView myUrlBar = findViewById(R.id.url_bar);
                 myUrlBar.setText(url);
             }
             if (mNetwork != null) {
@@ -412,7 +412,7 @@
     private class MyWebChromeClient extends WebChromeClient {
         @Override
         public void onProgressChanged(WebView view, int newProgress) {
-            final ProgressBar myProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
+            final ProgressBar myProgressBar = findViewById(R.id.progress_bar);
             myProgressBar.setProgress(newProgress);
         }
     }
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
index 14b9de5..76a64e5 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
@@ -65,7 +65,7 @@
         } else {
             setContentView(R.layout.device_chooser);
             setTitle(Html.fromHtml(getString(R.string.chooser_title, getCallingAppName()), 0));
-            mDeviceListView = (ListView) findViewById(R.id.device_list);
+            mDeviceListView = findViewById(R.id.device_list);
             final DeviceDiscoveryService.DevicesAdapter adapter = getService().mDevicesAdapter;
             mDeviceListView.setAdapter(adapter);
             adapter.registerDataSetObserver(new DataSetObserver() {
@@ -101,7 +101,7 @@
 
     @Override
     public void setTitle(CharSequence title) {
-        final TextView titleView = (TextView) findViewById(R.id.title);
+        final TextView titleView = findViewById(R.id.title);
         final int padding = getPadding(getResources());
         titleView.setPadding(padding, padding, padding, padding);
         titleView.setText(title);
diff --git a/packages/EasterEgg/src/com/android/egg/neko/NekoLand.java b/packages/EasterEgg/src/com/android/egg/neko/NekoLand.java
index f59f0d9..689e381 100644
--- a/packages/EasterEgg/src/com/android/egg/neko/NekoLand.java
+++ b/packages/EasterEgg/src/com/android/egg/neko/NekoLand.java
@@ -82,7 +82,7 @@
 
         mPrefs = new PrefState(this);
         mPrefs.setListener(this);
-        final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.holder);
+        final RecyclerView recyclerView = findViewById(R.id.holder);
         mAdapter = new CatAdapter();
         recyclerView.setAdapter(mAdapter);
         recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
diff --git a/packages/Osu/src/com/android/hotspot2/app/MainActivity.java b/packages/Osu/src/com/android/hotspot2/app/MainActivity.java
index ae0a45c..7fd2238 100644
--- a/packages/Osu/src/com/android/hotspot2/app/MainActivity.java
+++ b/packages/Osu/src/com/android/hotspot2/app/MainActivity.java
@@ -123,7 +123,7 @@
         if (osuData.size() > 0) {
             noOsuView.setVisibility(View.GONE);
             osuListAdapter = new OsuListAdapter(this, osuData);
-            osuListView = (ListView) findViewById(R.id.profile_list);
+            osuListView = findViewById(R.id.profile_list);
             osuListView.setAdapter(osuListAdapter);
             osuListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                 @Override
diff --git a/packages/Osu/src/com/android/hotspot2/osu/OSUWebView.java b/packages/Osu/src/com/android/hotspot2/osu/OSUWebView.java
index afbd0d1..a6778c8 100644
--- a/packages/Osu/src/com/android/hotspot2/osu/OSUWebView.java
+++ b/packages/Osu/src/com/android/hotspot2/osu/OSUWebView.java
@@ -37,7 +37,7 @@
         setContentView(R.layout.osu_web_view);
         getActionBar().setDisplayShowHomeEnabled(false);
 
-        final WebView myWebView = (WebView) findViewById(R.id.webview);
+        final WebView myWebView = findViewById(R.id.webview);
         myWebView.clearCache(true);
         WebSettings webSettings = myWebView.getSettings();
         webSettings.setJavaScriptEnabled(true);
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 4cce166..ccdec62 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -1290,11 +1290,11 @@
     private void bindUi() {
         // Summary
         mSummaryContainer = findViewById(R.id.summary_content);
-        mSummaryCopies = (TextView) findViewById(R.id.copies_count_summary);
-        mSummaryPaperSize = (TextView) findViewById(R.id.paper_size_summary);
+        mSummaryCopies = findViewById(R.id.copies_count_summary);
+        mSummaryPaperSize = findViewById(R.id.paper_size_summary);
 
         // Options container
-        mOptionsContent = (PrintContentView) findViewById(R.id.options_content);
+        mOptionsContent = findViewById(R.id.options_content);
         mOptionsContent.setOptionsStateChangeListener(this);
         mOptionsContent.setOpenOptionsController(this);
 
@@ -1302,7 +1302,7 @@
         OnClickListener clickListener = new MyClickListener();
 
         // Copies
-        mCopiesEditText = (EditText) findViewById(R.id.copies_edittext);
+        mCopiesEditText = findViewById(R.id.copies_edittext);
         mCopiesEditText.setOnFocusChangeListener(mSelectAllOnFocusListener);
         mCopiesEditText.setText(MIN_COPIES_STRING);
         mCopiesEditText.setSelection(mCopiesEditText.getText().length());
@@ -1311,28 +1311,28 @@
         // Destination.
         mPrintersObserver = new PrintersObserver();
         mDestinationSpinnerAdapter.registerDataSetObserver(mPrintersObserver);
-        mDestinationSpinner = (Spinner) findViewById(R.id.destination_spinner);
+        mDestinationSpinner = findViewById(R.id.destination_spinner);
         mDestinationSpinner.setAdapter(mDestinationSpinnerAdapter);
         mDestinationSpinner.setOnItemSelectedListener(itemSelectedListener);
 
         // Media size.
         mMediaSizeSpinnerAdapter = new ArrayAdapter<>(
                 this, android.R.layout.simple_spinner_dropdown_item, android.R.id.text1);
-        mMediaSizeSpinner = (Spinner) findViewById(R.id.paper_size_spinner);
+        mMediaSizeSpinner = findViewById(R.id.paper_size_spinner);
         mMediaSizeSpinner.setAdapter(mMediaSizeSpinnerAdapter);
         mMediaSizeSpinner.setOnItemSelectedListener(itemSelectedListener);
 
         // Color mode.
         mColorModeSpinnerAdapter = new ArrayAdapter<>(
                 this, android.R.layout.simple_spinner_dropdown_item, android.R.id.text1);
-        mColorModeSpinner = (Spinner) findViewById(R.id.color_spinner);
+        mColorModeSpinner = findViewById(R.id.color_spinner);
         mColorModeSpinner.setAdapter(mColorModeSpinnerAdapter);
         mColorModeSpinner.setOnItemSelectedListener(itemSelectedListener);
 
         // Duplex mode.
         mDuplexModeSpinnerAdapter = new ArrayAdapter<>(
                 this, android.R.layout.simple_spinner_dropdown_item, android.R.id.text1);
-        mDuplexModeSpinner = (Spinner) findViewById(R.id.duplex_spinner);
+        mDuplexModeSpinner = findViewById(R.id.duplex_spinner);
         mDuplexModeSpinner.setAdapter(mDuplexModeSpinnerAdapter);
         mDuplexModeSpinner.setOnItemSelectedListener(itemSelectedListener);
 
@@ -1345,32 +1345,32 @@
                 ORIENTATION_PORTRAIT, orientationLabels[0]));
         mOrientationSpinnerAdapter.add(new SpinnerItem<>(
                 ORIENTATION_LANDSCAPE, orientationLabels[1]));
-        mOrientationSpinner = (Spinner) findViewById(R.id.orientation_spinner);
+        mOrientationSpinner = findViewById(R.id.orientation_spinner);
         mOrientationSpinner.setAdapter(mOrientationSpinnerAdapter);
         mOrientationSpinner.setOnItemSelectedListener(itemSelectedListener);
 
         // Range options
         ArrayAdapter<SpinnerItem<Integer>> rangeOptionsSpinnerAdapter = new ArrayAdapter<>(
                 this, android.R.layout.simple_spinner_dropdown_item, android.R.id.text1);
-        mRangeOptionsSpinner = (Spinner) findViewById(R.id.range_options_spinner);
+        mRangeOptionsSpinner = findViewById(R.id.range_options_spinner);
         mRangeOptionsSpinner.setAdapter(rangeOptionsSpinnerAdapter);
         mRangeOptionsSpinner.setOnItemSelectedListener(itemSelectedListener);
         updatePageRangeOptions(PrintDocumentInfo.PAGE_COUNT_UNKNOWN);
 
         // Page range
-        mPageRangeTitle = (TextView) findViewById(R.id.page_range_title);
-        mPageRangeEditText = (EditText) findViewById(R.id.page_range_edittext);
+        mPageRangeTitle = findViewById(R.id.page_range_title);
+        mPageRangeEditText = findViewById(R.id.page_range_edittext);
         mPageRangeEditText.setVisibility(View.GONE);
         mPageRangeTitle.setVisibility(View.GONE);
         mPageRangeEditText.setOnFocusChangeListener(mSelectAllOnFocusListener);
         mPageRangeEditText.addTextChangedListener(new RangeTextWatcher());
 
         // Advanced options button.
-        mMoreOptionsButton = (Button) findViewById(R.id.more_options_button);
+        mMoreOptionsButton = findViewById(R.id.more_options_button);
         mMoreOptionsButton.setOnClickListener(clickListener);
 
         // Print button
-        mPrintButton = (ImageView) findViewById(R.id.print_button);
+        mPrintButton = findViewById(R.id.print_button);
         mPrintButton.setOnClickListener(clickListener);
 
         // The UI is now initialized
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
index 6f0caa2..a9a6cbd 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java
@@ -134,7 +134,7 @@
                 LOADER_ID_PRINT_REGISTRY_INT);
 
         // Hook up the list view.
-        mListView = (ListView) findViewById(android.R.id.list);
+        mListView = findViewById(android.R.id.list);
         final DestinationAdapter adapter = new DestinationAdapter();
         adapter.registerDataSetObserver(new DataSetObserver() {
             @Override
@@ -411,7 +411,7 @@
             View emptyView = findViewById(R.id.empty_print_state);
             mListView.setEmptyView(emptyView);
         }
-        TextView titleView = (TextView) findViewById(R.id.title);
+        TextView titleView = findViewById(R.id.title);
         View progressBar = findViewById(R.id.progress_bar);
         if (mEnabledPrintServices.size() == 0) {
             titleView.setText(R.string.print_no_print_services);
diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/PrintContentView.java b/packages/PrintSpooler/src/com/android/printspooler/widget/PrintContentView.java
index 0bb4bfa..8b00ed0 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/widget/PrintContentView.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/widget/PrintContentView.java
@@ -136,12 +136,12 @@
     @Override
     protected void onFinishInflate() {
         mStaticContent = findViewById(R.id.static_content);
-        mSummaryContent = (ViewGroup) findViewById(R.id.summary_content);
+        mSummaryContent = findViewById(R.id.summary_content);
         mDynamicContent = findViewById(R.id.dynamic_content);
         mDraggableContent = findViewById(R.id.draggable_content);
         mPrintButton = findViewById(R.id.print_button);
         mMoreOptionsButton = findViewById(R.id.more_options_button);
-        mOptionsContainer = (ViewGroup) findViewById(R.id.options_container);
+        mOptionsContainer = findViewById(R.id.options_container);
         mEmbeddedContentContainer = findViewById(R.id.embedded_content_container);
         mEmbeddedContentScrim = findViewById(R.id.embedded_content_scrim);
         mExpandCollapseHandle = findViewById(R.id.expand_collapse_handle);
diff --git a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java b/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java
index 5b2541c..2d8defa 100644
--- a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java
+++ b/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java
@@ -25,22 +25,21 @@
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.text.format.Formatter;
-import android.util.Log;
 import android.util.SparseIntArray;
 import com.android.internal.os.BatteryStatsHelper;
 import com.android.settingslib.graph.UsageView;
 
 public class BatteryInfo {
 
-    public String mChargeLabelString;
-    public int mBatteryLevel;
-    public boolean mDischarging = true;
+    public String chargeLabelString;
+    public int batteryLevel;
+    public boolean discharging = true;
     public long remainingTimeUs = 0;
     public String batteryPercentString;
     public String remainingLabel;
     public String statusLabel;
-    private BatteryStats mStats;
     private boolean mCharging;
+    private BatteryStats mStats;
     private long timePeriod;
 
     public interface Callback {
@@ -132,10 +131,11 @@
             BatteryStats stats, long elapsedRealtimeUs, boolean shortString) {
         BatteryInfo info = new BatteryInfo();
         info.mStats = stats;
-        info.mBatteryLevel = Utils.getBatteryLevel(batteryBroadcast);
-        info.batteryPercentString = Utils.formatPercentage(info.mBatteryLevel);
+        info.batteryLevel = Utils.getBatteryLevel(batteryBroadcast);
+        info.batteryPercentString = Utils.formatPercentage(info.batteryLevel);
         info.mCharging = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
         final Resources resources = context.getResources();
+
         info.statusLabel = Utils.getBatteryStatus(resources, batteryBroadcast);
         if (!info.mCharging) {
             final long drainTime = stats.computeBatteryTimeRemaining(elapsedRealtimeUs);
@@ -147,20 +147,20 @@
                         shortString ? R.string.power_remaining_duration_only_short
                                 : R.string.power_remaining_duration_only,
                         timeString);
-                info.mChargeLabelString = resources.getString(
+                info.chargeLabelString = resources.getString(
                         shortString ? R.string.power_discharging_duration_short
                                 : R.string.power_discharging_duration,
                         info.batteryPercentString, timeString);
             } else {
                 info.remainingLabel = null;
-                info.mChargeLabelString = info.batteryPercentString;
+                info.chargeLabelString = info.batteryPercentString;
             }
         } else {
             final long chargeTime = stats.computeChargeTimeRemaining(elapsedRealtimeUs);
             final int status = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS,
                     BatteryManager.BATTERY_STATUS_UNKNOWN);
+            info.discharging = false;
             if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) {
-                info.mDischarging = false;
                 info.remainingTimeUs = chargeTime;
                 String timeString = Formatter.formatShortElapsedTime(context,
                         chargeTime / 1000);
@@ -168,13 +168,13 @@
                         : R.string.power_charging_duration;
                 info.remainingLabel = resources.getString(
                         R.string.power_remaining_charging_duration_only, timeString);
-                info.mChargeLabelString = resources.getString(resId, info.batteryPercentString,
-                        timeString);
+                info.chargeLabelString = resources.getString(
+                        resId, info.batteryPercentString, timeString);
             } else {
                 final String chargeStatusLabel = resources.getString(
                         R.string.battery_info_status_charging_lower);
                 info.remainingLabel = null;
-                info.mChargeLabelString = resources.getString(
+                info.chargeLabelString = resources.getString(
                         R.string.power_charging, info.batteryPercentString, chargeStatusLabel);
             }
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index 02f1162..8a86c13 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -984,18 +984,27 @@
                                     mCurComputingSizeUserId = UserHandle.getUserId(entry.info.uid);
 
                                     mBackgroundHandler.post(() -> {
-                                        final StorageStats stats = mStats.queryStatsForPackage(
-                                                mCurComputingSizeUuid, mCurComputingSizePkg,
-                                                UserHandle.of(mCurComputingSizeUserId));
-                                        final PackageStats legacyStats = new PackageStats(
-                                                mCurComputingSizePkg, mCurComputingSizeUserId);
-                                        legacyStats.codeSize = stats.getCodeBytes();
-                                        legacyStats.dataSize = stats.getDataBytes();
-                                        legacyStats.cacheSize = stats.getCacheBytes();
                                         try {
-                                            mStatsObserver.onGetStatsCompleted(legacyStats, true);
-                                        } catch (RemoteException ignored) {
+                                            final StorageStats stats = mStats.queryStatsForPackage(
+                                                    mCurComputingSizeUuid, mCurComputingSizePkg,
+                                                    UserHandle.of(mCurComputingSizeUserId));
+                                            final PackageStats legacyStats = new PackageStats(
+                                                    mCurComputingSizePkg, mCurComputingSizeUserId);
+                                            legacyStats.codeSize = stats.getCodeBytes();
+                                            legacyStats.dataSize = stats.getDataBytes();
+                                            legacyStats.cacheSize = stats.getCacheBytes();
+                                            try {
+                                                mStatsObserver.onGetStatsCompleted(legacyStats, true);
+                                            } catch (RemoteException ignored) {
+                                            }
+                                        } catch (IllegalStateException e) {
+                                            Log.e(TAG,"An exception occurred while fetching app size", e);
+                                            try {
+                                                mStatsObserver.onGetStatsCompleted(null, false);
+                                            } catch (RemoteException ignored) {
+                                            }
                                         }
+
                                     });
                                 }
                                 if (DEBUG_LOCKING) Log.v(TAG, "MSG_LOAD_SIZES releasing: now computing");
@@ -1493,7 +1502,8 @@
 
         @Override
         public boolean filterApp(AppEntry entry) {
-            return (entry.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
+            return !AppUtils.isInstant(entry.info)
+                && (entry.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
         }
     };
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
index 61ca13d..9d6505b 100755
--- a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
@@ -40,9 +40,15 @@
     public static final String TAG = BatteryMeterDrawableBase.class.getSimpleName();
 
     protected final Context mContext;
+    protected final Paint mFramePaint;
+    protected final Paint mBatteryPaint;
+    protected final Paint mWarningTextPaint;
+    protected final Paint mTextPaint;
+    protected final Paint mBoltPaint;
+    protected final Paint mPlusPaint;
 
     private int mLevel = -1;
-    private boolean mPluggedIn;
+    private boolean mCharging;
     private boolean mPowerSaveEnabled;
     private boolean mShowPercent;
 
@@ -59,8 +65,6 @@
     private float mButtonHeightFraction;
     private float mSubpixelSmoothingLeft;
     private float mSubpixelSmoothingRight;
-    private final Paint mFramePaint, mBatteryPaint, mWarningTextPaint, mTextPaint, mBoltPaint,
-            mPlusPaint;
     private float mTextHeight, mWarningTextHeight;
     private int mIconTint = Color.WHITE;
     private float mOldDarkIntensity = -1f;
@@ -180,16 +184,24 @@
         postInvalidate();
     }
 
-    public void setPluggedIn(boolean val) {
-        mPluggedIn = val;
+    public void setCharging(boolean val) {
+        mCharging = val;
         postInvalidate();
     }
 
+    public boolean getCharging() {
+        return mCharging;
+    }
+
     public void setBatteryLevel(int val) {
         mLevel = val;
         postInvalidate();
     }
 
+    public int getBatteryLevel() {
+        return mLevel;
+    }
+
     public void setPowerSave(boolean val) {
         mPowerSaveEnabled = val;
         postInvalidate();
@@ -314,7 +326,7 @@
         mFrame.bottom -= mSubpixelSmoothingRight;
 
         // set the battery charging color
-        mBatteryPaint.setColor(mPluggedIn ? mChargeColor : getColorForLevel(level));
+        mBatteryPaint.setColor(mCharging ? mChargeColor : getColorForLevel(level));
 
         if (level >= FULL) {
             drawFrac = 1f;
@@ -337,7 +349,7 @@
         mShapePath.lineTo(mButtonFrame.left, mFrame.top);
         mShapePath.lineTo(mButtonFrame.left, mButtonFrame.top);
 
-        if (mPluggedIn) {
+        if (mCharging) {
             // define the bolt shape
             final float bl = mFrame.left + mFrame.width() / 4f;
             final float bt = mFrame.top + mFrame.height() / 6f;
@@ -408,7 +420,7 @@
         boolean pctOpaque = false;
         float pctX = 0, pctY = 0;
         String pctText = null;
-        if (!mPluggedIn && !mPowerSaveEnabled && level > mCriticalLevel && mShowPercent) {
+        if (!mCharging && !mPowerSaveEnabled && level > mCriticalLevel && mShowPercent) {
             mTextPaint.setColor(getColorForLevel(level));
             mTextPaint.setTextSize(height *
                     (SINGLE_DIGIT_PERCENT ? 0.75f
@@ -436,7 +448,7 @@
         mShapePath.op(mClipPath, Path.Op.INTERSECT);
         c.drawPath(mShapePath, mBatteryPaint);
 
-        if (!mPluggedIn && !mPowerSaveEnabled) {
+        if (!mCharging && !mPowerSaveEnabled) {
             if (level <= mCriticalLevel) {
                 // draw the warning text
                 final float x = mWidth * 0.5f;
@@ -467,4 +479,8 @@
     public int getOpacity() {
         return 0;
     }
+
+    public int getCriticalLevel() {
+        return mCriticalLevel;
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java b/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java
index c6a45bc..e2c05a1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java
@@ -35,15 +35,15 @@
     public UsageView(Context context, AttributeSet attrs) {
         super(context, attrs);
         LayoutInflater.from(context).inflate(R.layout.usage_view, this);
-        mUsageGraph = (UsageGraph) findViewById(R.id.usage_graph);
+        mUsageGraph = findViewById(R.id.usage_graph);
         mLabels = new TextView[] {
-                (TextView) findViewById(R.id.label_bottom),
-                (TextView) findViewById(R.id.label_middle),
-                (TextView) findViewById(R.id.label_top),
+                findViewById(R.id.label_bottom),
+                findViewById(R.id.label_middle),
+                findViewById(R.id.label_top),
         };
         mBottomLabels = new TextView[] {
-                (TextView) findViewById(R.id.label_start),
-                (TextView) findViewById(R.id.label_end),
+                findViewById(R.id.label_start),
+                findViewById(R.id.label_end),
         };
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.UsageView, 0, 0);
         if (a.hasValue(R.styleable.UsageView_sideLabels)) {
@@ -64,15 +64,15 @@
         if (a.hasValue(R.styleable.UsageView_android_gravity)) {
             int gravity = a.getInt(R.styleable.UsageView_android_gravity, 0);
             if (gravity == Gravity.END) {
-                LinearLayout layout = (LinearLayout) findViewById(R.id.graph_label_group);
-                LinearLayout labels = (LinearLayout) findViewById(R.id.label_group);
+                LinearLayout layout = findViewById(R.id.graph_label_group);
+                LinearLayout labels = findViewById(R.id.label_group);
                 // Swap the children order.
                 layout.removeView(labels);
                 layout.addView(labels);
                 // Set gravity.
                 labels.setGravity(Gravity.END);
                 // Swap the bottom space order.
-                LinearLayout bottomLabels = (LinearLayout) findViewById(R.id.bottom_label_group);
+                LinearLayout bottomLabels = findViewById(R.id.bottom_label_group);
                 View bottomSpace = bottomLabels.findViewById(R.id.bottom_label_space);
                 bottomLabels.removeView(bottomSpace);
                 bottomLabels.addView(bottomSpace);
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java
index c680b2a..fed18fa 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java
@@ -201,6 +201,22 @@
     }
 
     @Test
+    public void testFilterWithDomainUrls() {
+        mEntry.info.privateFlags |= ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS;
+        // should included updated system apps
+        when(mEntry.info.isInstantApp()).thenReturn(false);
+        assertThat(ApplicationsState.FILTER_WITH_DOMAIN_URLS.filterApp(mEntry))
+                .isTrue();
+        mEntry.info.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS;
+        assertThat(ApplicationsState.FILTER_WITH_DOMAIN_URLS.filterApp(mEntry))
+                .isFalse();
+        mEntry.info.privateFlags |= ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS;
+        when(mEntry.info.isInstantApp()).thenReturn(true);
+        assertThat(ApplicationsState.FILTER_WITH_DOMAIN_URLS.filterApp(mEntry))
+                .isFalse();
+    }
+
+    @Test
     public void testDisabledFilterRejectsInstantApp() {
         mEntry.info.enabled = false;
         assertThat(ApplicationsState.FILTER_DISABLED.filterApp(mEntry)).isTrue();
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
index 4de2c12..83667ea 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
@@ -55,12 +55,12 @@
         final int levels[] = { 0, 1, 5, 10, 25, 50, 75, 90, 95, 99, 100 };
         final boolean bools[] = { false, true };
         for (int l : levels) {
-            for (boolean plugged : bools) {
+            for (boolean charging : bools) {
                 for (boolean saver : bools) {
                     for (boolean percent : bools) {
                         mBatteryDrawable.setBatteryLevel(l);
                         mBatteryDrawable.setPowerSave(saver);
-                        mBatteryDrawable.setPluggedIn(plugged);
+                        mBatteryDrawable.setCharging(charging);
                         mBatteryDrawable.setShowPercent(percent);
                         mBatteryDrawable.draw(canvas);
                     }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/BatteryInfoTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/BatteryInfoTest.java
index 962c4e7..69efc9e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/BatteryInfoTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/BatteryInfoTest.java
@@ -32,6 +32,7 @@
 import org.robolectric.annotation.Config;
 
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.eq;
@@ -44,10 +45,12 @@
     private static final String STATUS_FULL = "Full";
     private static final String STATUS_CHARGING_NO_TIME = "Charging";
     private static final String STATUS_CHARGING_TIME = "Charging - 2h left";
+    private static final int PLUGGED_IN = 1;
     private static final long REMAINING_TIME_NULL = -1;
     private static final long REMAINING_TIME = 2;
     private Intent mDisChargingBatteryBroadcast;
     private Intent mChargingBatteryBroadcast;
+
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private BatteryStats mBatteryStats;
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
@@ -95,7 +98,7 @@
         BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
                 mBatteryStats, SystemClock.elapsedRealtime() * 1000, false);
 
-        assertThat(info.mChargeLabelString).isEqualTo(STATUS_CHARGING_TIME);
+        assertThat(info.chargeLabelString).isEqualTo(STATUS_CHARGING_TIME);
     }
 
     @Test
@@ -104,6 +107,14 @@
         BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
                 mBatteryStats, SystemClock.elapsedRealtime() * 1000, false);
 
-        assertThat(info.mChargeLabelString).isEqualTo(STATUS_CHARGING_NO_TIME);
+        assertThat(info.chargeLabelString).isEqualTo(STATUS_CHARGING_NO_TIME);
+    }
+
+    @Test
+    public void testGetBatteryInfo_pluggedIn_dischargingFalse() {
+        BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
+                mBatteryStats, SystemClock.elapsedRealtime() * 1000, true);
+
+        assertThat(info.discharging).isEqualTo(false);
     }
 }
diff --git a/packages/SystemUI/res/drawable-hdpi/pip_dismiss_scrim.9.png b/packages/SystemUI/res/drawable-hdpi/pip_dismiss_scrim.9.png
index 6737c80..32f1ed7 100644
--- a/packages/SystemUI/res/drawable-hdpi/pip_dismiss_scrim.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/pip_dismiss_scrim.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/pip_dismiss_scrim.9.png b/packages/SystemUI/res/drawable-mdpi/pip_dismiss_scrim.9.png
index d9e33eb..33826a6 100644
--- a/packages/SystemUI/res/drawable-mdpi/pip_dismiss_scrim.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/pip_dismiss_scrim.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/pip_dismiss_scrim.9.png b/packages/SystemUI/res/drawable-xhdpi/pip_dismiss_scrim.9.png
index 64daf20..c1157f4 100644
--- a/packages/SystemUI/res/drawable-xhdpi/pip_dismiss_scrim.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/pip_dismiss_scrim.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/pip_dismiss_scrim.9.png b/packages/SystemUI/res/drawable-xxhdpi/pip_dismiss_scrim.9.png
index 49e0499..8d58a7e 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/pip_dismiss_scrim.9.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/pip_dismiss_scrim.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/pip_dismiss_scrim.9.png b/packages/SystemUI/res/drawable-xxxhdpi/pip_dismiss_scrim.9.png
index 0e6ca16..6c04d1a 100644
--- a/packages/SystemUI/res/drawable-xxxhdpi/pip_dismiss_scrim.9.png
+++ b/packages/SystemUI/res/drawable-xxxhdpi/pip_dismiss_scrim.9.png
Binary files differ
diff --git a/packages/SystemUI/res/layout/pip_dismiss_view.xml b/packages/SystemUI/res/layout/pip_dismiss_view.xml
index 34228d9..058f59f 100644
--- a/packages/SystemUI/res/layout/pip_dismiss_view.xml
+++ b/packages/SystemUI/res/layout/pip_dismiss_view.xml
@@ -27,6 +27,10 @@
         android:layout_gravity="bottom|center_horizontal"
         android:text="@string/pip_phone_dismiss_hint"
         android:textColor="#FFFFFFFF"
-        android:textSize="14sp" />
+        android:textSize="14sp"
+        android:shadowColor="@android:color/black"
+        android:shadowDx="-2"
+        android:shadowDy="2"
+        android:shadowRadius="0.01" />
 
 </FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 6837340..6d8a077 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -738,7 +738,7 @@
     <dimen name="pip_dismiss_gradient_height">196dp</dimen>
 
     <!-- The bottom margin of the PIP drag to dismiss info text shown when moving a PIP. -->
-    <dimen name="pip_dismiss_text_bottom_margin">36dp</dimen>
+    <dimen name="pip_dismiss_text_bottom_margin">24dp</dimen>
 
     <!-- The shortest-edge size of the expanded PiP. -->
     <dimen name="pip_expanded_shortest_edge_size">160dp</dimen>
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java b/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java
index 0a89d9b..e98ef06 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java
@@ -37,8 +37,8 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mCarrierText = (CarrierText) findViewById(R.id.carrier_text);
-        mEmergencyButton = (EmergencyButton) findViewById(R.id.emergency_call_button);
+        mCarrierText = findViewById(R.id.carrier_text);
+        mEmergencyButton = findViewById(R.id.emergency_call_button);
 
         // The emergency button overlaps the carrier text, only noticeable when highlighted.
         // So temporarily hide the carrier text while the emergency button is pressed.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index 5aa673b..abc3b94 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -98,7 +98,7 @@
         mSecurityMessageDisplay = KeyguardMessageArea.findSecurityMessageDisplay(this);
         mEcaView = findViewById(R.id.keyguard_selector_fade_container);
 
-        EmergencyButton button = (EmergencyButton) findViewById(R.id.emergency_call_button);
+        EmergencyButton button = findViewById(R.id.emergency_call_button);
         if (button != null) {
             button.setCallback(this);
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
index dd5544d..27a3f7d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
@@ -143,7 +143,7 @@
     @Override
     protected void onFinishInflate() {
         mSecurityContainer =
-                (KeyguardSecurityContainer) findViewById(R.id.keyguard_security_container);
+                findViewById(R.id.keyguard_security_container);
         mLockPatternUtils = new LockPatternUtils(mContext);
         mSecurityContainer.setLockPatternUtils(mLockPatternUtils);
         mSecurityContainer.setSecurityCallback(this);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
index 590d8d5..c1cff9e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -79,11 +79,11 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
 
-        mContainer = (ViewGroup) findViewById(R.id.container);
-        mRow0 = (ViewGroup) findViewById(R.id.row0);
-        mRow1 = (ViewGroup) findViewById(R.id.row1);
-        mRow2 = (ViewGroup) findViewById(R.id.row2);
-        mRow3 = (ViewGroup) findViewById(R.id.row3);
+        mContainer = findViewById(R.id.container);
+        mRow0 = findViewById(R.id.row0);
+        mRow1 = findViewById(R.id.row1);
+        mRow2 = findViewById(R.id.row2);
+        mRow3 = findViewById(R.id.row3);
         mDivider = findViewById(R.id.divider);
         mViews = new View[][]{
                 new View[]{
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index d49ff97..b6184a8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -174,7 +174,7 @@
         mImm = (InputMethodManager) getContext().getSystemService(
                 Context.INPUT_METHOD_SERVICE);
 
-        mPasswordEntry = (TextView) findViewById(getPasswordTextViewId());
+        mPasswordEntry = findViewById(getPasswordTextViewId());
         mPasswordEntryDisabler = new TextViewInputDisabler(mPasswordEntry);
         mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
         mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index c2b57ff..3c9a6b9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -140,7 +140,7 @@
         mLockPatternUtils = mLockPatternUtils == null
                 ? new LockPatternUtils(mContext) : mLockPatternUtils;
 
-        mLockPatternView = (LockPatternView) findViewById(R.id.lockPatternView);
+        mLockPatternView = findViewById(R.id.lockPatternView);
         mLockPatternView.setSaveEnabled(false);
         mLockPatternView.setOnPatternListener(new UnlockPatternListener());
 
@@ -150,9 +150,9 @@
         mSecurityMessageDisplay =
                 (KeyguardMessageArea) KeyguardMessageArea.findSecurityMessageDisplay(this);
         mEcaView = findViewById(R.id.keyguard_selector_fade_container);
-        mContainer = (ViewGroup) findViewById(R.id.container);
+        mContainer = findViewById(R.id.container);
 
-        EmergencyButton button = (EmergencyButton) findViewById(R.id.emergency_call_button);
+        EmergencyButton button = findViewById(R.id.emergency_call_button);
         if (button != null) {
             button.setCallback(this);
         }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
index 108b466..c04ae68 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -171,7 +171,7 @@
 
     @Override
     protected void onFinishInflate() {
-        mPasswordEntry = (PasswordTextView) findViewById(getPasswordTextViewId());
+        mPasswordEntry = findViewById(getPasswordTextViewId());
         mPasswordEntry.setOnKeyListener(this);
 
         // Set selected property on so the view can send accessibility events.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 8cdb906..b447979 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -160,7 +160,7 @@
     }
 
     protected void onFinishInflate() {
-        mSecurityViewFlipper = (KeyguardSecurityViewFlipper) findViewById(R.id.view_flipper);
+        mSecurityViewFlipper = findViewById(R.id.view_flipper);
         mSecurityViewFlipper.setLockPatternUtils(mLockPatternUtils);
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
index 839d3ce..0cf8900 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
@@ -144,7 +144,7 @@
         if (mEcaView instanceof EmergencyCarrierArea) {
             ((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true);
         }
-        mSimImageView = (ImageView) findViewById(R.id.keyguard_sim);
+        mSimImageView = findViewById(R.id.keyguard_sim);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
index 3871448..fb3cee7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
@@ -187,7 +187,7 @@
         if (mEcaView instanceof EmergencyCarrierArea) {
             ((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true);
         }
-        mSimImageView = (ImageView) findViewById(R.id.keyguard_sim);
+        mSimImageView = findViewById(R.id.keyguard_sim);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index b2b0ee4..162faa5 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -115,14 +115,14 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mClockContainer = (ViewGroup) findViewById(R.id.keyguard_clock_container);
-        mAlarmStatusView = (TextView) findViewById(R.id.alarm_status);
-        mDateView = (TextClock) findViewById(R.id.date_view);
-        mClockView = (TextClock) findViewById(R.id.clock_view);
+        mClockContainer = findViewById(R.id.keyguard_clock_container);
+        mAlarmStatusView = findViewById(R.id.alarm_status);
+        mDateView = findViewById(R.id.date_view);
+        mClockView = findViewById(R.id.clock_view);
         mDateView.setShowCurrentUserTime(true);
         mClockView.setShowCurrentUserTime(true);
-        mOwnerInfo = (TextView) findViewById(R.id.owner_info);
-        mBatteryDoze = (ChargingView) findViewById(R.id.battery_doze);
+        mOwnerInfo = findViewById(R.id.owner_info);
+        mBatteryDoze = findViewById(R.id.battery_doze);
         mVisibleInDoze = new View[]{mBatteryDoze, mClockView};
 
         boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index d57e88c..911ef24 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -149,7 +149,7 @@
     @Override
     public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
         mDrawable.setBatteryLevel(level);
-        mDrawable.setPluggedIn(pluggedIn);
+        mDrawable.setCharging(pluggedIn);
         mLevel = level;
         updatePercentText();
         setContentDescription(
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 0b0ea720..7fed3e8 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -31,6 +31,7 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.FlingAnimationUtils;
@@ -130,6 +131,11 @@
         }
     };
 
+    @VisibleForTesting
+    ObjectAnimator getScaleAnimation() {
+        return mScaleAnimation;
+    }
+
     private class ViewScaler {
         ExpandableView mView;
 
@@ -176,7 +182,8 @@
         mFlingAnimationUtils = new FlingAnimationUtils(context, EXPAND_DURATION);
     }
 
-    private void updateExpansion() {
+    @VisibleForTesting
+    void updateExpansion() {
         if (DEBUG_SCALE) Log.v(TAG, "updateExpansion()");
         // are we scaling or dragging?
         float span = mSGD.getCurrentSpan() - mInitialTouchSpan;
@@ -500,7 +507,8 @@
     /**
      * @return True if the view is expandable, false otherwise.
      */
-    private boolean startExpanding(ExpandableView v, int expandType) {
+    @VisibleForTesting
+    boolean startExpanding(ExpandableView v, int expandType) {
         if (!(v instanceof ExpandableNotificationRow)) {
             return false;
         }
@@ -535,7 +543,8 @@
      *                   state
      * @param velocity the velocity this was expanded/ collapsed with
      */
-    private void finishExpanding(boolean forceAbort, float velocity) {
+    @VisibleForTesting
+    void finishExpanding(boolean forceAbort, float velocity) {
         if (!mExpanding) return;
 
         if (DEBUG) Log.d(TAG, "scale in finishing on view: " + mResizedView);
@@ -571,7 +580,9 @@
                 public void onAnimationEnd(Animator animation) {
                     if (!mCancelled) {
                         mCallback.setUserExpandedChild(scaledView, expand);
-                        mScaler.setView(null);
+                        if (!mExpanding) {
+                            mScaler.setView(null);
+                        }
                     } else {
                         mCallback.setExpansionCancelled(scaledView);
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistOrbView.java b/packages/SystemUI/src/com/android/systemui/assist/AssistOrbView.java
index abcf27d..1d032e8 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistOrbView.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistOrbView.java
@@ -137,7 +137,7 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mLogo = (ImageView) findViewById(R.id.search_logo);
+        mLogo = findViewById(R.id.search_logo);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/egg/MLandActivity.java b/packages/SystemUI/src/com/android/systemui/egg/MLandActivity.java
index cdda45f..f06ea45 100644
--- a/packages/SystemUI/src/com/android/systemui/egg/MLandActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/egg/MLandActivity.java
@@ -30,8 +30,8 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.mland);
-        mLand = (MLand) findViewById(R.id.world);
-        mLand.setScoreFieldHolder((ViewGroup) findViewById(R.id.scores));
+        mLand = findViewById(R.id.world);
+        mLand.setScoreFieldHolder(findViewById(R.id.scores));
         final View welcome = findViewById(R.id.welcome);
         mLand.setSplash(welcome);
         final int numControllers = mLand.getGameControllers().size();
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
index 2b6ea15..4b0ff14 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
@@ -157,7 +157,7 @@
         // TODO: Do something?
     }
 
-    private View findViewById(int id) {
+    private <T extends View> T findViewById(int id) {
         return mRootView.findViewById(id);
     }
 
@@ -245,7 +245,7 @@
 
         @Override
         @Nullable
-        public View onFindViewById(int id) {
+        public <T extends View> T onFindViewById(int id) {
             return FragmentHostManager.this.findViewById(id);
         }
 
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 114a594..c565373 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -86,6 +86,7 @@
 
             ComponentName topPipActivity = PipUtils.getTopPinnedActivity(mContext,
                     mActivityManager);
+            mMenuController.hideMenu();
             mNotificationController.onActivityUnpinned(topPipActivity);
 
             SystemServicesProxy.getInstance(mContext).setPipVisibility(topPipActivity != null);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index c06e56a..9c4f16b 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -188,10 +188,10 @@
         mDismissButton.setOnClickListener((v) -> {
             dismissPip();
         });
-        mActionsGroup = (LinearLayout) findViewById(R.id.actions_group);
+        mActionsGroup = findViewById(R.id.actions_group);
         mBetweenActionPaddingLand = getResources().getDimensionPixelSize(
                 R.dimen.pip_between_action_padding_land);
-        mExpandButton = (ImageView) findViewById(R.id.expand_button);
+        mExpandButton = findViewById(R.id.expand_button);
 
         updateFromIntent(getIntent());
         setTitle(R.string.pip_menu_title);
@@ -392,8 +392,8 @@
     }
 
     private void updateActionViews(Rect stackBounds) {
-        ViewGroup expandContainer = (ViewGroup) findViewById(R.id.expand_container);
-        ViewGroup actionsContainer = (ViewGroup) findViewById(R.id.actions_container);
+        ViewGroup expandContainer = findViewById(R.id.expand_container);
+        ViewGroup actionsContainer = findViewById(R.id.actions_container);
         actionsContainer.setOnTouchListener((v, ev) -> {
             // Do nothing, prevent click through to parent
             return true;
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 c3c09a0..3f26fdd 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -662,6 +662,7 @@
                 mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
                         mMovementBounds, true /* allowMenuTimeout */);
             } else {
+                mMenuController.hideMenu();
                 mMotionHelper.expandPip();
             }
             return true;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlButtonView.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlButtonView.java
index 59cb086..40a63d7 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlButtonView.java
@@ -77,9 +77,9 @@
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         inflater.inflate(R.layout.tv_pip_control_button, this);
 
-        mIconImageView = (ImageView) findViewById(R.id.icon);
-        mButtonImageView = (ImageView) findViewById(R.id.button);
-        mDescriptionTextView = (TextView) findViewById(R.id.desc);
+        mIconImageView = findViewById(R.id.icon);
+        mButtonImageView = findViewById(R.id.button);
+        mDescriptionTextView = findViewById(R.id.desc);
 
         int[] values = new int[] {android.R.attr.src, android.R.attr.text};
         TypedArray typedArray =
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java
index a2aff2d..4c81907 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipControlsView.java
@@ -107,7 +107,7 @@
     public void onFinishInflate() {
         super.onFinishInflate();
 
-        mFullButtonView = (PipControlButtonView) findViewById(R.id.full_button);
+        mFullButtonView = findViewById(R.id.full_button);
         mFullButtonView.setOnFocusChangeListener(mFocusChangeListener);
         mFullButtonView.setOnClickListener(new View.OnClickListener() {
             @Override
@@ -116,7 +116,7 @@
             }
         });
 
-        mCloseButtonView = (PipControlButtonView) findViewById(R.id.close_button);
+        mCloseButtonView = findViewById(R.id.close_button);
         mCloseButtonView.setOnFocusChangeListener(mFocusChangeListener);
         mCloseButtonView.setOnClickListener(new View.OnClickListener() {
             @Override
@@ -128,7 +128,7 @@
             }
         });
 
-        mPlayPauseButtonView = (PipControlButtonView) findViewById(R.id.play_pause_button);
+        mPlayPauseButtonView = findViewById(R.id.play_pause_button);
         mPlayPauseButtonView.setOnFocusChangeListener(mFocusChangeListener);
         mPlayPauseButtonView.setOnClickListener(new View.OnClickListener() {
             @Override
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
index 01d86b6..9945079 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java
@@ -44,7 +44,7 @@
         mPipManager.addListener(this);
 
         mRestorePipSizeWhenClose = true;
-        mPipControlsView = (PipControlsView) findViewById(R.id.pip_controls);
+        mPipControlsView = findViewById(R.id.pip_controls);
         mFadeInAnimation = AnimatorInflater.loadAnimator(
                 this, R.anim.tv_pip_menu_fade_in_animation);
         mFadeInAnimation.setTarget(mPipControlsView);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipOnboardingActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipOnboardingActivity.java
index 57952f4..423530a 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipOnboardingActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipOnboardingActivity.java
@@ -65,7 +65,7 @@
         mEnterAnimator.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationStart(Animator animation) {
-                ImageView button = (ImageView) findViewById(R.id.remote_button);
+                ImageView button = findViewById(R.id.remote_button);
                 ((AnimationDrawable) button.getDrawable()).start();
             }
         });
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index d2a2919..f124e86 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -92,14 +92,14 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mDetailContent = (ViewGroup) findViewById(android.R.id.content);
-        mDetailSettingsButton = (TextView) findViewById(android.R.id.button2);
-        mDetailDoneButton = (TextView) findViewById(android.R.id.button1);
+        mDetailContent = findViewById(android.R.id.content);
+        mDetailSettingsButton = findViewById(android.R.id.button2);
+        mDetailDoneButton = findViewById(android.R.id.button1);
 
         mQsDetailHeader = findViewById(R.id.qs_detail_header);
         mQsDetailHeaderTitle = (TextView) mQsDetailHeader.findViewById(android.R.id.title);
         mQsDetailHeaderSwitch = (Switch) mQsDetailHeader.findViewById(android.R.id.toggle);
-        mQsDetailHeaderProgress = (ImageView) findViewById(R.id.qs_detail_header_progress);
+        mQsDetailHeaderProgress = findViewById(R.id.qs_detail_header_progress);
 
         updateDetailText();
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java
index efc0668..f91aa9a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java
@@ -76,7 +76,7 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mItemList = (AutoSizingList) findViewById(android.R.id.list);
+        mItemList = findViewById(android.R.id.list);
         mItemList.setVisibility(GONE);
         mItemList.setAdapter(mAdapter);
         mEmpty = findViewById(android.R.id.empty);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 596d3bc..30053e3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -82,7 +82,7 @@
 
         LayoutInflater.from(getContext()).inflate(R.layout.qs_customize_panel_content, this);
 
-        mToolbar = (Toolbar) findViewById(com.android.internal.R.id.action_bar);
+        mToolbar = findViewById(com.android.internal.R.id.action_bar);
         TypedValue value = new TypedValue();
         mContext.getTheme().resolveAttribute(android.R.attr.homeAsUpIndicator, value, true);
         mToolbar.setNavigationIcon(
@@ -98,7 +98,7 @@
                 mContext.getString(com.android.internal.R.string.reset));
         mToolbar.setTitle(R.string.qs_edit);
 
-        mRecyclerView = (RecyclerView) findViewById(android.R.id.list);
+        mRecyclerView = findViewById(android.R.id.list);
         mTileAdapter = new TileAdapter(getContext());
         mRecyclerView.setAdapter(mTileAdapter);
         mTileAdapter.getItemTouchHelper().attachToRecyclerView(mRecyclerView);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index 8209ee2..ecc275d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -181,7 +181,7 @@
                 return;
             }
             mDrawable.setBatteryLevel(100);
-            mDrawable.setPluggedIn(false);
+            mDrawable.setCharging(false);
             mDrawable.setPowerSave(true);
             mDrawable.setShowPercent(false);
             ((ImageView) mCurrentView.findViewById(android.R.id.icon)).setImageDrawable(mDrawable);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
index 9cd79f8..7224ae6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataUsageDetailView.java
@@ -98,21 +98,21 @@
             usageColor = Utils.getColorAccent(mContext);
         }
 
-        final TextView title = (TextView) findViewById(android.R.id.title);
+        final TextView title = findViewById(android.R.id.title);
         title.setText(titleId);
-        final TextView usage = (TextView) findViewById(R.id.usage_text);
+        final TextView usage = findViewById(R.id.usage_text);
         usage.setText(formatBytes(bytes));
         usage.setTextColor(usageColor);
-        final DataUsageGraph graph = (DataUsageGraph) findViewById(R.id.usage_graph);
+        final DataUsageGraph graph = findViewById(R.id.usage_graph);
         graph.setLevels(info.limitLevel, info.warningLevel, info.usageLevel);
-        final TextView carrier = (TextView) findViewById(R.id.usage_carrier_text);
+        final TextView carrier = findViewById(R.id.usage_carrier_text);
         carrier.setText(info.carrier);
-        final TextView period = (TextView) findViewById(R.id.usage_period_text);
+        final TextView period = findViewById(R.id.usage_period_text);
         period.setText(info.period);
-        final TextView infoTop = (TextView) findViewById(R.id.usage_info_top_text);
+        final TextView infoTop = findViewById(R.id.usage_info_top_text);
         infoTop.setVisibility(top != null ? View.VISIBLE : View.GONE);
         infoTop.setText(top);
-        final TextView infoBottom = (TextView) findViewById(R.id.usage_info_bottom_text);
+        final TextView infoBottom = findViewById(R.id.usage_info_bottom_text);
         infoBottom.setVisibility(bottom != null ? View.VISIBLE : View.GONE);
         infoBottom.setText(bottom);
         boolean showLevel = info.warningLevel > 0 || info.limitLevel > 0;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
index c485a9e..1e9a618 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailItemView.java
@@ -117,8 +117,8 @@
 
     @Override
     protected void onFinishInflate() {
-        mAvatar = (UserAvatarView) findViewById(R.id.user_picture);
-        mName = (TextView) findViewById(R.id.user_name);
+        mAvatar = findViewById(R.id.user_picture);
+        mName = findViewById(R.id.user_name);
         if (mRegularTypeface == null) {
             mRegularTypeface = mName.getTypeface();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index f0a9bc3..143d934 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -325,7 +325,7 @@
         // Set the Recents layout
         setContentView(R.layout.recents);
         takeKeyEvents(true);
-        mRecentsView = (RecentsView) findViewById(R.id.recents_view);
+        mRecentsView = findViewById(R.id.recents_view);
         mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
                 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                 View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index b8be580..e34987b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -222,8 +222,8 @@
     @Override
     protected void onFinishInflate() {
         // Bind the views
-        mHeaderView = (TaskViewHeader) findViewById(R.id.task_view_bar);
-        mThumbnailView = (TaskViewThumbnail) findViewById(R.id.task_view_thumbnail);
+        mHeaderView = findViewById(R.id.task_view_bar);
+        mThumbnailView = findViewById(R.id.task_view_thumbnail);
         mThumbnailView.updateClipToTaskBar(mHeaderView);
         mActionButtonView = findViewById(R.id.lock_to_app_fab);
         mActionButtonView.setOutlineProvider(new ViewOutlineProvider() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index 311f8ff..ae922fc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -244,12 +244,12 @@
         SystemServicesProxy ssp = Recents.getSystemServices();
 
         // Initialize the icon and description views
-        mIconView = (ImageView) findViewById(R.id.icon);
+        mIconView = findViewById(R.id.icon);
         mIconView.setOnLongClickListener(this);
-        mTitleView = (TextView) findViewById(R.id.title);
-        mDismissButton = (ImageView) findViewById(R.id.dismiss_task);
+        mTitleView = findViewById(R.id.title);
+        mDismissButton = findViewById(R.id.dismiss_task);
         if (ssp.hasFreeformWorkspaceSupport()) {
-            mMoveTaskButton = (ImageView) findViewById(R.id.move_task);
+            mMoveTaskButton = findViewById(R.id.move_task);
         }
 
         onConfigurationChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
index 7d847a3..6918a63 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
@@ -54,8 +54,8 @@
                 R.layout.quick_settings_brightness_dialog, null);
         setContentView(v);
 
-        final ImageView icon = (ImageView) findViewById(R.id.brightness_icon);
-        final ToggleSliderView slider = (ToggleSliderView) findViewById(R.id.brightness_slider);
+        final ImageView icon = findViewById(R.id.brightness_icon);
+        final ToggleSliderView slider = findViewById(R.id.brightness_slider);
         mBrightnessController = new BrightnessController(this, icon, slider);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSliderView.java b/packages/SystemUI/src/com/android/systemui/settings/ToggleSliderView.java
index afe89ec..5b234e9 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSliderView.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/ToggleSliderView.java
@@ -60,13 +60,13 @@
         final TypedArray a = context.obtainStyledAttributes(
                 attrs, R.styleable.ToggleSliderView, defStyle, 0);
 
-        mToggle = (CompoundButton) findViewById(R.id.toggle);
+        mToggle = findViewById(R.id.toggle);
         mToggle.setOnCheckedChangeListener(mCheckListener);
 
-        mSlider = (ToggleSeekBar) findViewById(R.id.slider);
+        mSlider = findViewById(R.id.slider);
         mSlider.setOnSeekBarChangeListener(mSeekListener);
 
-        mLabel = (TextView) findViewById(R.id.label);
+        mLabel = findViewById(R.id.label);
         mLabel.setText(a.getString(R.styleable.ToggleSliderView_text));
 
         mSlider.setAccessibilityLabel(getContentDescription().toString());
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index c48ecdb..da56e62 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -269,9 +269,9 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mHandle = (DividerHandleView) findViewById(R.id.docked_divider_handle);
+        mHandle = findViewById(R.id.docked_divider_handle);
         mBackground = findViewById(R.id.docked_divider_background);
-        mMinimizedShadow = (MinimizedDockShadow) findViewById(R.id.minimized_dock_shadow);
+        mMinimizedShadow = findViewById(R.id.minimized_dock_shadow);
         mHandle.setOnTouchListener(this);
         mDividerWindowWidth = getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.docked_stack_divider_thickness);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index d4997ea..469f3ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -203,10 +203,10 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mBackgroundNormal = (NotificationBackgroundView) findViewById(R.id.backgroundNormal);
-        mFakeShadow = (FakeShadowView) findViewById(R.id.fake_shadow);
+        mBackgroundNormal = findViewById(R.id.backgroundNormal);
+        mFakeShadow = findViewById(R.id.fake_shadow);
         mShadowHidden = mFakeShadow.getVisibility() != VISIBLE;
-        mBackgroundDimmed = (NotificationBackgroundView) findViewById(R.id.backgroundDimmed);
+        mBackgroundDimmed = findViewById(R.id.backgroundDimmed);
         mBackgroundNormal.setCustomBackground(R.drawable.notification_material_bg);
         mBackgroundDimmed.setCustomBackground(R.drawable.notification_material_bg_dim);
         updateBackground();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutAppItemLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutAppItemLayout.java
index 507b665..5377dee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutAppItemLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutAppItemLayout.java
@@ -44,8 +44,8 @@
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
-            ImageView shortcutIcon = (ImageView) findViewById(R.id.keyboard_shortcuts_icon);
-            TextView shortcutKeyword = (TextView) findViewById(R.id.keyboard_shortcuts_keyword);
+            ImageView shortcutIcon = findViewById(R.id.keyboard_shortcuts_icon);
+            TextView shortcutKeyword = findViewById(R.id.keyboard_shortcuts_keyword);
             int totalMeasuredWidth = MeasureSpec.getSize(widthMeasureSpec);
             int totalPadding = getPaddingLeft() + getPaddingRight();
             int availableWidth = totalMeasuredWidth - totalPadding;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index fab4e59..7928575 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -151,7 +151,7 @@
                 pkg, mAppUid, false /* includeDeleted */);
 
         String channelsDescText;
-        mNumChannelsView = (TextView) (findViewById(R.id.num_channels_desc));
+        mNumChannelsView = findViewById(R.id.num_channels_desc);
         if (isSingleDefaultChannel) {
             channelsDescText = mContext.getString(R.string.notification_default_channel_desc);
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 51345c2..b134fc5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -79,7 +79,7 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mShelfIcons = (NotificationIconContainer) findViewById(R.id.content);
+        mShelfIcons = findViewById(R.id.content);
         mShelfIcons.setClipChildren(false);
         mShelfIcons.setClipToPadding(false);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
index 0de3e02..4a3f112 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSnooze.java
@@ -63,9 +63,9 @@
         createOptionViews();
 
         // Snackbar
-        mSelectedOptionText = (TextView) findViewById(R.id.snooze_option_default);
+        mSelectedOptionText = findViewById(R.id.snooze_option_default);
         mSelectedOptionText.setOnClickListener(this);
-        mUndoButton = (TextView) findViewById(R.id.undo);
+        mUndoButton = findViewById(R.id.undo);
         mUndoButton.setOnClickListener(this);
 
         // Default to first option in list
@@ -102,7 +102,7 @@
     }
 
     private void createOptionViews() {
-        mSnoozeOptionView = (ViewGroup) findViewById(R.id.snooze_options);
+        mSnoozeOptionView = findViewById(R.id.snooze_options);
         mSnoozeOptionView.removeAllViews();
         mSnoozeOptionView.setVisibility(View.GONE);
         final Resources res = getResources();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index c5e1438..d5f0e7c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -177,22 +177,22 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
 
-        mVpn            = (ImageView) findViewById(R.id.vpn);
-        mEthernetGroup  = (ViewGroup) findViewById(R.id.ethernet_combo);
-        mEthernet       = (ImageView) findViewById(R.id.ethernet);
-        mEthernetDark   = (ImageView) findViewById(R.id.ethernet_dark);
-        mWifiGroup      = (ViewGroup) findViewById(R.id.wifi_combo);
-        mWifi           = (ImageView) findViewById(R.id.wifi_signal);
-        mWifiDark       = (ImageView) findViewById(R.id.wifi_signal_dark);
-        mWifiActivityIn = (ImageView) findViewById(R.id.wifi_in);
-        mWifiActivityOut= (ImageView) findViewById(R.id.wifi_out);
-        mAirplane       = (ImageView) findViewById(R.id.airplane);
-        mNoSims         = (ImageView) findViewById(R.id.no_sims);
-        mNoSimsDark     = (ImageView) findViewById(R.id.no_sims_dark);
+        mVpn            = findViewById(R.id.vpn);
+        mEthernetGroup  = findViewById(R.id.ethernet_combo);
+        mEthernet       = findViewById(R.id.ethernet);
+        mEthernetDark   = findViewById(R.id.ethernet_dark);
+        mWifiGroup      = findViewById(R.id.wifi_combo);
+        mWifi           = findViewById(R.id.wifi_signal);
+        mWifiDark       = findViewById(R.id.wifi_signal_dark);
+        mWifiActivityIn = findViewById(R.id.wifi_in);
+        mWifiActivityOut= findViewById(R.id.wifi_out);
+        mAirplane       = findViewById(R.id.airplane);
+        mNoSims         = findViewById(R.id.no_sims);
+        mNoSimsDark     = findViewById(R.id.no_sims_dark);
         mNoSimsCombo    =             findViewById(R.id.no_sims_combo);
         mWifiAirplaneSpacer =         findViewById(R.id.wifi_airplane_spacer);
         mWifiSignalSpacer =           findViewById(R.id.wifi_signal_spacer);
-        mMobileSignalGroup = (LinearLayout) findViewById(R.id.mobile_signal_group);
+        mMobileSignalGroup = findViewById(R.id.mobile_signal_group);
 
         maybeScaleVpnAndNoSimsIcons();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
index d530759..6cbbd6c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
@@ -40,8 +40,8 @@
 
     @Override
     public void onFinishInflate() {
-        mNavButtons = (LinearLayout) findViewById(R.id.nav_buttons);
-        mLightsOutButtons = (LinearLayout) findViewById(R.id.lights_out);
+        mNavButtons = findViewById(R.id.nav_buttons);
+        mLightsOutButtons = findViewById(R.id.lights_out);
     }
 
     public void addButton(CarNavigationButton button, CarNavigationButton lightsOutButton){
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
index f46fc67..2de358f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
@@ -41,13 +41,13 @@
     @Override
     public void onFinishInflate() {
         super.onFinishInflate();
-        mIcon = (AlphaOptimizedImageButton) findViewById(R.id.car_nav_button_icon);
+        mIcon = findViewById(R.id.car_nav_button_icon);
         mIcon.setScaleType(ImageView.ScaleType.CENTER);
         mIcon.setClickable(false);
         mIcon.setBackgroundColor(android.R.color.transparent);
         mIcon.setAlpha(UNSELECTED_ALPHA);
 
-        mMoreIcon = (AlphaOptimizedImageButton) findViewById(R.id.car_nav_button_more_icon);
+        mMoreIcon = findViewById(R.id.car_nav_button_more_icon);
         mMoreIcon.setClickable(false);
         mMoreIcon.setBackgroundColor(android.R.color.transparent);
         mMoreIcon.setVisibility(INVISIBLE);
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 9a49d67..41a60e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -227,14 +227,14 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         mLockPatternUtils = new LockPatternUtils(mContext);
-        mPreviewContainer = (ViewGroup) findViewById(R.id.preview_container);
-        mRightAffordanceView = (KeyguardAffordanceView) findViewById(R.id.camera_button);
-        mLeftAffordanceView = (KeyguardAffordanceView) findViewById(R.id.left_button);
-        mLockIcon = (LockIcon) findViewById(R.id.lock_icon);
-        mIndicationArea = (ViewGroup) findViewById(R.id.keyguard_indication_area);
-        mEnterpriseDisclosure = (TextView) findViewById(
+        mPreviewContainer = findViewById(R.id.preview_container);
+        mRightAffordanceView = findViewById(R.id.camera_button);
+        mLeftAffordanceView = findViewById(R.id.left_button);
+        mLockIcon = findViewById(R.id.lock_icon);
+        mIndicationArea = findViewById(R.id.keyguard_indication_area);
+        mEnterpriseDisclosure = findViewById(
                 R.id.keyguard_indication_enterprise_disclosure);
-        mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text);
+        mIndicationText = findViewById(R.id.keyguard_indication_text);
         watchForCameraPolicyChanges();
         updateCameraVisibility();
         mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
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 307a8c7..f1b4498 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -231,9 +231,9 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mKeyguardStatusBar = (KeyguardStatusBarView) findViewById(R.id.keyguard_header);
-        mKeyguardStatusView = (KeyguardStatusView) findViewById(R.id.keyguard_status_view);
-        mClockView = (TextView) findViewById(R.id.clock_view);
+        mKeyguardStatusBar = findViewById(R.id.keyguard_header);
+        mKeyguardStatusView = findViewById(R.id.keyguard_status_view);
+        mClockView = findViewById(R.id.clock_view);
 
         mNotificationContainerParent = (NotificationsQuickSettingsContainer)
                 findViewById(R.id.notification_container_parent);
@@ -242,13 +242,13 @@
         mNotificationStackScroller.setOnHeightChangedListener(this);
         mNotificationStackScroller.setOverscrollTopChangedListener(this);
         mNotificationStackScroller.setOnEmptySpaceClickListener(this);
-        mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area);
+        mKeyguardBottomArea = findViewById(R.id.keyguard_bottom_area);
         mQsNavbarScrim = findViewById(R.id.qs_navbar_scrim);
         mAffordanceHelper = new KeyguardAffordanceHelper(this, getContext());
         mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
         mLastOrientation = getResources().getConfiguration().orientation;
 
-        mQsFrame = (FrameLayout) findViewById(R.id.qs_frame);
+        mQsFrame = findViewById(R.id.qs_frame);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 4dc593b..916b603 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -75,7 +75,7 @@
     @Override
     public void onFinishInflate() {
         mBarTransitions.init();
-        mBattery = (DarkReceiver) findViewById(R.id.battery);
+        mBattery = findViewById(R.id.battery);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 784f25e..37b0de4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -101,9 +101,9 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
 
-        mProgressBar = (ProgressBar) findViewById(R.id.remote_input_progress);
+        mProgressBar = findViewById(R.id.remote_input_progress);
 
-        mSendButton = (ImageButton) findViewById(R.id.remote_input_send);
+        mSendButton = findViewById(R.id.remote_input_send);
         mSendButton.setOnClickListener(this);
 
         mEditText = (RemoteEditText) getChildAt(0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java
index faa1a28..9f61574 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SplitClockView.java
@@ -59,8 +59,8 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mTimeView = (TextClock) findViewById(R.id.time_view);
-        mAmPmView = (TextClock) findViewById(R.id.am_pm_view);
+        mTimeView = findViewById(R.id.time_view);
+        mAmPmView = findViewById(R.id.am_pm_view);
         mTimeView.setShowCurrentUserTime(true);
         mAmPmView.setShowCurrentUserTime(true);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index ba91ffd..b5db78d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -495,12 +495,12 @@
         int childCount = algorithmState.visibleChildren.size();
         float childrenOnTop = 0.0f;
         for (int i = childCount - 1; i >= 0; i--) {
-            updateChildZValue(i, childrenOnTop,
+            childrenOnTop = updateChildZValue(i, childrenOnTop,
                     resultState, algorithmState, ambientState);
         }
     }
 
-    protected void updateChildZValue(int i, float childrenOnTop,
+    protected float updateChildZValue(int i, float childrenOnTop,
             StackScrollState resultState, StackScrollAlgorithmState algorithmState,
             AmbientState ambientState) {
         ExpandableView child = algorithmState.visibleChildren.get(i);
@@ -538,6 +538,7 @@
         } else {
             childViewState.zTranslation = baseZ;
         }
+        return childrenOnTop;
     }
 
     public void setIsExpanded(boolean isExpanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
index 4e4832c..10b6ff5 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
@@ -60,10 +60,10 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mIcon = (ImageView) findViewById(R.id.volume_zen_icon);
-        mSummaryLine1 = (TextView) findViewById(R.id.volume_zen_summary_line_1);
-        mSummaryLine2 = (TextView) findViewById(R.id.volume_zen_summary_line_2);
-        mEndNowButton = (TextView) findViewById(R.id.volume_zen_end_now);
+        mIcon = findViewById(R.id.volume_zen_icon);
+        mSummaryLine1 = findViewById(R.id.volume_zen_summary_line_1);
+        mSummaryLine2 = findViewById(R.id.volume_zen_summary_line_2);
+        mEndNowButton = findViewById(R.id.volume_zen_end_now);
         mConfigurableTexts.add(mSummaryLine1);
         mConfigurableTexts.add(mSummaryLine2);
         mConfigurableTexts.add(mEndNowButton, R.string.volume_zen_end_now);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/BatteryMeterDrawableTest.java b/packages/SystemUI/tests/src/com/android/systemui/BatteryMeterDrawableTest.java
index 6b47ada..e1f56a47 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/BatteryMeterDrawableTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/BatteryMeterDrawableTest.java
@@ -53,7 +53,7 @@
     @Test
     public void testDrawImageButNoTextIfPluggedIn() {
         mBatteryMeter.setBatteryLevel(0);
-        mBatteryMeter.setPluggedIn(true);
+        mBatteryMeter.setCharging(true);
         final Canvas canvas = mock(Canvas.class);
         mBatteryMeter.draw(canvas);
         verify(canvas, atLeastOnce()).drawPath(any(), any());
@@ -63,7 +63,7 @@
     @Test
     public void testDrawTextIfNotPluggedIn() {
         mBatteryMeter.setBatteryLevel(0);
-        mBatteryMeter.setPluggedIn(false);
+        mBatteryMeter.setCharging(false);
         final Canvas canvas = mock(Canvas.class);
         mBatteryMeter.draw(canvas);
         verify(canvas, times(1)).drawText(anyString(), anyFloat(), anyFloat(), any());
@@ -72,7 +72,7 @@
     @Test
     public void testDrawNoTextIfPowerSaveEnabled() {
         mBatteryMeter.setBatteryLevel(0);
-        mBatteryMeter.setPluggedIn(false);
+        mBatteryMeter.setCharging(false);
         mBatteryMeter.setPowerSave(true);
         final Canvas canvas = mock(Canvas.class);
         mBatteryMeter.draw(canvas);
@@ -84,7 +84,7 @@
         int criticalLevel = mResources.getInteger(
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
         mBatteryMeter.setBatteryLevel(criticalLevel);
-        mBatteryMeter.setPluggedIn(false);
+        mBatteryMeter.setCharging(false);
         final Canvas canvas = mock(Canvas.class);
         mBatteryMeter.draw(canvas);
         String warningString = mResources.getString(R.string.battery_meter_very_low_overlay_symbol);
@@ -96,7 +96,7 @@
         int criticalLevel = mResources.getInteger(
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
         mBatteryMeter.setBatteryLevel(criticalLevel + 1);
-        mBatteryMeter.setPluggedIn(false);
+        mBatteryMeter.setCharging(false);
         final Canvas canvas = mock(Canvas.class);
         mBatteryMeter.draw(canvas);
         String warningString = mResources.getString(R.string.battery_meter_very_low_overlay_symbol);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java
new file mode 100644
index 0000000..1b5d4a4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017 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;
+
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.NotificationTestHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ExpandHelperTest extends SysuiTestCase {
+
+    private ExpandableNotificationRow mRow;
+    private ExpandHelper mExpandHelper;
+    private ExpandHelper.Callback mCallback;
+
+    @Before
+    @UiThreadTest
+    public void setUp() {
+        Context context = getContext();
+        mRow = new NotificationTestHelper(context).createRow();
+        mCallback = mock(ExpandHelper.Callback.class);
+        mExpandHelper = new ExpandHelper(context, mCallback, 10, 100);
+    }
+
+    @Test
+    @UiThreadTest
+    public void testAnimationDoesntClearViewIfNewExpansionStarted() {
+        when(mCallback.getMaxExpandHeight(any())).thenReturn(100);
+        mExpandHelper.startExpanding(mRow, 0);
+        mExpandHelper.finishExpanding(false, 0);
+        mExpandHelper.startExpanding(mRow, 0);
+        ObjectAnimator scaleAnimation = mExpandHelper.getScaleAnimation();
+        scaleAnimation.end();
+        mExpandHelper.updateExpansion();
+    }
+
+}
diff --git a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/ClientTest.java b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/ClientTest.java
index 78fd174..63b6a11 100644
--- a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/ClientTest.java
+++ b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/ClientTest.java
@@ -49,21 +49,21 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
 
-        Button addpbtn = (Button) findViewById(R.id.addpkg);
-        Button procbtn = (Button) findViewById(R.id.procmsg);
-        Button delbtn = (Button) findViewById(R.id.delpkg);
+        Button addpbtn = findViewById(R.id.addpkg);
+        Button procbtn = findViewById(R.id.procmsg);
+        Button delbtn = findViewById(R.id.delpkg);
 
         Log.v(LOG_TAG, "activity created!!");
 
         addpbtn.setOnClickListener(new View.OnClickListener() {
                 public void onClick(View v) {
-                    EditText app_id = (EditText) findViewById(R.id.app_id);
-                    EditText cont = (EditText) findViewById(R.id.cont);
-                    EditText pkg = (EditText) findViewById(R.id.pkg);
-                    EditText cls = (EditText) findViewById(R.id.cls);
-                    RadioButton act = (RadioButton) findViewById(R.id.act);
-                    CheckBox sig = (CheckBox) findViewById(R.id.sig);
-                    CheckBox ftr = (CheckBox) findViewById(R.id.ftr);
+                    EditText app_id = findViewById(R.id.app_id);
+                    EditText cont = findViewById(R.id.cont);
+                    EditText pkg = findViewById(R.id.pkg);
+                    EditText cls = findViewById(R.id.cls);
+                    RadioButton act = findViewById(R.id.act);
+                    CheckBox sig = findViewById(R.id.sig);
+                    CheckBox ftr = findViewById(R.id.ftr);
 
                     try {
                         if (!mWapPushMan.addPackage(
@@ -93,11 +93,11 @@
 
         delbtn.setOnClickListener(new View.OnClickListener() {
                 public void onClick(View v) {
-                    EditText app_id = (EditText) findViewById(R.id.app_id);
-                    EditText cont = (EditText) findViewById(R.id.cont);
-                    EditText pkg = (EditText) findViewById(R.id.pkg);
-                    EditText cls = (EditText) findViewById(R.id.cls);
-                    // CheckBox delall = (CheckBox) findViewById(R.id.delall);
+                    EditText app_id = findViewById(R.id.app_id);
+                    EditText cont = findViewById(R.id.cont);
+                    EditText pkg = findViewById(R.id.pkg);
+                    EditText cls = findViewById(R.id.cls);
+                    // CheckBox delall = findViewById(R.id.delall);
                     // Log.d(LOG_TAG, "button clicked");
 
                     try {
@@ -115,9 +115,9 @@
 
         procbtn.setOnClickListener(new View.OnClickListener() {
                 public void onClick(View v) {
-                    EditText pdu = (EditText) findViewById(R.id.pdu);
-                    EditText app_id = (EditText) findViewById(R.id.app_id);
-                    EditText cont = (EditText) findViewById(R.id.cont);
+                    EditText pdu = findViewById(R.id.pdu);
+                    EditText app_id = findViewById(R.id.app_id);
+                    EditText cont = findViewById(R.id.cont);
 
                     // WapPushOverSms wap = new WapPushOverSms();
                     // wap.dispatchWapPdu(strToHex(pdu.getText().toString()));
diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
index a319beb..f878b4d 100644
--- a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
+++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
@@ -88,7 +88,7 @@
     protected void init() {
         setContentView(R.layout.wallpaper_cropper);
 
-        mCropView = (CropView) findViewById(R.id.cropView);
+        mCropView = findViewById(R.id.cropView);
 
         Intent cropIntent = getIntent();
         final Uri imageUri = cropIntent.getData();
diff --git a/samples/training/network-usage/src/com/example/android/networkusage/NetworkActivity.java b/samples/training/network-usage/src/com/example/android/networkusage/NetworkActivity.java
index b7ed331..27d230b 100644
--- a/samples/training/network-usage/src/com/example/android/networkusage/NetworkActivity.java
+++ b/samples/training/network-usage/src/com/example/android/networkusage/NetworkActivity.java
@@ -158,7 +158,7 @@
         setContentView(R.layout.main);
 
         // The specified network connection is not available. Displays error message.
-        WebView myWebView = (WebView) findViewById(R.id.webview);
+        WebView myWebView = findViewById(R.id.webview);
         myWebView.loadData(getResources().getString(R.string.connection_error),
                 "text/html", null);
     }
@@ -205,7 +205,7 @@
         protected void onPostExecute(String result) {
             setContentView(R.layout.main);
             // Displays the HTML string in the UI via a WebView
-            WebView myWebView = (WebView) findViewById(R.id.webview);
+            WebView myWebView = findViewById(R.id.webview);
             myWebView.loadData(result, "text/html", null);
         }
     }
diff --git a/services/Android.mk b/services/Android.mk
index 4452543..a4c891b 100644
--- a/services/Android.mk
+++ b/services/Android.mk
@@ -40,8 +40,8 @@
 
 # The convention is to name each service module 'services.$(module_name)'
 LOCAL_STATIC_JAVA_LIBRARIES := $(addprefix services.,$(services)) \
-    android.hidl.base@1.0-java-static \
-    android.hardware.biometrics.fingerprint@2.1-java-static
+    android.hidl.base-V1.0-java-static \
+    android.hardware.biometrics.fingerprint-V2.1-java-static
 
 ifeq ($(EMMA_INSTRUMENT_FRAMEWORK),true)
 LOCAL_EMMA_INSTRUMENT := true
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 67c2314c..67b5282 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -370,6 +370,23 @@
         }
     }
 
+    // AutoFillUiCallback
+    @Override
+    public void startIntentSender(IntentSender intentSender) {
+        synchronized (mLock) {
+            removeSelfLocked();
+        }
+        mHandlerCaller.getHandler().post(() -> {
+            try {
+                synchronized (mLock) {
+                    mClient.startIntentSender(intentSender);
+                }
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Error launching auth intent", e);
+            }
+        });
+    }
+
     public void setAuthenticationResultLocked(Bundle data) {
         if ((mResponseWaitingAuth == null && mDatasetWaitingAuth == null) || data == null) {
             removeSelf();
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 0f18c87..4449da9 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -67,6 +67,7 @@
         void requestShowFillUi(AutofillId id, int width, int height,
                 IAutofillWindowPresenter presenter);
         void requestHideFillUi(AutofillId id);
+        void startIntentSender(IntentSender intentSender);
     }
 
     public AutoFillUI(@NonNull Context context) {
@@ -201,6 +202,13 @@
                         mCallback.requestHideFillUi(focusedId);
                     }
                 }
+
+                @Override
+                public void startIntentSender(IntentSender intentSender) {
+                    if (mCallback != null) {
+                        mCallback.startIntentSender(intentSender);
+                    }
+                }
             });
         });
     }
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index a89df92..b68e3b1 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -17,7 +17,10 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.PendingIntent;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender;
 import android.graphics.Rect;
 import android.service.autofill.Dataset;
 import android.service.autofill.FillResponse;
@@ -55,6 +58,7 @@
         void requestShowFillUi(int width, int height,
                 IAutofillWindowPresenter windowPresenter);
         void requestHideFillUi();
+        void startIntentSender(IntentSender intentSender);
     }
 
     private final @NonNull AutofillWindowPresenter mWindowPresenter =
@@ -84,13 +88,24 @@
         final ViewGroup decor = (ViewGroup) inflater.inflate(
                 R.layout.autofill_dataset_picker, null);
 
+        final RemoteViews.OnClickHandler interceptionHandler = new RemoteViews.OnClickHandler() {
+            @Override
+            public boolean onClickHandler(View view, PendingIntent pendingIntent,
+                    Intent fillInIntent) {
+                if (pendingIntent != null) {
+                    mCallback.startIntentSender(pendingIntent.getIntentSender());
+                }
+                return true;
+            }
+        };
+
         if (response.getAuthentication() != null) {
             mListView = null;
             mAdapter = null;
 
             final View content;
             try {
-                content = response.getPresentation().apply(context, decor);
+                content = response.getPresentation().apply(context, decor, interceptionHandler);
                 decor.addView(content);
             } catch (RuntimeException e) {
                 callback.onCanceled();
@@ -101,7 +116,7 @@
             final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
             final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
             content.measure(widthMeasureSpec, heightMeasureSpec);
-            content.setOnClickListener(v -> mCallback.onResponsePicked(response));
+            decor.setOnClickListener(v -> mCallback.onResponsePicked(response));
             // TODO(b/33197203 , b/36660292): temporary limiting maximum height and minimum width
             mContentWidth = Math.max(content.getMeasuredWidth(), 1000);
             mContentHeight = Math.min(content.getMeasuredHeight(), 500);
@@ -118,7 +133,7 @@
                     final RemoteViews presentation = dataset.getFieldPresentation(index);
                     final View view;
                     try {
-                        view = presentation.apply(context, null);
+                        view = presentation.apply(context, null, interceptionHandler);
                     } catch (RuntimeException e) {
                         Slog.e(TAG, "Error inflating remote views", e);
                         continue;
diff --git a/services/core/Android.mk b/services/core/Android.mk
index 8003d21..f896478 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -20,17 +20,17 @@
 
 LOCAL_JAVA_LIBRARIES := \
     services.net \
-    android.hardware.light@2.0-java \
-    android.hardware.power@1.0-java \
-    android.hardware.tv.cec@1.0-java \
-    android.hidl.manager@1.0-java
+    android.hardware.light-V2.0-java \
+    android.hardware.power-V1.0-java \
+    android.hardware.tv.cec-V1.0-java \
+    android.hidl.manager-V1.0-java
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     tzdata_shared2 \
     tzdata_update2 \
-    android.hidl.base@1.0-java-static \
-    android.hardware.biometrics.fingerprint@2.1-java-static \
-    android.hardware.vibrator@1.0-java-constants \
+    android.hidl.base-V1.0-java-static \
+    android.hardware.biometrics.fingerprint-V2.1-java-static \
+    android.hardware.vibrator-V1.0-java-constants \
 
 ifneq ($(INCREMENTAL_BUILDS),)
     LOCAL_PROGUARD_ENABLED := disabled
diff --git a/services/core/java/com/android/server/OemLockService.java b/services/core/java/com/android/server/OemLockService.java
new file mode 100644
index 0000000..03f82a8
--- /dev/null
+++ b/services/core/java/com/android/server/OemLockService.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2017 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;
+
+import android.Manifest;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.service.oemlock.IOemLockService;
+import android.service.persistentdata.PersistentDataBlockManager;
+
+/**
+ * Service for managing the OEM lock state of the device.
+ *
+ * The current implementation is a wrapper around the previous implementation of OEM lock.
+ *  - the DISALLOW_OEM_UNLOCK user restriction was set if the carrier disallowed unlock
+ *  - the user allows unlock in settings which calls PDBM.setOemUnlockEnabled()
+ */
+public class OemLockService extends SystemService {
+    private Context mContext;
+
+    public OemLockService(Context context) {
+        super(context);
+        mContext = context;
+    }
+
+    @Override
+    public void onStart() {
+        publishBinderService(Context.OEM_LOCK_SERVICE, mService);
+    }
+
+    private boolean doIsOemUnlockAllowedByCarrier() {
+        return !UserManager.get(mContext).hasUserRestriction(UserManager.DISALLOW_OEM_UNLOCK);
+    }
+
+    private boolean doIsOemUnlockAllowedByUser() {
+        final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
+            mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return pdbm.getOemUnlockEnabled();
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    /**
+     * Implements the binder interface for the service.
+     */
+    private final IBinder mService = new IOemLockService.Stub() {
+        @Override
+        public void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) {
+            enforceManageCarrierOemUnlockPermission();
+            enforceUserIsAdmin();
+
+            // Note: this implementation does not require a signature
+
+            // Continue using user restriction for backwards compatibility
+            final UserHandle userHandle = UserHandle.of(UserHandle.getCallingUserId());
+            final long token = Binder.clearCallingIdentity();
+            try {
+                UserManager.get(mContext)
+                        .setUserRestriction(UserManager.DISALLOW_OEM_UNLOCK, !allowed, userHandle);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public boolean isOemUnlockAllowedByCarrier() {
+            enforceManageCarrierOemUnlockPermission();
+            return doIsOemUnlockAllowedByCarrier();
+        }
+
+        @Override
+        public void setOemUnlockAllowedByUser(boolean allowedByUser) {
+            if (ActivityManager.isUserAMonkey()) {
+                // Prevent a monkey from changing this
+                return;
+            }
+
+            enforceManageUserOemUnlockPermission();
+            enforceUserIsAdmin();
+
+            final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
+                    mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+                // The method name is misleading as it really just means whether or not the device
+                // can be unlocked but doesn't actually do any unlocking.
+                pdbm.setOemUnlockEnabled(allowedByUser);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public boolean isOemUnlockAllowedByUser() {
+            enforceManageUserOemUnlockPermission();
+            return doIsOemUnlockAllowedByUser();
+        }
+    };
+
+    private void enforceManageCarrierOemUnlockPermission() {
+        mContext.enforceCallingOrSelfPermission(
+                Manifest.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE,
+                "Can't manage OEM unlock allowed by carrier");
+    }
+
+    private void enforceManageUserOemUnlockPermission() {
+        mContext.enforceCallingOrSelfPermission(
+                Manifest.permission.MANAGE_USER_OEM_UNLOCK_STATE,
+                "Can't manage OEM unlock allowed by user");
+    }
+
+    private void enforceUserIsAdmin() {
+        final int userId = UserHandle.getCallingUserId();
+        final long token = Binder.clearCallingIdentity();
+        try {
+            if (!UserManager.get(mContext).isUserAdmin(userId)) {
+                throw new SecurityException("Must be an admin user");
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 5f585cc..eb58e4c 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -959,6 +959,12 @@
         mContext.sendBroadcastAsUser(ACCOUNTS_CHANGED_INTENT, new UserHandle(userId));
     }
 
+    private void sendAccountRemovedBroadcast(int userId) {
+        Intent intent = new Intent(AccountManager.ACTION_ACCOUNT_REMOVED);
+        intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+        mContext.sendBroadcastAsUser(intent, new UserHandle(userId));
+    }
+
     @Override
     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
             throws RemoteException {
@@ -1111,6 +1117,7 @@
                                     notifyPackage(packageToVisibility.getKey(), accounts);
                                 }
                             }
+                            sendAccountRemovedBroadcast(accounts.userId);
                         } else {
                             ArrayList<String> accountNames = accountNamesByType.get(account.type);
                             if (accountNames == null) {
@@ -1971,6 +1978,7 @@
 
                 sendNotificationAccountUpdated(resultAccount, accounts);
                 sendAccountsChangedBroadcast(accounts.userId);
+                sendAccountRemovedBroadcast(accounts.userId);
             }
         }
         return resultAccount;
@@ -2206,6 +2214,7 @@
 
                     // Only broadcast LOGIN_ACCOUNTS_CHANGED if a change occurred.
                     sendAccountsChangedBroadcast(accounts.userId);
+                    sendAccountRemovedBroadcast(accounts.userId);
                     String action = userUnlocked ? AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE
                             : AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE_DE;
                     logRecord(action, AccountsDb.TABLE_ACCOUNTS, accountId, accounts);
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index df250b1..55ee183 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -32,16 +32,10 @@
  */
 final class ActivityManagerConstants extends ContentObserver {
     // Key names stored in the settings value.
-    private static final String KEY_ENFORCE_BG_CHECK = "enforce_bg_check";
     private static final String KEY_MAX_CACHED_PROCESSES = "max_cached_processes";
 
-    private static final boolean DEFAULT_ENFORCE_BG_CHECK = SystemProperties.getBoolean(
-            "debug.bgcheck", true);
     private static final int DEFAULT_MAX_CACHED_PROCESSES = 32;
 
-    // Enforce background check on apps targeting O?
-    public boolean ENFORCE_BG_CHECK = DEFAULT_ENFORCE_BG_CHECK;
-
     // Maximum number of cached processes we will allow.
     public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
 
@@ -115,7 +109,6 @@
                 // with defaults.
                 Slog.e("ActivityManagerConstants", "Bad activity manager config settings", e);
             }
-            ENFORCE_BG_CHECK = mParser.getBoolean(KEY_ENFORCE_BG_CHECK, DEFAULT_ENFORCE_BG_CHECK);
             MAX_CACHED_PROCESSES = mParser.getInt(KEY_MAX_CACHED_PROCESSES,
                     DEFAULT_MAX_CACHED_PROCESSES);
             updateMaxCachedProcesses();
@@ -139,9 +132,6 @@
         pw.println("ACTIVITY MANAGER SETTINGS (dumpsys activity settings) "
                 + Settings.Global.ACTIVITY_MANAGER_CONSTANTS + ":");
 
-        pw.print("  "); pw.print(KEY_ENFORCE_BG_CHECK); pw.print("=");
-        pw.println(ENFORCE_BG_CHECK);
-
         pw.print("  "); pw.print(KEY_MAX_CACHED_PROCESSES); pw.print("=");
         pw.println(MAX_CACHED_PROCESSES);
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index fd7dea1..2be5313 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2717,17 +2717,6 @@
 
         mConstants = new ActivityManagerConstants(this, mHandler);
 
-        if (DEBUG_BACKGROUND_CHECK) {
-            Slog.d(TAG, "Enforcing O+ bg restrictions: " + mConstants.ENFORCE_BG_CHECK);
-            StringBuilder sb = new StringBuilder(200);
-            sb.append("  ");
-            for (String a : getBackgroundLaunchBroadcasts()) {
-                sb.append(' '); sb.append(a);
-            }
-            Slog.d(TAG, "Background implicit broadcasts:");
-            Slog.d(TAG, sb.toString());
-        }
-
         /* static; one-time init here */
         if (sKillHandler == null) {
             sKillThread = new ServiceThread(TAG + ":kill",
@@ -7875,9 +7864,7 @@
                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
                     final Rect sourceBounds = r.pictureInPictureArgs.getSourceRectHint();
-                    final Rect destBounds = mWindowManager.getPictureInPictureBounds(DEFAULT_DISPLAY,
-                            aspectRatio);
-                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, destBounds,
+                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
                             true /* moveHomeStackToFront */, "enterPictureInPictureMode");
                     final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
                     stack.setPictureInPictureAspectRatio(aspectRatio);
@@ -7938,7 +7925,7 @@
                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
                     // be used the next time the activity enters PiP
                     final PinnedActivityStack stack = r.getStack();
-                    if (!stack.isBoundsAnimatingToFullscreen()) {
+                    if (!stack.isAnimatingBoundsToFullscreen()) {
                         stack.setPictureInPictureAspectRatio(
                                 r.pictureInPictureArgs.getAspectRatio());
                         stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
@@ -8309,7 +8296,7 @@
     // Unified app-op and target sdk check
     int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
         // Apps that target O+ are always subject to background check
-        if (mConstants.ENFORCE_BG_CHECK && packageTargetSdk >= Build.VERSION_CODES.O) {
+        if (packageTargetSdk >= Build.VERSION_CODES.O) {
             if (DEBUG_BACKGROUND_CHECK) {
                 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
             }
@@ -10547,8 +10534,10 @@
                     if (stackId == PINNED_STACK_ID) {
                         final PinnedActivityStack pinnedStack =
                                 mStackSupervisor.getStack(PINNED_STACK_ID);
-                        pinnedStack.animateResizePinnedStack(null /* sourceBounds */, destBounds,
-                                animationDuration);
+                        if (pinnedStack != null) {
+                            pinnedStack.animateResizePinnedStack(null /* sourceBounds */,
+                                    destBounds, animationDuration);
+                        }
                     } else {
                         throw new IllegalArgumentException("Stack: " + stackId
                                 + " doesn't support animated resize.");
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 68e25c3..4d16e33 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -174,6 +174,7 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.LocalServices;
 import com.android.server.am.ActivityStack.ActivityState;
+import com.android.server.wm.PinnedStackWindowController;
 import com.android.server.wm.WindowManagerService;
 
 import java.io.FileDescriptor;
@@ -2492,11 +2493,21 @@
     }
 
     void resizePinnedStackLocked(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
-        final ActivityStack stack = getStack(PINNED_STACK_ID);
+        final PinnedActivityStack stack = getStack(PINNED_STACK_ID);
         if (stack == null) {
             Slog.w(TAG, "resizePinnedStackLocked: pinned stack not found");
             return;
         }
+
+        // It is possible for the bounds animation from the WM to call this but be delayed by
+        // another AM call that is holding the AMS lock. In such a case, the pinnedBounds may be
+        // incorrect if AMS.resizeStackWithBoundsFromWindowManager() is already called while waiting
+        // for the AMS lock to be freed. So check and make sure these bounds are still good.
+        final PinnedStackWindowController stackController = stack.getWindowContainerController();
+        if (stackController.pinnedStackResizeAllowed()) {
+            return;
+        }
+
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizePinnedStack");
         mWindowManager.deferSurfaceLayout();
         try {
@@ -2857,12 +2868,12 @@
             return false;
         }
 
-        moveActivityToPinnedStackLocked(r, null /* sourceBounds */, destBounds,
+        moveActivityToPinnedStackLocked(r, null /* sourceBounds */, 0f /* aspectRatio */,
                 true /* moveHomeStackToFront */, "moveTopActivityToPinnedStack");
         return true;
     }
 
-    void moveActivityToPinnedStackLocked(ActivityRecord r, Rect sourceBounds, Rect destBounds,
+    void moveActivityToPinnedStackLocked(ActivityRecord r, Rect sourceBounds, float aspectRatio,
             boolean moveHomeStackToFront, String reason) {
 
         mWindowManager.deferSurfaceLayout();
@@ -2932,6 +2943,11 @@
         ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
         resumeFocusedStackTopActivityLocked();
 
+        // Calculate the default bounds (don't use existing stack bounds as we may have just created
+        // the stack
+        final Rect destBounds = mWindowManager.getPictureInPictureBounds(DEFAULT_DISPLAY,
+                aspectRatio, false /* useExistingStackBounds */);
+
         // TODO(b/36099777): Schedule the PiP mode change here immediately until we can defer all
         // callbacks until after the bounds animation
         scheduleUpdatePictureInPictureModeIfNeeded(r.getTask(), destBounds, true /* immediate */);
diff --git a/services/core/java/com/android/server/am/AppErrorDialog.java b/services/core/java/com/android/server/am/AppErrorDialog.java
index 646f6ce..02ec075 100644
--- a/services/core/java/com/android/server/am/AppErrorDialog.java
+++ b/services/core/java/com/android/server/am/AppErrorDialog.java
@@ -106,7 +106,7 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        final FrameLayout frame = (FrameLayout) findViewById(android.R.id.custom);
+        final FrameLayout frame = findViewById(android.R.id.custom);
         final Context context = getContext();
         LayoutInflater.from(context).inflate(
                 com.android.internal.R.layout.app_error_dialog, frame, true);
@@ -114,19 +114,19 @@
         boolean hasRestart = !mRepeating && mIsRestartable;
         final boolean hasReceiver = mProc.errorReportReceiver != null;
 
-        final TextView restart = (TextView) findViewById(com.android.internal.R.id.aerr_restart);
+        final TextView restart = findViewById(com.android.internal.R.id.aerr_restart);
         restart.setOnClickListener(this);
         restart.setVisibility(hasRestart ? View.VISIBLE : View.GONE);
-        final TextView report = (TextView) findViewById(com.android.internal.R.id.aerr_report);
+        final TextView report = findViewById(com.android.internal.R.id.aerr_report);
         report.setOnClickListener(this);
         report.setVisibility(hasReceiver ? View.VISIBLE : View.GONE);
-        final TextView close = (TextView) findViewById(com.android.internal.R.id.aerr_close);
+        final TextView close = findViewById(com.android.internal.R.id.aerr_close);
         close.setVisibility(!hasRestart ? View.VISIBLE : View.GONE);
         close.setOnClickListener(this);
 
         boolean showMute = !IS_USER_BUILD && Settings.Global.getInt(context.getContentResolver(),
                 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
-        final TextView mute = (TextView) findViewById(com.android.internal.R.id.aerr_mute);
+        final TextView mute = findViewById(com.android.internal.R.id.aerr_mute);
         mute.setOnClickListener(this);
         mute.setVisibility(showMute ? View.VISIBLE : View.GONE);
 
diff --git a/services/core/java/com/android/server/am/AppNotRespondingDialog.java b/services/core/java/com/android/server/am/AppNotRespondingDialog.java
index 9e29725..a3a6778 100644
--- a/services/core/java/com/android/server/am/AppNotRespondingDialog.java
+++ b/services/core/java/com/android/server/am/AppNotRespondingDialog.java
@@ -104,18 +104,18 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        final FrameLayout frame = (FrameLayout) findViewById(android.R.id.custom);
+        final FrameLayout frame = findViewById(android.R.id.custom);
         final Context context = getContext();
         LayoutInflater.from(context).inflate(
                 com.android.internal.R.layout.app_anr_dialog, frame, true);
 
-        final TextView report = (TextView) findViewById(com.android.internal.R.id.aerr_report);
+        final TextView report = findViewById(com.android.internal.R.id.aerr_report);
         report.setOnClickListener(this);
         final boolean hasReceiver = mProc.errorReportReceiver != null;
         report.setVisibility(hasReceiver ? View.VISIBLE : View.GONE);
-        final TextView close = (TextView) findViewById(com.android.internal.R.id.aerr_close);
+        final TextView close = findViewById(com.android.internal.R.id.aerr_close);
         close.setOnClickListener(this);
-        final TextView wait = (TextView) findViewById(com.android.internal.R.id.aerr_wait);
+        final TextView wait = findViewById(com.android.internal.R.id.aerr_wait);
         wait.setOnClickListener(this);
 
         findViewById(com.android.internal.R.id.customPanel).setVisibility(View.VISIBLE);
diff --git a/services/core/java/com/android/server/am/PinnedActivityStack.java b/services/core/java/com/android/server/am/PinnedActivityStack.java
index 394e902..cd9c42c 100644
--- a/services/core/java/com/android/server/am/PinnedActivityStack.java
+++ b/services/core/java/com/android/server/am/PinnedActivityStack.java
@@ -21,7 +21,7 @@
 
 import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
 import com.android.server.wm.PinnedStackWindowController;
-import com.android.server.wm.StackWindowController;
+import com.android.server.wm.PinnedStackWindowListener;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -29,7 +29,8 @@
 /**
  * State and management of the pinned stack of activities.
  */
-class PinnedActivityStack extends ActivityStack<PinnedStackWindowController> {
+class PinnedActivityStack extends ActivityStack<PinnedStackWindowController>
+        implements PinnedStackWindowListener {
 
     PinnedActivityStack(ActivityContainer activityContainer,
             RecentTasks recentTasks, boolean onTop) {
@@ -55,8 +56,8 @@
         getWindowContainerController().setPictureInPictureActions(actions);
     }
 
-    boolean isBoundsAnimatingToFullscreen() {
-        return getWindowContainerController().isBoundsAnimatingToFullscreen();
+    boolean isAnimatingBoundsToFullscreen() {
+        return getWindowContainerController().isAnimatingBoundsToFullscreen();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
index ad66faa..5dee91d 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java
@@ -23,9 +23,6 @@
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
-import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
-import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog;
-import static com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.NetworkId;
 
 import android.net.ConnectivityMetricsEvent;
 import android.net.metrics.ApfProgramEvent;
@@ -34,6 +31,7 @@
 import android.net.metrics.DhcpClientEvent;
 import android.net.metrics.DhcpErrorEvent;
 import android.net.metrics.DnsEvent;
+import android.net.metrics.ConnectStats;
 import android.net.metrics.IpManagerEvent;
 import android.net.metrics.IpReachabilityEvent;
 import android.net.metrics.NetworkEvent;
@@ -41,7 +39,12 @@
 import android.net.metrics.ValidationProbeEvent;
 import android.os.Parcelable;
 import android.util.SparseArray;
+import android.util.SparseIntArray;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass;
+import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
+import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog;
+import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.NetworkId;
+import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.Pair;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
@@ -77,20 +80,51 @@
     }
 
     public static IpConnectivityEvent toProto(ConnectivityMetricsEvent ev) {
-        final IpConnectivityEvent out = new IpConnectivityEvent();
+        final IpConnectivityEvent out = buildEvent(ev.netId, ev.transports, ev.ifname);
+        out.timeMs = ev.timestamp;
         if (!setEvent(out, ev.data)) {
             return null;
         }
-        out.timeMs = ev.timestamp;
-        out.networkId = ev.netId;
-        out.transports = ev.transports;
-        if (ev.ifname != null) {
-          out.ifName = ev.ifname;
-        }
-        inferLinkLayer(out);
         return out;
     }
 
+    public static IpConnectivityEvent toProto(ConnectStats in) {
+        IpConnectivityLogClass.ConnectStatistics stats =
+                new IpConnectivityLogClass.ConnectStatistics();
+        stats.connectCount = in.connectCount;
+        stats.connectBlockingCount = in.connectBlockingCount;
+        stats.ipv6AddrCount = in.ipv6ConnectCount;
+        stats.latenciesMs = in.latencies.toArray();
+        stats.errnosCounters = toPairArray(in.errnos);
+        final IpConnectivityEvent out = buildEvent(in.netId, in.transports, null);
+        out.setConnectStatistics(stats);
+        return out;
+    }
+
+
+    public static IpConnectivityEvent toProto(DnsEvent in) {
+        IpConnectivityLogClass.DNSLookupBatch dnsLookupBatch =
+                new IpConnectivityLogClass.DNSLookupBatch();
+        in.resize(in.eventCount);
+        dnsLookupBatch.eventTypes = bytesToInts(in.eventTypes);
+        dnsLookupBatch.returnCodes = bytesToInts(in.returnCodes);
+        dnsLookupBatch.latenciesMs = in.latenciesMs;
+        final IpConnectivityEvent out = buildEvent(in.netId, in.transports, null);
+        out.setDnsLookupBatch(dnsLookupBatch);
+        return out;
+    }
+
+    private static IpConnectivityEvent buildEvent(int netId, long transports, String ifname) {
+        final IpConnectivityEvent ev = new IpConnectivityEvent();
+        ev.networkId = netId;
+        ev.transports = transports;
+        if (ifname != null) {
+            ev.ifName = ifname;
+        }
+        inferLinkLayer(ev);
+        return ev;
+    }
+
     private static boolean setEvent(IpConnectivityEvent out, Parcelable in) {
         if (in instanceof DhcpErrorEvent) {
             setDhcpErrorEvent(out, (DhcpErrorEvent) in);
@@ -102,11 +136,6 @@
             return true;
         }
 
-        if (in instanceof DnsEvent) {
-            setDnsEvent(out, (DnsEvent) in);
-            return true;
-        }
-
         if (in instanceof IpManagerEvent) {
             setIpManagerEvent(out, (IpManagerEvent) in);
             return true;
@@ -163,16 +192,6 @@
         out.setDhcpEvent(dhcpEvent);
     }
 
-    private static void setDnsEvent(IpConnectivityEvent out, DnsEvent in) {
-        IpConnectivityLogClass.DNSLookupBatch dnsLookupBatch =
-                new IpConnectivityLogClass.DNSLookupBatch();
-        dnsLookupBatch.networkId = netIdOf(in.netId);
-        dnsLookupBatch.eventTypes = bytesToInts(in.eventTypes);
-        dnsLookupBatch.returnCodes = bytesToInts(in.returnCodes);
-        dnsLookupBatch.latenciesMs = in.latenciesMs;
-        out.setDnsLookupBatch(dnsLookupBatch);
-    }
-
     private static void setIpManagerEvent(IpConnectivityEvent out, IpManagerEvent in) {
         IpConnectivityLogClass.IpProvisioningEvent ipProvisioningEvent =
                 new IpConnectivityLogClass.IpProvisioningEvent();
@@ -268,6 +287,18 @@
         return out;
     }
 
+    private static Pair[] toPairArray(SparseIntArray counts) {
+        final int s = counts.size();
+        Pair[] pairs = new Pair[s];
+        for (int i = 0; i < s; i++) {
+            Pair p = new Pair();
+            p.key = counts.keyAt(i);
+            p.value = counts.valueAt(i);
+            pairs[i] = p;
+        }
+        return pairs;
+    }
+
     private static NetworkId netIdOf(int netid) {
         final NetworkId ni = new NetworkId();
         ni.networkId = netid;
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
index da56a07..475d786 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
@@ -76,7 +76,8 @@
 
     @VisibleForTesting
     public final Impl impl = new Impl();
-    private NetdEventListenerService mNetdListener;
+    @VisibleForTesting
+    NetdEventListenerService mNetdListener;
 
     @GuardedBy("mLock")
     private ArrayList<ConnectivityMetricsEvent> mBuffer;
diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
index 7b9c60c..214cfce 100644
--- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
+++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
@@ -18,10 +18,9 @@
 
 import android.content.Context;
 import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
 import android.net.INetdEventCallback;
 import android.net.Network;
-import android.net.NetworkRequest;
+import android.net.NetworkCapabilities;
 import android.net.metrics.ConnectStats;
 import android.net.metrics.DnsEvent;
 import android.net.metrics.INetdEventListener;
@@ -29,17 +28,17 @@
 import android.os.RemoteException;
 import android.text.format.DateUtils;
 import android.util.Log;
+import android.util.SparseArray;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.BitUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.TokenBucket;
-import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.ConnectStatistics;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
 import java.io.PrintWriter;
-import java.util.Arrays;
 import java.util.List;
-import java.util.SortedMap;
-import java.util.TreeMap;
+import java.util.function.Function;
+import java.util.function.IntFunction;
 
 /**
  * Implementation of the INetdEventListener interface.
@@ -52,8 +51,7 @@
     private static final boolean DBG = false;
     private static final boolean VDBG = false;
 
-    // TODO: read this constant from system property
-    private static final int MAX_LOOKUPS_PER_DNS_EVENT = 100;
+    private static final int INITIAL_DNS_BATCH_SIZE = 100;
 
     // Rate limit connect latency logging to 1 measurement per 15 seconds (5760 / day) with maximum
     // bursts of 5000 measurements.
@@ -61,81 +59,17 @@
     private static final int CONNECT_LATENCY_FILL_RATE    = 15 * (int) DateUtils.SECOND_IN_MILLIS;
     private static final int CONNECT_LATENCY_MAXIMUM_RECORDS = 20000;
 
-    // Stores the results of a number of consecutive DNS lookups on the same network.
-    // This class is not thread-safe and it is the responsibility of the service to call its methods
-    // on one thread at a time.
-    private class DnsEventBatch {
-        private final int mNetId;
-
-        private final byte[] mEventTypes = new byte[MAX_LOOKUPS_PER_DNS_EVENT];
-        private final byte[] mReturnCodes = new byte[MAX_LOOKUPS_PER_DNS_EVENT];
-        private final int[] mLatenciesMs = new int[MAX_LOOKUPS_PER_DNS_EVENT];
-        private int mEventCount;
-
-        public DnsEventBatch(int netId) {
-            mNetId = netId;
-        }
-
-        public void addResult(byte eventType, byte returnCode, int latencyMs) {
-            mEventTypes[mEventCount] = eventType;
-            mReturnCodes[mEventCount] = returnCode;
-            mLatenciesMs[mEventCount] = latencyMs;
-            mEventCount++;
-            if (mEventCount == MAX_LOOKUPS_PER_DNS_EVENT) {
-                logAndClear();
-            }
-        }
-
-        public void logAndClear() {
-            // Did we lose a race with addResult?
-            if (mEventCount == 0) {
-                return;
-            }
-
-            // Only log as many events as we actually have.
-            byte[] eventTypes = Arrays.copyOf(mEventTypes, mEventCount);
-            byte[] returnCodes = Arrays.copyOf(mReturnCodes, mEventCount);
-            int[] latenciesMs = Arrays.copyOf(mLatenciesMs, mEventCount);
-            mMetricsLog.log(new DnsEvent(mNetId, eventTypes, returnCodes, latenciesMs));
-            maybeLog("Logging %d results for netId %d", mEventCount, mNetId);
-            mEventCount = 0;
-        }
-
-        // For debugging and unit tests only.
-        public String toString() {
-            return String.format("%s %d %d", getClass().getSimpleName(), mNetId, mEventCount);
-        }
-    }
-
-    // Only sorted for ease of debugging. Because we only typically have a handful of networks up
-    // at any given time, performance is not a concern.
+    // Sparse arrays of DNS and connect events, grouped by net id.
     @GuardedBy("this")
-    private final SortedMap<Integer, DnsEventBatch> mEventBatches = new TreeMap<>();
+    private final SparseArray<DnsEvent> mDnsEvents = new SparseArray<>();
+    @GuardedBy("this")
+    private final SparseArray<ConnectStats> mConnectEvents = new SparseArray<>();
 
-    // We register a NetworkCallback to ensure that when a network disconnects, we flush the DNS
-    // queries we've logged on that network. Because we do not do this periodically, we might lose
-    // up to MAX_LOOKUPS_PER_DNS_EVENT lookup stats on each network when the system is shutting
-    // down. We believe this to be sufficient for now.
     private final ConnectivityManager mCm;
-    private final IpConnectivityLog mMetricsLog;
-    private final NetworkCallback mNetworkCallback = new NetworkCallback() {
-        @Override
-        public void onLost(Network network) {
-            synchronized (NetdEventListenerService.this) {
-                DnsEventBatch batch = mEventBatches.remove(network.netId);
-                if (batch != null) {
-                    batch.logAndClear();
-                }
-            }
-        }
-    };
 
     @GuardedBy("this")
     private final TokenBucket mConnectTb =
             new TokenBucket(CONNECT_LATENCY_FILL_RATE, CONNECT_LATENCY_BURST_LIMIT);
-    @GuardedBy("this")
-    private ConnectStats mConnectStats = makeConnectStats();
-
     // 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")
@@ -152,16 +86,13 @@
     }
 
     public NetdEventListenerService(Context context) {
-        this(context.getSystemService(ConnectivityManager.class), new IpConnectivityLog());
+        this(context.getSystemService(ConnectivityManager.class));
     }
 
     @VisibleForTesting
-    public NetdEventListenerService(ConnectivityManager cm, IpConnectivityLog log) {
+    public NetdEventListenerService(ConnectivityManager cm) {
         // We are started when boot is complete, so ConnectivityService should already be running.
         mCm = cm;
-        mMetricsLog = log;
-        final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
-        mCm.registerNetworkCallback(request, mNetworkCallback);
     }
 
     @Override
@@ -172,16 +103,16 @@
             throws RemoteException {
         maybeVerboseLog("onDnsEvent(%d, %d, %d, %dms)", netId, eventType, returnCode, latencyMs);
 
-        DnsEventBatch batch = mEventBatches.get(netId);
-        if (batch == null) {
-            batch = new DnsEventBatch(netId);
-            mEventBatches.put(netId, batch);
+        DnsEvent dnsEvent = mDnsEvents.get(netId);
+        if (dnsEvent == null) {
+            dnsEvent = makeDnsEvent(netId);
+            mDnsEvents.put(netId, dnsEvent);
         }
-        batch.addResult((byte) eventType, (byte) returnCode, latencyMs);
+        dnsEvent.addResult((byte) eventType, (byte) returnCode, latencyMs);
 
         if (mNetdEventCallback != null) {
-            mNetdEventCallback.onDnsEvent(hostname, ipAddresses, ipAddressesCount,
-                    System.currentTimeMillis(), uid);
+            long timestamp = System.currentTimeMillis();
+            mNetdEventCallback.onDnsEvent(hostname, ipAddresses, ipAddressesCount, timestamp, uid);
         }
     }
 
@@ -192,7 +123,12 @@
             int port, int uid) throws RemoteException {
         maybeVerboseLog("onConnectEvent(%d, %d, %dms)", netId, error, latencyMs);
 
-        mConnectStats.addEvent(error, latencyMs, ipAddr);
+        ConnectStats connectStats = mConnectEvents.get(netId);
+        if (connectStats == null) {
+            connectStats = makeConnectStats(netId);
+            mConnectEvents.put(netId, connectStats);
+        }
+        connectStats.addEvent(error, latencyMs, ipAddr);
 
         if (mNetdEventCallback != null) {
             mNetdEventCallback.onConnectEvent(ipAddr, port, System.currentTimeMillis(), uid);
@@ -200,21 +136,8 @@
     }
 
     public synchronized void flushStatistics(List<IpConnectivityEvent> events) {
-        events.add(flushConnectStats());
-        // TODO: migrate DnsEventBatch to IpConnectivityLogClass.DNSLatencies
-    }
-
-    private IpConnectivityEvent connectStatsProto() {
-        // TODO: add transport information
-        IpConnectivityEvent ev = new IpConnectivityEvent();
-        ev.setConnectStatistics(mConnectStats.toProto());
-        return ev;
-    }
-
-    private IpConnectivityEvent flushConnectStats() {
-        IpConnectivityEvent ev = connectStatsProto();
-        mConnectStats = makeConnectStats();
-        return ev;
+        flushProtos(events, mConnectEvents, IpConnectivityEventBuilder::toProto);
+        flushProtos(events, mDnsEvents, IpConnectivityEventBuilder::toProto);
     }
 
     public synchronized void dump(PrintWriter writer) {
@@ -226,18 +149,47 @@
     }
 
     public synchronized void list(PrintWriter pw) {
-        for (DnsEventBatch batch : mEventBatches.values()) {
-            pw.println(batch.toString());
-        }
-        pw.println(mConnectStats.toString());
+        listEvents(pw, mConnectEvents, (x) -> x);
+        listEvents(pw, mDnsEvents, (x) -> x);
     }
 
     public synchronized void listAsProtos(PrintWriter pw) {
-        pw.println(connectStatsProto().toString());
+        listEvents(pw, mConnectEvents, IpConnectivityEventBuilder::toProto);
+        listEvents(pw, mDnsEvents, IpConnectivityEventBuilder::toProto);
     }
 
-    private ConnectStats makeConnectStats() {
-        return new ConnectStats(mConnectTb, CONNECT_LATENCY_MAXIMUM_RECORDS);
+    private static <T> void flushProtos(List<IpConnectivityEvent> out, SparseArray<T> in,
+            Function<T, IpConnectivityEvent> mapper) {
+        for (int i = 0; i < in.size(); i++) {
+            out.add(mapper.apply(in.valueAt(i)));
+        }
+        in.clear();
+    }
+
+    public static <T> void listEvents(
+            PrintWriter pw, SparseArray<T> events, Function<T, Object> mapper) {
+        for (int i = 0; i < events.size(); i++) {
+            pw.println(mapper.apply(events.valueAt(i)).toString());
+        }
+    }
+
+    private ConnectStats makeConnectStats(int netId) {
+        long transports = getTransports(netId);
+        return new ConnectStats(netId, transports, mConnectTb, CONNECT_LATENCY_MAXIMUM_RECORDS);
+    }
+
+    private DnsEvent makeDnsEvent(int netId) {
+        long transports = getTransports(netId);
+        return new DnsEvent(netId, transports, INITIAL_DNS_BATCH_SIZE);
+    }
+
+    private long getTransports(int netId) {
+        // TODO: directly query ConnectivityService instead of going through Binder interface.
+        NetworkCapabilities nc = mCm.getNetworkCapabilities(new Network(netId));
+        if (nc == null) {
+            return 0;
+        }
+        return BitUtils.packBits(nc.getTransportTypes());
     }
 
     private static void maybeLog(String s, Object... args) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index 3e53aca..d3c74e6 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -70,6 +70,7 @@
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.UnknownHostException;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Random;
 import java.util.concurrent.CountDownLatch;
@@ -90,6 +91,8 @@
     private static final String DEFAULT_HTTP_URL      =
             "http://connectivitycheck.gstatic.com/generate_204";
     private static final String DEFAULT_FALLBACK_URL  = "http://www.google.com/gen_204";
+    private static final String DEFAULT_OTHER_FALLBACK_URLS =
+            "http://play.googleapis.com/generate_204";
     private static final String DEFAULT_USER_AGENT    = "Mozilla/5.0 (X11; Linux x86_64) "
                                                       + "AppleWebKit/537.36 (KHTML, like Gecko) "
                                                       + "Chrome/52.0.2743.82 Safari/537.36";
@@ -263,7 +266,8 @@
     private final String mCaptivePortalUserAgent;
     private final URL mCaptivePortalHttpsUrl;
     private final URL mCaptivePortalHttpUrl;
-    private final URL mCaptivePortalFallbackUrl;
+    private final URL[] mCaptivePortalFallbackUrls;
+    private int mNextFallbackUrlIndex = 0;
 
     public NetworkMonitor(Context context, Handler handler, NetworkAgentInfo networkAgentInfo,
             NetworkRequest defaultRequest) {
@@ -302,7 +306,7 @@
         mCaptivePortalUserAgent = getCaptivePortalUserAgent(context);
         mCaptivePortalHttpsUrl = makeURL(getCaptivePortalServerHttpsUrl(context));
         mCaptivePortalHttpUrl = makeURL(getCaptivePortalServerHttpUrl(context));
-        mCaptivePortalFallbackUrl = makeURL(getCaptivePortalFallbackUrl(context));
+        mCaptivePortalFallbackUrls = makeCaptivePortalFallbackUrls(context);
 
         start();
     }
@@ -450,7 +454,7 @@
                     intent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL,
                             mLastPortalProbeResult.detectUrl);
                     intent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT,
-                            getCaptivePortalUserAgent(mContext));
+                            mCaptivePortalUserAgent);
                     intent.setFlags(
                             Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
                     mContext.startActivityAsUser(intent, UserHandle.CURRENT);
@@ -666,9 +670,24 @@
         return getSetting(context, Settings.Global.CAPTIVE_PORTAL_HTTP_URL, DEFAULT_HTTP_URL);
     }
 
-    private static String getCaptivePortalFallbackUrl(Context context) {
-        return getSetting(context,
+    private URL[] makeCaptivePortalFallbackUrls(Context context) {
+        String separator = ",";
+        String firstUrl = getSetting(context,
                 Settings.Global.CAPTIVE_PORTAL_FALLBACK_URL, DEFAULT_FALLBACK_URL);
+        String joinedUrls = firstUrl + separator + getSetting(context,
+                Settings.Global.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS, DEFAULT_OTHER_FALLBACK_URLS);
+        List<URL> urls = new ArrayList<>();
+        for (String s : joinedUrls.split(separator)) {
+            URL u = makeURL(s);
+            if (u == null) {
+                continue;
+            }
+            urls.add(u);
+        }
+        if (urls.isEmpty()) {
+            Log.e(TAG, String.format("could not create any url from %s", joinedUrls));
+        }
+        return urls.toArray(new URL[urls.size()]);
     }
 
     private static String getCaptivePortalUserAgent(Context context) {
@@ -680,6 +699,15 @@
         return value != null ? value : defaultValue;
     }
 
+    private URL nextFallbackUrl() {
+        if (mCaptivePortalFallbackUrls.length == 0) {
+            return null;
+        }
+        int idx = Math.abs(mNextFallbackUrlIndex) % mCaptivePortalFallbackUrls.length;
+        mNextFallbackUrlIndex += new Random().nextInt(); // randomely change url without memory.
+        return mCaptivePortalFallbackUrls[idx];
+    }
+
     @VisibleForTesting
     protected CaptivePortalProbeResult isCaptivePortal() {
         if (!mIsCaptivePortalCheckEnabled) {
@@ -690,7 +718,6 @@
         URL pacUrl = null;
         URL httpsUrl = mCaptivePortalHttpsUrl;
         URL httpUrl = mCaptivePortalHttpUrl;
-        URL fallbackUrl = mCaptivePortalFallbackUrl;
 
         // On networks with a PAC instead of fetching a URL that should result in a 204
         // response, we instead simply fetch the PAC script.  This is done for a few reasons:
@@ -727,7 +754,7 @@
         if (pacUrl != null) {
             result = sendDnsAndHttpProbes(null, pacUrl, ValidationProbeEvent.PROBE_PAC);
         } else if (mUseHttps) {
-            result = sendParallelHttpProbes(proxyInfo, httpsUrl, httpUrl, fallbackUrl);
+            result = sendParallelHttpProbes(proxyInfo, httpsUrl, httpUrl);
         } else {
             result = sendDnsAndHttpProbes(proxyInfo, httpUrl, ValidationProbeEvent.PROBE_HTTP);
         }
@@ -863,7 +890,7 @@
     }
 
     private CaptivePortalProbeResult sendParallelHttpProbes(
-            ProxyInfo proxy, URL httpsUrl, URL httpUrl, URL fallbackUrl) {
+            ProxyInfo proxy, URL httpsUrl, URL httpUrl) {
         // Number of probes to wait for. If a probe completes with a conclusive answer
         // it shortcuts the latch immediately by forcing the count to 0.
         final CountDownLatch latch = new CountDownLatch(2);
@@ -922,7 +949,8 @@
         if (httpsResult.isPortal() || httpsResult.isSuccessful()) {
             return httpsResult;
         }
-        // If a fallback url is specified, use a fallback probe to try again portal detection.
+        // If a fallback url exists, use a fallback probe to try again portal detection.
+        URL fallbackUrl = nextFallbackUrl();
         if (fallbackUrl != null) {
             CaptivePortalProbeResult result =
                     sendHttpProbe(fallbackUrl, ValidationProbeEvent.PROBE_FALLBACK);
@@ -1061,7 +1089,7 @@
     }
 
     private void logValidationProbe(long durationMs, int probeType, int probeResult) {
-        long transports = mNetworkAgentInfo.networkCapabilities.getTransports();
+        int[] transports = mNetworkAgentInfo.networkCapabilities.getTransportTypes();
         boolean isFirstValidation = validationStage().isFirstValidation;
         ValidationProbeEvent ev = new ValidationProbeEvent();
         ev.probeType = ValidationProbeEvent.makeProbeType(probeType, isFirstValidation);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 95fb5af..4f29bfa 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -145,6 +145,7 @@
 import android.database.ContentObserver;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.hardware.display.DisplayManager;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiPlaybackClient;
@@ -221,6 +222,7 @@
 import android.view.animation.Animation;
 import android.view.animation.AnimationSet;
 import android.view.animation.AnimationUtils;
+import android.widget.ImageView;
 
 import com.android.internal.R;
 import com.android.internal.logging.MetricsLogger;
@@ -2809,6 +2811,7 @@
                             + overrideConfig + " to starting window resId=" + resId);
                     context = overrideContext;
                 }
+                typedArray.recycle();
             }
 
             final PhoneWindow win = new PhoneWindow(context);
@@ -2868,6 +2871,8 @@
             }
 
             params.setTitle("Splash Screen " + packageName);
+            addSplashscreenContent(win, context);
+
             wm = (WindowManager) context.getSystemService(WINDOW_SERVICE);
             view = win.getDecorView();
 
@@ -2898,6 +2903,24 @@
         return null;
     }
 
+    private void addSplashscreenContent(PhoneWindow win, Context ctx) {
+        final TypedArray a = ctx.obtainStyledAttributes(R.styleable.Window);
+        final int resId = a.getResourceId(R.styleable.Window_windowSplashscreenContent, 0);
+        a.recycle();
+        if (resId == 0) {
+            return;
+        }
+        final Drawable drawable = ctx.getDrawable(resId);
+        if (drawable == null) {
+            return;
+        }
+
+        // We wrap this into a view so the system insets get applied to the drawable.
+        final View v = new View(ctx);
+        v.setBackground(drawable);
+        win.setContentView(v);
+    }
+
     /** Obtain proper context for showing splash screen on the provided display. */
     private Context getDisplayContext(Context context, int displayId) {
         if (displayId == Display.DEFAULT_DISPLAY) {
@@ -5238,7 +5261,7 @@
     @Override
     public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs,
             WindowState attached, WindowState imeTarget) {
-        final boolean visible = !win.isGoneForLayoutLw();
+        final boolean visible = !win.isGoneForLayoutLw() && win.getAttrs().alpha > 0f;
         if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisible=" + visible);
         applyKeyguardPolicyLw(win, imeTarget);
         final int fl = PolicyControl.getWindowFlags(win, attrs);
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index 2811145..f41eed5 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -33,6 +33,8 @@
 import android.view.animation.Interpolator;
 import android.view.WindowManagerInternal;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  * Enables animating bounds of objects.
  *
@@ -103,7 +105,8 @@
                 com.android.internal.R.interpolator.fast_out_slow_in);
     }
 
-    private final class BoundsAnimator extends ValueAnimator
+    @VisibleForTesting
+    final class BoundsAnimator extends ValueAnimator
             implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener {
         private final AnimateBoundsUser mTarget;
         private final Rect mFrom = new Rect();
@@ -113,10 +116,12 @@
         private final boolean mMoveToFullScreen;
         // True if this this animation was cancelled and will be replaced the another animation from
         // the same {@link #AnimateBoundsUser} target.
-        private boolean mSkipAnimationEnd;
+        private boolean mSkipFinalResize;
         // True if this animation replaced a previous animation of the same
         // {@link #AnimateBoundsUser} target.
         private final boolean mSkipAnimationStart;
+        // True if this animation was cancelled by the user, not as a part of a replacing animation
+        private boolean mSkipAnimationEnd;
         // True if this animation is not replacing a previous animation, or if the previous
         // animation is animating to a different fullscreen state than the current animation.
         // We use this to ensure that we always provide a consistent set/order of callbacks when we
@@ -200,7 +205,11 @@
                 // Whoops, the target doesn't feel like animating anymore. Let's immediately finish
                 // any further animation.
                 if (DEBUG) Slog.d(TAG, "animateUpdate: cancelled");
-                animation.cancel();
+
+                // Since we are cancelling immediately without a replacement animation, send the
+                // animation end to maintain callback parity, but also skip any further resizes
+                prepareCancel(false /* skipAnimationEnd */, true /* skipFinalResize */);
+                cancel();
             }
         }
 
@@ -208,7 +217,7 @@
         public void onAnimationEnd(Animator animation) {
             if (DEBUG) Slog.d(TAG, "onAnimationEnd: mTarget=" + mTarget
                     + " mMoveToFullScreen=" + mMoveToFullScreen
-                    + " mSkipAnimationEnd=" + mSkipAnimationEnd
+                    + " mSkipFinalResize=" + mSkipFinalResize
                     + " mFinishAnimationAfterTransition=" + mFinishAnimationAfterTransition
                     + " mAppTransitionIsRunning=" + mAppTransition.isRunning());
 
@@ -222,10 +231,15 @@
                 return;
             }
 
+            if (!mSkipFinalResize) {
+                // If not cancelled, resize the pinned stack to the final size. All calls to
+                // setPinnedStackSize() must be done between onAnimationStart() and onAnimationEnd()
+                mTarget.setPinnedStackSize(mTo, null);
+            }
+
             finishAnimation();
 
-            mTarget.setPinnedStackSize(mTo, null);
-            if (mMoveToFullScreen && !mSkipAnimationEnd) {
+            if (mMoveToFullScreen && !mSkipFinalResize) {
                 mTarget.moveToFullscreen();
             }
         }
@@ -235,10 +249,16 @@
             finishAnimation();
         }
 
+        public void prepareCancel(boolean skipAnimationEnd, boolean skipFinalResize) {
+            if (DEBUG) Slog.d(TAG, "prepareCancel: skipAnimationEnd=" + skipAnimationEnd
+                    + " skipFinalResize=" + skipFinalResize);
+            mSkipAnimationEnd = skipAnimationEnd;
+            mSkipFinalResize = skipFinalResize;
+        }
+
         @Override
         public void cancel() {
-            mSkipAnimationEnd = true;
-            if (DEBUG) Slog.d(TAG, "cancel: willReplace mTarget=" + mTarget);
+            if (DEBUG) Slog.d(TAG, "cancel: mTarget=" + mTarget);
             super.cancel();
         }
 
@@ -273,19 +293,15 @@
 
     public interface AnimateBoundsUser {
         /**
-         * Asks the target to directly (without any intermediate steps, like scheduling animation)
-         * resize its bounds.
-         *
-         * @return Whether the target still wants to be animated and successfully finished the
-         * operation. If it returns false, the animation will immediately be cancelled. The target
-         * should return false when something abnormal happened, e.g. it was completely removed
-         * from the hierarchy and is not valid anymore.
-         */
-        boolean setSize(Rect bounds);
-        /**
-         * Behaves as setSize, but freezes the bounds of any tasks in the target at taskBounds,
+         * Sets the size of the target (without any intermediate steps, like scheduling animation)
+         * but freezes the bounds of any tasks in the target at taskBounds,
          * to allow for more flexibility during resizing. Only works for the pinned stack at the
          * moment.
+         *
+         * @return Whether the target should continue to be animated and this call was successful.
+         * If false, the animation will be cancelled because the user has determined that the
+         * animation is now invalid and not required. In such a case, the cancel will trigger the
+         * animation end callback as well, but will not send any further size changes.
          */
         boolean setPinnedStackSize(Rect bounds, Rect taskBounds);
 
@@ -310,11 +326,20 @@
          */
         void onAnimationEnd();
 
+        /**
+         * Callback for the target to inform it to reparent to the fullscreen stack.
+         */
         void moveToFullscreen();
     }
 
-    void animateBounds(final AnimateBoundsUser target, Rect from, Rect to, int animationDuration,
-            boolean moveToFullscreen) {
+    public void animateBounds(final AnimateBoundsUser target, Rect from, Rect to,
+            int animationDuration, boolean moveToFullscreen) {
+        animateBoundsImpl(target, from, to, animationDuration, moveToFullscreen);
+    }
+
+    @VisibleForTesting
+    BoundsAnimator animateBoundsImpl(final AnimateBoundsUser target, Rect from, Rect to,
+            int animationDuration, boolean moveToFullscreen) {
         final BoundsAnimator existing = mRunningAnimations.get(target);
         final boolean replacing = existing != null;
         final boolean animatingToNewFullscreenState = (existing == null) ||
@@ -326,12 +351,15 @@
 
         if (replacing) {
             if (existing.isAnimatingTo(to)) {
-                // Just les the current animation complete if it has the same destination as the
+                // Just let the current animation complete if it has the same destination as the
                 // one we are trying to start.
                 if (DEBUG) Slog.d(TAG, "animateBounds: same destination as existing=" + existing
                         + " ignoring...");
-                return;
+                return existing;
             }
+            // Since we are replacing, we skip both animation start and end callbacks, and don't
+            // animate to the final bounds when cancelling
+            existing.prepareCancel(true /* skipAnimationEnd */, true /* skipFinalResize */);
             existing.cancel();
         }
         final BoundsAnimator animator = new BoundsAnimator(target, from, to, moveToFullscreen,
@@ -342,5 +370,6 @@
                 : DEFAULT_TRANSITION_DURATION) * DEBUG_ANIMATION_SLOW_DOWN_FACTOR);
         animator.setInterpolator(mFastOutSlowInInterpolator);
         animator.start();
+        return animator;
     }
 }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 2f64cd4..058fdae 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1420,6 +1420,13 @@
                 changedStackList.add(stack.mStackId);
             }
         }
+
+        // If there was no pinned stack, we still need to notify the controller of the display info
+        // update as a result of the config change.  We do this here to consolidate the flow between
+        // changes when there is and is not a stack.
+        if (getStackById(PINNED_STACK_ID) == null) {
+            mPinnedStackControllerLocked.onDisplayInfoChanged();
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 3ce61f0..1684878 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -147,7 +147,6 @@
 
     void onConfigurationChanged() {
         reloadResources();
-        notifyMovementBoundsChanged(false /* fromImeAdjustment */);
     }
 
     /**
@@ -241,13 +240,31 @@
     }
 
     /**
+     * In the case where the display rotation is changed but there is no stack, we can't depend on
+     * onTaskStackBoundsChanged() to be called.  But we still should update our known display info
+     * with the new state so that we can update SystemUI.
+     */
+    synchronized void onDisplayInfoChanged() {
+        mDisplayInfo.copyFrom(mDisplayContent.getDisplayInfo());
+        notifyMovementBoundsChanged(false /* fromImeAdjustment */);
+    }
+
+    /**
      * Updates the display info, calculating and returning the new stack and movement bounds in the
      * new orientation of the device if necessary.
      */
-    void onTaskStackBoundsChanged(Rect targetBounds, Rect outBounds) {
+    boolean onTaskStackBoundsChanged(Rect targetBounds, Rect outBounds) {
         final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
         if (mDisplayInfo.equals(displayInfo)) {
-            return;
+            // We are already in the right orientation, ignore
+            outBounds.setEmpty();
+            return false;
+        } else if (targetBounds.isEmpty()) {
+            // The stack is null, we are just initializing the stack, so just store the display info
+            // and ignore
+            mDisplayInfo.copyFrom(displayInfo);
+            outBounds.setEmpty();
+            return false;
         }
 
         mTmpRect.set(targetBounds);
@@ -272,6 +289,7 @@
         notifyMovementBoundsChanged(false /* fromImeAdjustment */);
 
         outBounds.set(postChangeStackBounds);
+        return true;
     }
 
     /**
@@ -371,7 +389,7 @@
                 final Rect animatingBounds = mTmpAnimatingBoundsRect;
                 final TaskStack pinnedStack = mDisplayContent.getStackById(PINNED_STACK_ID);
                 if (pinnedStack != null) {
-                    pinnedStack.getAnimatingBounds(animatingBounds);
+                    pinnedStack.getAnimationOrCurrentBounds(animatingBounds);
                 } else {
                     animatingBounds.set(normalBounds);
                 }
diff --git a/services/core/java/com/android/server/wm/PinnedStackWindowController.java b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
index 0145454..135832e 100644
--- a/services/core/java/com/android/server/wm/PinnedStackWindowController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
@@ -32,8 +32,8 @@
 
     private Rect mTmpBoundsRect = new Rect();
 
-    public PinnedStackWindowController(int stackId, StackWindowListener listener, int displayId,
-            boolean onTop, Rect outBounds) {
+    public PinnedStackWindowController(int stackId, PinnedStackWindowListener listener,
+            int displayId, boolean onTop, Rect outBounds) {
         super(stackId, listener, displayId, onTop, outBounds, WindowManagerService.getInstance());
     }
 
@@ -63,7 +63,7 @@
 
             final Rect originalBounds = new Rect();
             mContainer.getBounds(originalBounds);
-            mContainer.setAnimatingBounds(sourceBounds, toBounds);
+            mContainer.setAnimationFinalBounds(sourceBounds, toBounds);
             UiThread.getHandler().post(() -> {
                 if (mContainer == null) {
                     return;
@@ -84,9 +84,10 @@
             }
 
             final int displayId = mContainer.getDisplayContent().getDisplayId();
-            final Rect toBounds = mService.getPictureInPictureBounds(displayId, aspectRatio);
+            final Rect toBounds = mService.getPictureInPictureBounds(displayId, aspectRatio,
+                    true /* useExistingStackBounds */);
             final Rect targetBounds = new Rect();
-            mContainer.getAnimatingBounds(targetBounds);
+            mContainer.getAnimationOrCurrentBounds(targetBounds);
             final PinnedStackController pinnedStackController =
                     mContainer.getDisplayContent().getPinnedStackController();
 
@@ -117,8 +118,12 @@
     /**
      * @return whether the bounds are currently animating to fullscreen.
      */
-    public boolean isBoundsAnimatingToFullscreen() {
-        return mContainer.isBoundsAnimatingToFullscreen();
+    public boolean isAnimatingBoundsToFullscreen() {
+        return mContainer.isAnimatingBoundsToFullscreen();
+    }
+
+    public boolean pinnedStackResizeAllowed() {
+        return mContainer.pinnedStackResizeAllowed();
     }
 
     /**
@@ -132,4 +137,16 @@
         }
         return bounds;
     }
+
+    /**
+     * The following calls are made from WM to AM.
+     */
+
+    /** Calls directly into activity manager so window manager lock shouldn't held. */
+    public void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {
+        if (mListener != null) {
+            PinnedStackWindowListener listener = (PinnedStackWindowListener) mListener;
+            listener.updatePictureInPictureModeForPinnedStackAnimation(targetStackBounds);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/PinnedStackWindowListener.java b/services/core/java/com/android/server/wm/PinnedStackWindowListener.java
new file mode 100644
index 0000000..12b9c1f
--- /dev/null
+++ b/services/core/java/com/android/server/wm/PinnedStackWindowListener.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 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.graphics.Rect;
+
+/**
+ * Interface used by the creator of {@link PinnedStackWindowController} to listen to changes with
+ * the stack container.
+ */
+public interface PinnedStackWindowListener extends StackWindowListener {
+
+    /**
+     * Called when the stack container pinned stack animation will change the picture-in-picture
+     * mode. This is a direct call into ActivityManager.
+     */
+    default void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {}
+}
diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java
index bf024cf..b927e67 100644
--- a/services/core/java/com/android/server/wm/StackWindowController.java
+++ b/services/core/java/com/android/server/wm/StackWindowController.java
@@ -368,13 +368,6 @@
         }
     }
 
-    /** Calls directly into activity manager so window manager lock shouldn't held. */
-    void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {
-        if (mListener != null) {
-            mListener.updatePictureInPictureModeForPinnedStackAnimation(targetStackBounds);
-        }
-    }
-
     void requestResize(Rect bounds) {
         mHandler.obtainMessage(H.REQUEST_RESIZE, bounds).sendToTarget();
     }
diff --git a/services/core/java/com/android/server/wm/StackWindowListener.java b/services/core/java/com/android/server/wm/StackWindowListener.java
index a55f9df..c763c17 100644
--- a/services/core/java/com/android/server/wm/StackWindowListener.java
+++ b/services/core/java/com/android/server/wm/StackWindowListener.java
@@ -26,10 +26,4 @@
 
     /** Called when the stack container would like its controller to resize. */
     void requestResize(Rect bounds);
-
-    /**
-     * Called when the stack container pinned stack animation will change the picture-in-picture
-     * mode. This is a direct call into ActivityManager.
-     */
-    default void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {}
 }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index b816d81..5c46ca9 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -595,8 +595,7 @@
      * we will have a jump at the end.
      */
     boolean isFloating() {
-        return StackId.tasksAreFloating(mStack.mStackId)
-            && !mStack.isBoundsAnimatingToFullscreen();
+        return StackId.tasksAreFloating(mStack.mStackId) && !mStack.isAnimatingBoundsToFullscreen();
     }
 
     WindowState getTopVisibleAppMainWindow() {
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 1a67ac7..d7c41d3 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -77,6 +77,7 @@
     /** For comparison with DisplayContent bounds. */
     private Rect mTmpRect = new Rect();
     private Rect mTmpRect2 = new Rect();
+    private Rect mTmpRect3 = new Rect();
 
     /** Content limits relative to the DisplayContent this sits in. */
     private Rect mBounds = new Rect();
@@ -125,7 +126,11 @@
     // perfectly fit the region it would have been cropped to. We may also avoid certain logic we
     // would otherwise apply while resizing, while resizing in the bounds animating mode.
     private boolean mBoundsAnimating = false;
+    // Set when an animation has been requested but has not yet started from the UI thread. This is
+    // cleared when the animation actually starts.
+    private boolean mBoundsAnimatingRequested = false;
     private boolean mBoundsAnimatingToFullscreen = false;
+    private boolean mCancelCurrentBoundsAnimation = false;
     private Rect mBoundsAnimationTarget = new Rect();
     private Rect mBoundsAnimationSourceBounds = new Rect();
 
@@ -262,12 +267,6 @@
 
         if (mDisplayContent != null) {
             mDisplayContent.mDimLayerController.updateDimLayer(this);
-            if (mStackId == PINNED_STACK_ID) {
-                // Update the bounds based on any changes to the display info
-                getAnimatingBounds(mTmpRect2);
-                mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(mTmpRect2,
-                        bounds);
-            }
             mAnimationBackgroundSurface.setBounds(bounds);
         }
 
@@ -320,10 +319,11 @@
     }
 
     /**
-     * Sets the bounds animation target bounds.  This can't currently be done in onAnimationStart()
-     * since that is started on the UiThread.
+     * Sets the bounds animation target bounds ahead of an animation.  This can't currently be done
+     * in onAnimationStart() since that is started on the UiThread.
      */
-    void setAnimatingBounds(Rect sourceBounds, Rect destBounds) {
+    void setAnimationFinalBounds(Rect sourceBounds, Rect destBounds) {
+        mBoundsAnimatingRequested = true;
         if (sourceBounds != null) {
             mBoundsAnimationSourceBounds.set(sourceBounds);
         } else {
@@ -337,23 +337,26 @@
     }
 
     /**
-     * @return the source bounds for the bounds animation.
+     * @return the final bounds for the bounds animation.
      */
-    void getAnimatingSourceBounds(Rect outBounds) {
-        if (!mBoundsAnimationSourceBounds.isEmpty()) {
-            outBounds.set(mBoundsAnimationSourceBounds);
-            return;
-        }
-        outBounds.setEmpty();
+    void getFinalAnimationBounds(Rect outBounds) {
+        outBounds.set(mBoundsAnimationTarget);
     }
 
     /**
-     * @return the bounds that the task stack is currently being animated towards, or the current
-     *         stack bounds if there is no animation in progress.
+     * @return the final source bounds for the bounds animation.
      */
-    void getAnimatingBounds(Rect outBounds) {
-        if (!mBoundsAnimationTarget.isEmpty()) {
-            outBounds.set(mBoundsAnimationTarget);
+    void getFinalAnimationSourceBounds(Rect outBounds) {
+        outBounds.set(mBoundsAnimationSourceBounds);
+    }
+
+    /**
+     * @return the final animation bounds if the task stack is currently being animated, or the
+     *         current stack bounds otherwise.
+     */
+    void getAnimationOrCurrentBounds(Rect outBounds) {
+        if ((mBoundsAnimatingRequested || mBoundsAnimating) && !mBoundsAnimationTarget.isEmpty()) {
+            getFinalAnimationBounds(outBounds);
             return;
         }
         getBounds(outBounds);
@@ -398,6 +401,24 @@
             // as it's going away soon anyway.
             return false;
         }
+
+        if (mStackId == PINNED_STACK_ID) {
+            getAnimationOrCurrentBounds(mTmpRect2);
+            boolean updated = mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(
+                    mTmpRect2, mTmpRect3);
+            if (updated) {
+                mBoundsAfterRotation.set(mTmpRect3);
+
+                // Once we've set the bounds based on the rotation of the old bounds in the new
+                // orientation, clear the animation target bounds since they are obsolete, and
+                // cancel any currently running animations
+                mBoundsAnimationTarget.setEmpty();
+                mBoundsAnimationSourceBounds.setEmpty();
+                mCancelCurrentBoundsAnimation = true;
+                return true;
+            }
+        }
+
         final int newRotation = getDisplayInfo().rotation;
         final int newDensity = getDisplayInfo().logicalDensityDpi;
 
@@ -413,20 +434,6 @@
             return false;
         }
 
-        if (StackId.tasksAreFloating(mStackId)) {
-            // Update stack bounds again since the display info has changed since updateDisplayInfo,
-            // however, for floating tasks, we don't need to apply the new rotation to the bounds,
-            // we can just update and return them here
-            setBounds(mBounds);
-            mBoundsAfterRotation.set(mBounds);
-
-            // Once we've set the bounds based on the rotation of the old bounds in the new
-            // orientation, clear the animation target bounds since they are obsolete
-            mBoundsAnimationTarget.setEmpty();
-            mBoundsAnimationSourceBounds.setEmpty();
-            return true;
-        }
-
         mTmpRect2.set(mBounds);
         mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
         switch (mStackId) {
@@ -692,6 +699,14 @@
             getStackDockedModeBounds(mTmpRect, bounds, mStackId, mTmpRect2,
                     mDisplayContent.mDividerControllerLocked.getContentWidth(),
                     dockedOnTopOrLeft);
+        } else if (mStackId == PINNED_STACK_ID) {
+            // Update the bounds based on any changes to the display info
+            getAnimationOrCurrentBounds(mTmpRect2);
+            boolean updated = mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(
+                    mTmpRect2, mTmpRect3);
+            if (updated) {
+                bounds = new Rect(mTmpRect3);
+            }
         }
 
         updateDisplayInfo(bounds);
@@ -1443,21 +1458,11 @@
         }
     }
 
-    @Override  // AnimatesBounds
-    public boolean setSize(Rect bounds) {
-        synchronized (mService.mWindowMap) {
-            if (mDisplayContent == null) {
-                return false;
-            }
-        }
-        try {
-            mService.mActivityManager.resizeStack(mStackId, bounds, false, true, false, -1);
-        } catch (RemoteException e) {
-        }
-        return true;
-    }
-
     public boolean setPinnedStackSize(Rect bounds, Rect tempTaskBounds) {
+        if (mCancelCurrentBoundsAnimation) {
+            return false;
+        }
+
         try {
             mService.mActivityManager.resizePinnedStack(bounds, tempTaskBounds);
         } catch (RemoteException e) {
@@ -1469,8 +1474,10 @@
     @Override  // AnimatesBounds
     public void onAnimationStart(boolean toFullscreen) {
         synchronized (mService.mWindowMap) {
+            mBoundsAnimatingRequested = false;
             mBoundsAnimating = true;
             mBoundsAnimatingToFullscreen = toFullscreen;
+            mCancelCurrentBoundsAnimation = false;
         }
 
         if (mStackId == PINNED_STACK_ID) {
@@ -1484,7 +1491,8 @@
 
     @Override  // AnimatesBounds
     public void updatePictureInPictureMode(Rect targetStackBounds) {
-        final StackWindowController controller = getController();
+        final PinnedStackWindowController controller =
+                (PinnedStackWindowController) getController();
         if (controller != null) {
             controller.updatePictureInPictureModeForPinnedStackAnimation(targetStackBounds);
         }
@@ -1523,14 +1531,21 @@
         return mBoundsAnimating;
     }
 
-    public boolean getBoundsAnimating() {
+    public boolean isAnimatingBounds() {
         return mBoundsAnimating;
     }
 
-    public boolean isBoundsAnimatingToFullscreen() {
+    public boolean isAnimatingBoundsToFullscreen() {
         return mBoundsAnimating && mBoundsAnimatingToFullscreen;
     }
 
+    public boolean pinnedStackResizeAllowed() {
+        if (mBoundsAnimating && mCancelCurrentBoundsAnimation) {
+            return true;
+        }
+        return false;
+    }
+
     /** Returns true if a removal action is still being deferred. */
     boolean checkCompleteDeferredRemoval() {
         if (isAnimating()) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0f4707e..0049585 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -31,7 +31,6 @@
 import static android.os.Process.SYSTEM_UID;
 import static android.os.Process.THREAD_PRIORITY_DISPLAY;
 import static android.os.Process.myPid;
-import static android.os.Process.myTid;
 import static android.os.UserHandle.USER_NULL;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.DOCKED_INVALID;
@@ -148,7 +147,6 @@
 import android.os.PowerManager;
 import android.os.PowerManagerInternal;
 import android.os.PowerSaveState;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StrictMode;
@@ -2758,7 +2756,12 @@
         mDockedStackCreateBounds = bounds;
     }
 
-    public Rect getPictureInPictureBounds(int displayId, float aspectRatio) {
+    /**
+     * @param useExistingStackBounds Apply {@param aspectRatio} to the existing target stack bounds
+     *                               if possible
+     */
+    public Rect getPictureInPictureBounds(int displayId, float aspectRatio,
+            boolean useExistingStackBounds) {
         synchronized (mWindowMap) {
             if (!mSupportsPictureInPicture) {
                 return null;
@@ -2773,11 +2776,11 @@
             final PinnedStackController pinnedStackController =
                     displayContent.getPinnedStackController();
             final TaskStack stack = displayContent.getStackById(PINNED_STACK_ID);
-            if (stack != null) {
+            if (stack != null && useExistingStackBounds) {
                 // If the stack exists, then use its final bounds to calculate the new aspect ratio
                 // bounds.
                 stackBounds = new Rect();
-                stack.getAnimatingBounds(stackBounds);
+                stack.getAnimationOrCurrentBounds(stackBounds);
             } else {
                 // Otherwise, just calculate the aspect ratio bounds from the default bounds
                 stackBounds = pinnedStackController.getDefaultBounds();
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 979af7e..0b96f3f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1090,7 +1090,7 @@
         // notify the client of frame changes in this case. Not only is it a lot of churn, but
         // the frame may not correspond to the surface size or the onscreen area at various
         // phases in the animation, and the client will become sad and confused.
-        if (task != null && task.mStack.getBoundsAnimating()) {
+        if (task != null && task.mStack.isAnimatingBounds()) {
             return;
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index ae17d08..fa35336 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1360,11 +1360,11 @@
             int posX = mTmpSize.left;
             int posY = mTmpSize.top;
             task.mStack.getDimBounds(mTmpStackBounds);
-            task.mStack.getAnimatingSourceBounds(mTmpSourceBounds);
+            task.mStack.getFinalAnimationSourceBounds(mTmpSourceBounds);
             if (!mTmpSourceBounds.isEmpty()) {
                 // Get the final target stack bounds, if we are not animating, this is just the
                 // current stack bounds
-                task.mStack.getAnimatingBounds(mTmpAnimatingBounds);
+                task.mStack.getFinalAnimationBounds(mTmpAnimatingBounds);
 
                 // Calculate the current progress and interpolate the difference between the target
                 // and source bounds
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 67f1a0a..42a9232 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -981,6 +981,11 @@
                     traceBeginAndSlog("StartPersistentDataBlock");
                     mSystemServiceManager.startService(PersistentDataBlockService.class);
                     traceEnd();
+
+                    // Implementation depends on persistent data block
+                    traceBeginAndSlog("StartOemLockService");
+                    mSystemServiceManager.startService(OemLockService.class);
+                    traceEnd();
                 }
 
                 traceBeginAndSlog("StartDeviceIdleController");
diff --git a/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java b/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java
index d14f4eb..013eab8 100644
--- a/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java
+++ b/services/retaildemo/java/com/android/server/retaildemo/UserInactivityCountdownDialog.java
@@ -67,7 +67,7 @@
     @Override
     public void show() {
         super.show();
-        final TextView messageView = (TextView) findViewById(R.id.message);
+        final TextView messageView = findViewById(R.id.message);
         messageView.post(new Runnable() {
             @Override
             public void run() {
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index 00f6273..20839c5 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -117,6 +117,7 @@
     @Captor private ArgumentCaptor<Bundle> mBundleCaptor;
     private int mVisibleAccountsChangedBroadcasts;
     private int mLoginAccountsChangedBroadcasts;
+    private int mAccountRemovedBroadcasts;
 
     private static final int LATCH_TIMEOUT_MS = 500;
     private static final String PREN_DB = "pren.db";
@@ -2510,6 +2511,7 @@
         updateBroadcastCounters(2);
         assertEquals(mVisibleAccountsChangedBroadcasts, 0); // broadcast was not sent
         assertEquals(mLoginAccountsChangedBroadcasts, 2);
+        assertEquals(mAccountRemovedBroadcasts, 0);
     }
 
     @SmallTest
@@ -2533,9 +2535,10 @@
         mAms.registerAccountListener( null /* accountTypes */, "testpackage");
         mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_INTERVENE);
 
-        updateBroadcastCounters(6);
+        updateBroadcastCounters(8);
         assertEquals(mVisibleAccountsChangedBroadcasts, 2);
         assertEquals(mLoginAccountsChangedBroadcasts, 4);
+        assertEquals(mAccountRemovedBroadcasts, 2);
     }
 
     @SmallTest
@@ -2560,17 +2563,19 @@
             "testpackage3"); // opPackageName
         // Remove account with 2 active listeners.
         mAms.removeAccountInternal(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS);
-        updateBroadcastCounters(7);
+        updateBroadcastCounters(8);
         assertEquals(mVisibleAccountsChangedBroadcasts, 5);
         assertEquals(mLoginAccountsChangedBroadcasts, 2); // 3 add, 2 remove
+        assertEquals(mAccountRemovedBroadcasts, 1);
 
         // Add account of another type.
         mAms.addAccountExplicitly(
             AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS_TYPE_2, "p11", null);
 
-        updateBroadcastCounters(8);
+        updateBroadcastCounters(9);
         assertEquals(mVisibleAccountsChangedBroadcasts, 5);
         assertEquals(mLoginAccountsChangedBroadcasts, 3);
+        assertEquals(mAccountRemovedBroadcasts, 1);
     }
 
     @SmallTest
@@ -2602,16 +2607,20 @@
     private void updateBroadcastCounters (int expectedBroadcasts){
         mVisibleAccountsChangedBroadcasts = 0;
         mLoginAccountsChangedBroadcasts = 0;
+        mAccountRemovedBroadcasts = 0;
         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
         verify(mMockContext, times(expectedBroadcasts)).sendBroadcastAsUser(captor.capture(),
             any(UserHandle.class));
         for (Intent intent : captor.getAllValues()) {
-            if (AccountManager.ACTION_VISIBLE_ACCOUNTS_CHANGED. equals(intent.getAction())) {
+            if (AccountManager.ACTION_VISIBLE_ACCOUNTS_CHANGED.equals(intent.getAction())) {
                 mVisibleAccountsChangedBroadcasts++;
             }
-            if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION. equals(intent.getAction())) {
+            if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION.equals(intent.getAction())) {
                 mLoginAccountsChangedBroadcasts++;
             }
+            if (AccountManager.ACTION_ACCOUNT_REMOVED.equals(intent.getAction())) {
+                mAccountRemovedBroadcasts++;
+            }
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
new file mode 100644
index 0000000..85dc712
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2017 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.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Looper;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.WindowManagerInternal.AppTransitionListener;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.server.wm.BoundsAnimationController.BoundsAnimator;
+
+/**
+ * Test class for {@link BoundsAnimationController} to ensure that it sends the right callbacks
+ * depending on the various interactions.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.wm.BoundsAnimationControllerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class BoundsAnimationControllerTests extends WindowTestsBase {
+
+    /**
+     * Mock value animator to simulate updates with.
+     */
+    private class MockValueAnimator extends ValueAnimator {
+
+        private float mFraction;
+
+        public MockValueAnimator getWithValue(float fraction) {
+            mFraction = fraction;
+            return this;
+        }
+
+        @Override
+        public Object getAnimatedValue() {
+            return mFraction;
+        }
+    }
+
+    /**
+     * Mock app transition to fire notifications to the bounds animator.
+     */
+    private class MockAppTransition extends AppTransition {
+
+        private AppTransitionListener mListener;
+
+        MockAppTransition(Context context) {
+            super(context, null);
+        }
+
+        @Override
+        void registerListenerLocked(AppTransitionListener listener) {
+            mListener = listener;
+        }
+
+        public void notifyTransitionPending() {
+            mListener.onAppTransitionPendingLocked();
+        }
+
+        public void notifyTransitionCancelled(int transit) {
+            mListener.onAppTransitionCancelledLocked(transit);
+        }
+
+        public void notifyTransitionStarting(int transit) {
+            mListener.onAppTransitionStartingLocked(transit, null, null, null, null);
+        }
+
+        public void notifyTransitionFinished() {
+            mListener.onAppTransitionFinishedLocked(null);
+        }
+    }
+
+    /**
+     * A test animate bounds user to track callbacks from the bounds animation.
+     */
+    private class TestAnimateBoundsUser implements BoundsAnimationController.AnimateBoundsUser {
+
+        boolean mMovedToFullscreen;
+        boolean mAnimationStarted;
+        boolean mAnimationStartedToFullscreen;
+        boolean mAnimationEnded;
+        boolean mUpdatedPictureInPictureModeWithBounds;
+        boolean mBoundsUpdated;
+        Rect mStackBounds;
+        Rect mTaskBounds;
+
+        boolean mRequestCancelAnimation = false;
+
+        void reinitialize(Rect stackBounds, Rect taskBounds) {
+            mMovedToFullscreen = false;
+            mAnimationStarted = false;
+            mAnimationStartedToFullscreen = false;
+            mAnimationEnded = false;
+            mUpdatedPictureInPictureModeWithBounds = false;
+            mStackBounds = stackBounds;
+            mTaskBounds = taskBounds;
+            mBoundsUpdated = false;
+            mRequestCancelAnimation = false;
+        }
+
+        @Override
+        public void onAnimationStart(boolean toFullscreen) {
+            mAnimationStarted = true;
+            mAnimationStartedToFullscreen = toFullscreen;
+        }
+
+        @Override
+        public void updatePictureInPictureMode(Rect targetStackBounds) {
+            mUpdatedPictureInPictureModeWithBounds = true;
+        }
+
+        @Override
+        public boolean setPinnedStackSize(Rect stackBounds, Rect taskBounds) {
+            // TODO: Once we break the runs apart, we should fail() here if this is called outside
+            //       of onAnimationStart() and onAnimationEnd()
+            if (mRequestCancelAnimation) {
+                return false;
+            } else {
+                mBoundsUpdated = true;
+                mStackBounds = stackBounds;
+                mTaskBounds = taskBounds;
+                return true;
+            }
+        }
+
+        @Override
+        public void onAnimationEnd() {
+            mAnimationEnded = true;
+        }
+
+        @Override
+        public void moveToFullscreen() {
+            mMovedToFullscreen = true;
+        }
+    }
+
+    // Constants
+    private static final boolean MOVE_TO_FULLSCREEN = true;
+
+    // Some dummy bounds to represent fullscreen and floating bounds
+    private static final Rect BOUNDS_FULL = new Rect(0, 0, 100, 100);
+    private static final Rect BOUNDS_FLOATING = new Rect(80, 80, 95, 95);
+    private static final Rect BOUNDS_ALT_FLOATING = new Rect(60, 60, 95, 95);
+
+    // Some dummy duration
+    private static final int DURATION = 100;
+
+    // Common
+    private MockAppTransition mAppTransition;
+    private MockValueAnimator mAnimator;
+    private TestAnimateBoundsUser mTarget;
+    private BoundsAnimationController mController;
+
+    // Temp
+    private Rect mTmpRect = new Rect();
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        final Context context = InstrumentationRegistry.getTargetContext();
+        final Handler handler = new Handler(Looper.getMainLooper());
+        mAppTransition = new MockAppTransition(context);
+        mAnimator = new MockValueAnimator();
+        mTarget = new TestAnimateBoundsUser();
+        mController = new BoundsAnimationController(context, mAppTransition, handler);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFullscreenToFloatingTransition() throws Exception {
+        // Create and start the animation
+        mTarget.reinitialize(BOUNDS_FULL, null);
+        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
+                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
+
+        // Assert that when we are started, and that we are not going to fullscreen
+        assertTrue(mTarget.mAnimationStarted);
+        assertFalse(mTarget.mAnimationStartedToFullscreen);
+        // Ensure we are not triggering a PiP mode change
+        assertFalse(mTarget.mUpdatedPictureInPictureModeWithBounds);
+        // Ensure that the task stack bounds are already frozen to the larger source stack bounds
+        assertEquals(BOUNDS_FULL, mTarget.mStackBounds);
+        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
+
+        // Drive some animation updates, ensure that only the stack bounds change and the task
+        // bounds are frozen to the original stack bounds (adjusted for the offset)
+        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
+        assertNotEquals(BOUNDS_FULL, mTarget.mStackBounds);
+        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
+        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(1f));
+        assertNotEquals(BOUNDS_FULL, mTarget.mStackBounds);
+        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
+
+        // Finish the animation, ensure that it reaches the final bounds with the given state
+        boundsAnimator.end();
+        assertTrue(mTarget.mAnimationEnded);
+        assertEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
+        assertNull(mTarget.mTaskBounds);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testFloatingToFullscreenTransition() throws Exception {
+        // Create and start the animation
+        mTarget.reinitialize(BOUNDS_FULL, null);
+        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FLOATING,
+                BOUNDS_FULL, DURATION, MOVE_TO_FULLSCREEN);
+
+        // Assert that when we are started, and that we are going to fullscreen
+        assertTrue(mTarget.mAnimationStarted);
+        assertTrue(mTarget.mAnimationStartedToFullscreen);
+        // Ensure that we update the PiP mode change with the new fullscreen bounds
+        assertTrue(mTarget.mUpdatedPictureInPictureModeWithBounds);
+        // Ensure that the task stack bounds are already frozen to the larger target stack bounds
+        assertEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
+        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
+
+        // Drive some animation updates, ensure that only the stack bounds change and the task
+        // bounds are frozen to the original stack bounds (adjusted for the offset)
+        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
+        assertNotEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
+        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
+        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(1f));
+        assertNotEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
+        assertEquals(BOUNDS_FULL, offsetToZero(mTarget.mTaskBounds));
+
+        // Finish the animation, ensure that it reaches the final bounds with the given state
+        boundsAnimator.end();
+        assertTrue(mTarget.mAnimationEnded);
+        assertEquals(BOUNDS_FULL, mTarget.mStackBounds);
+        assertNull(mTarget.mTaskBounds);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testInterruptAnimationFromUser() throws Exception {
+        // Create and start the animation
+        mTarget.reinitialize(BOUNDS_FULL, null);
+        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
+                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
+
+        // Cancel the animation on the next update from the user
+        mTarget.mRequestCancelAnimation = true;
+        mTarget.mBoundsUpdated = false;
+        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
+        // Ensure that we got no more updates after returning false and the bounds are not updated
+        // to the end value
+        assertFalse(mTarget.mBoundsUpdated);
+        assertNotEquals(BOUNDS_FLOATING, mTarget.mStackBounds);
+        assertNotEquals(BOUNDS_FLOATING, mTarget.mTaskBounds);
+        // Ensure that we received the animation end call
+        assertTrue(mTarget.mAnimationEnded);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testCancelAnimationFromNewAnimationToExistingBounds() throws Exception {
+        // Create and start the animation
+        mTarget.reinitialize(BOUNDS_FULL, null);
+        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
+                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
+
+        // Drive some animation updates
+        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
+
+        // Cancel the animation as a restart to the same bounds
+        mTarget.reinitialize(null, null);
+        final BoundsAnimator altBoundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
+                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
+        // Ensure the animator is the same
+        assertSame(boundsAnimator, altBoundsAnimator);
+        // Ensure we haven't restarted or finished the animation
+        assertFalse(mTarget.mAnimationStarted);
+        assertFalse(mTarget.mAnimationEnded);
+        // Ensure that we haven't tried to update the PiP mode
+        assertFalse(mTarget.mUpdatedPictureInPictureModeWithBounds);
+    }
+
+    @UiThreadTest
+    @Test
+    public void testCancelAnimationFromNewAnimationToNewBounds() throws Exception {
+        // Create and start the animation
+        mTarget.reinitialize(BOUNDS_FULL, null);
+        final BoundsAnimator boundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
+                BOUNDS_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
+
+        // Drive some animation updates
+        boundsAnimator.onAnimationUpdate(mAnimator.getWithValue(0.5f));
+
+        // Cancel the animation as a restart to new bounds
+        mTarget.reinitialize(null, null);
+        final BoundsAnimator altBoundsAnimator = mController.animateBoundsImpl(mTarget, BOUNDS_FULL,
+                BOUNDS_ALT_FLOATING, DURATION, !MOVE_TO_FULLSCREEN);
+        // Ensure the animator is not the same
+        assertNotSame(boundsAnimator, altBoundsAnimator);
+        // Ensure that we did not get an animation start/end callback
+        assertFalse(mTarget.mAnimationStarted);
+        assertFalse(mTarget.mAnimationEnded);
+        // Ensure that we haven't tried to update the PiP mode
+        assertFalse(mTarget.mUpdatedPictureInPictureModeWithBounds);
+    }
+
+    /**
+     * @return the bounds offset to zero/zero.
+     */
+    private Rect offsetToZero(Rect bounds) {
+        mTmpRect.set(bounds);
+        mTmpRect.offsetTo(0, 0);
+        return mTmpRect;
+    }
+}
diff --git a/services/usb/Android.mk b/services/usb/Android.mk
index f560e71..f6d212b 100644
--- a/services/usb/Android.mk
+++ b/services/usb/Android.mk
@@ -8,7 +8,7 @@
       $(call all-java-files-under,java)
 
 LOCAL_JAVA_LIBRARIES := services.core
-LOCAL_STATIC_JAVA_LIBRARIES := android.hardware.usb@1.0-java-static \
-android.hidl.manager@1.0-java-static
+LOCAL_STATIC_JAVA_LIBRARIES := android.hardware.usb-V1.0-java-static \
+android.hidl.manager-V1.0-java-static
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index d60f25c..397aa00 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2710,19 +2710,12 @@
      * @param phoneAccountHandle the phone account to change the client state
      * @param enabled the new state of the client
      * @hide
+     * @deprecated Visual voicemail no longer in telephony. {@link VisualVoicemailService} should
+     * be implemented instead.
      */
     @SystemApi
     public void setVisualVoicemailEnabled(PhoneAccountHandle phoneAccountHandle, boolean enabled){
-        try {
-            ITelephony telephony = getITelephony();
-            if (telephony != null) {
-                telephony.setVisualVoicemailEnabled(mContext.getOpPackageName(), phoneAccountHandle,
-                    enabled);
-            }
-        } catch (RemoteException ex) {
-        } catch (NullPointerException ex) {
-            // This could happen before phone restarts due to crashing
-        }
+
     }
 
     /**
@@ -2734,19 +2727,11 @@
      * @param phoneAccountHandle the phone account to check for.
      * @return {@code true} when the visual voicemail client is enabled for this client
      * @hide
+     * @deprecated Visual voicemail no longer in telephony. {@link VisualVoicemailService} should
+     * be implemented instead.
      */
     @SystemApi
     public boolean isVisualVoicemailEnabled(PhoneAccountHandle phoneAccountHandle){
-        try {
-            ITelephony telephony = getITelephony();
-            if (telephony != null) {
-                return telephony.isVisualVoicemailEnabled(
-                    mContext.getOpPackageName(), phoneAccountHandle);
-            }
-        } catch (RemoteException ex) {
-        } catch (NullPointerException ex) {
-            // This could happen before phone restarts due to crashing
-        }
         return false;
     }
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index b461a78..dd08f67 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -498,12 +498,6 @@
       */
     boolean isConcurrentVoiceAndDataAllowed(int subId);
 
-    oneway void setVisualVoicemailEnabled(String callingPackage,
-            in PhoneAccountHandle accountHandle, boolean enabled);
-
-    boolean isVisualVoicemailEnabled(String callingPackage,
-            in PhoneAccountHandle accountHandle);
-
     String getVisualVoicemailPackageName(String callingPackage, int subId);
 
     // Not oneway, caller needs to make sure the vaule is set before receiving a SMS
diff --git a/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/SinkActivity.java b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/SinkActivity.java
index 6fe2cfb..fc1d47b 100644
--- a/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/SinkActivity.java
+++ b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/SinkActivity.java
@@ -95,13 +95,13 @@
 
         setContentView(R.layout.sink_activity);
 
-        mLogTextView = (TextView) findViewById(R.id.logTextView);
+        mLogTextView = findViewById(R.id.logTextView);
         mLogTextView.setMovementMethod(ScrollingMovementMethod.getInstance());
         mLogger = new TextLogger();
 
-        mFpsTextView = (TextView) findViewById(R.id.fpsTextView);
+        mFpsTextView = findViewById(R.id.fpsTextView);
 
-        mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
+        mSurfaceView = findViewById(R.id.surfaceView);
         mSurfaceView.setOnTouchListener(new View.OnTouchListener() {
             @Override
             public boolean onTouch(View v, MotionEvent event) {
diff --git a/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/SourceActivity.java b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/SourceActivity.java
index c59c958..a216102 100644
--- a/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/SourceActivity.java
+++ b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/SourceActivity.java
@@ -63,7 +63,7 @@
 
         setContentView(R.layout.source_activity);
 
-        mLogTextView = (TextView) findViewById(R.id.logTextView);
+        mLogTextView = findViewById(R.id.logTextView);
         mLogTextView.setMovementMethod(ScrollingMovementMethod.getInstance());
         mLogger = new TextLogger();
         mPresenter = new Presenter();
diff --git a/tests/ActivityTests/AndroidManifest.xml b/tests/ActivityTests/AndroidManifest.xml
index 64cdcf7..b381cbf 100644
--- a/tests/ActivityTests/AndroidManifest.xml
+++ b/tests/ActivityTests/AndroidManifest.xml
@@ -87,5 +87,13 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <activity android:name="CustomSplashscreenActivity"
+            android:label="CustomSplashscreen"
+            android:theme="@style/CustomSplashscreen">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
     </application>
 </manifest>
diff --git a/tests/ActivityTests/res/drawable/splashscreen.xml b/tests/ActivityTests/res/drawable/splashscreen.xml
new file mode 100644
index 0000000..01fb646
--- /dev/null
+++ b/tests/ActivityTests/res/drawable/splashscreen.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2017 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
+  -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item>
+        <bitmap
+            android:gravity="center"
+            android:src="@drawable/icon"/>
+    </item>
+</layer-list>
\ No newline at end of file
diff --git a/tests/ActivityTests/res/values/themes.xml b/tests/ActivityTests/res/values/themes.xml
index b8dd830..c11d2e4 100644
--- a/tests/ActivityTests/res/values/themes.xml
+++ b/tests/ActivityTests/res/values/themes.xml
@@ -26,4 +26,7 @@
         <item name="android:colorBackground">@color/blue</item>
         <item name="android:windowBackground">@color/blue</item>
     </style>
+    <style name="CustomSplashscreen" parent="@android:style/Theme.Material.Light.NoActionBar">
+        <item name="android:windowSplashscreenContent">@drawable/splashscreen</item>
+    </style>
 </resources>
diff --git a/tests/ActivityTests/src/com/google/android/test/activity/CustomSplashscreenActivity.java b/tests/ActivityTests/src/com/google/android/test/activity/CustomSplashscreenActivity.java
new file mode 100644
index 0000000..0683df6
--- /dev/null
+++ b/tests/ActivityTests/src/com/google/android/test/activity/CustomSplashscreenActivity.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 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.google.android.test.activity;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.os.SystemClock;
+
+/**
+ * Activity for which we set a custom splash screen.
+ */
+public class CustomSplashscreenActivity extends Activity {
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        SystemClock.sleep(2000);
+    }
+}
diff --git a/tests/AmSlam/Android.mk b/tests/AmSlam/Android.mk
index 8dafac7..934bae0 100644
--- a/tests/AmSlam/Android.mk
+++ b/tests/AmSlam/Android.mk
@@ -21,7 +21,7 @@
 
 LOCAL_PACKAGE_NAME := AmSlam
 
-LOCAL_SDK_VERSION := 21
+LOCAL_SDK_VERSION := current
 LOCAL_MIN_SDK_VERSION := 21
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 
diff --git a/tests/AmSlam/src/test/amslam/MainActivity.java b/tests/AmSlam/src/test/amslam/MainActivity.java
index cce955e..17fca09 100644
--- a/tests/AmSlam/src/test/amslam/MainActivity.java
+++ b/tests/AmSlam/src/test/amslam/MainActivity.java
@@ -60,7 +60,7 @@
         super.onCreate(savedInstanceState);
         sAppContext = getApplicationContext();
         setContentView(R.layout.activity_main);
-        mOutput = (TextView) findViewById(R.id.output);
+        mOutput = findViewById(R.id.output);
         PongReceiver.addListener(this);
 
         findViewById(R.id.run).setOnClickListener(view -> {
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
index b88a885..f85e82d 100644
--- a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
@@ -75,7 +75,7 @@
 
         setContentView(R.layout.main);
 
-        mList = (ListView) findViewById(R.id.testlist);
+        mList = findViewById(R.id.testlist);
         mList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
         mList.setFocusableInTouchMode(true);
         
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/AutomaticActivity.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/AutomaticActivity.java
index 1ed4723..8ccd4e2 100644
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/AutomaticActivity.java
+++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/AutomaticActivity.java
@@ -111,8 +111,8 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.automatic_layout);
 
-        mSoftwareImageView = (ImageView) findViewById(R.id.software_image_view);
-        mHardwareImageView = (ImageView) findViewById(R.id.hardware_image_view);
+        mSoftwareImageView = findViewById(R.id.software_image_view);
+        mHardwareImageView = findViewById(R.id.hardware_image_view);
 
         onCreateCommon(mRunnable);
         beginTest();
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java
index 8d8d9de..0dec1de 100644
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java
+++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java
@@ -57,7 +57,7 @@
         getWindow().setBackgroundDrawable(new ColorDrawable(0xffefefef));
         ResourceModifiers.init(getResources());
 
-        mHardwareView = (MainView) findViewById(R.id.hardware_view);
+        mHardwareView = findViewById(R.id.hardware_view);
         mHardwareView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
         mHardwareView.setBackgroundColor(Color.WHITE);
         mHardwareView.addDrawCallback(mDrawCallback);
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java b/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
index 78e360b..723c460 100644
--- a/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
@@ -162,19 +162,19 @@
         // in res/layout/hello_activity.xml
         setContentView(R.layout.main);
 
-        mFgSpinner = (Spinner) findViewById(R.id.fgspinner);
+        mFgSpinner = findViewById(R.id.fgspinner);
         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                 android.R.layout.simple_spinner_item, mAvailOpLabels);
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
         mFgSpinner.setAdapter(adapter);
         mFgSpinner.setOnItemSelectedListener(this);
-        mBgSpinner = (Spinner) findViewById(R.id.bgspinner);
+        mBgSpinner = findViewById(R.id.bgspinner);
         adapter = new ArrayAdapter<String>(this,
                 android.R.layout.simple_spinner_item, mAvailOpLabels);
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
         mBgSpinner.setAdapter(adapter);
         mBgSpinner.setOnItemSelectedListener(this);
-        mLimitSpinner = (Spinner) findViewById(R.id.limitspinner);
+        mLimitSpinner = findViewById(R.id.limitspinner);
         adapter = new ArrayAdapter<String>(this,
                 android.R.layout.simple_spinner_item, mLimitLabels);
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
diff --git a/tests/HugeBackup/src/com/android/hugebackup/HugeBackupActivity.java b/tests/HugeBackup/src/com/android/hugebackup/HugeBackupActivity.java
index 84e31aa..83c27fb 100644
--- a/tests/HugeBackup/src/com/android/hugebackup/HugeBackupActivity.java
+++ b/tests/HugeBackup/src/com/android/hugebackup/HugeBackupActivity.java
@@ -71,9 +71,9 @@
         setContentView(R.layout.backup_restore);
 
         /** Once the UI has been inflated, cache the controls for later */
-        mFillingGroup = (RadioGroup) findViewById(R.id.filling_group);
-        mAddMayoCheckbox = (CheckBox) findViewById(R.id.mayo);
-        mAddTomatoCheckbox = (CheckBox) findViewById(R.id.tomato);
+        mFillingGroup = findViewById(R.id.filling_group);
+        mAddMayoCheckbox = findViewById(R.id.mayo);
+        mAddTomatoCheckbox = findViewById(R.id.tomato);
 
         /** Set up our file bookkeeping */
         mDataFile = new File(getFilesDir(), HugeBackupActivity.DATA_FILE_NAME);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/DatePicker.java b/tests/HwAccelerationTest/src/com/android/test/hwui/DatePicker.java
index eb4e3fd..492d158 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/DatePicker.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/DatePicker.java
@@ -101,7 +101,7 @@
                         Context.LAYOUT_INFLATER_SERVICE);
         inflater.inflate(R.layout.date_picker, this, true);
 
-        mDayPicker = (NumberPicker) findViewById(R.id.day);
+        mDayPicker = findViewById(R.id.day);
         mDayPicker.setFormatter(NumberPicker.getTwoDigitFormatter());
         mDayPicker.setOnLongPressUpdateInterval(100);
         mDayPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@@ -110,7 +110,7 @@
                 notifyDateChanged();
             }
         });
-        mMonthPicker = (NumberPicker) findViewById(R.id.month);
+        mMonthPicker = findViewById(R.id.month);
         mMonthPicker.setFormatter(NumberPicker.getTwoDigitFormatter());
         DateFormatSymbols dfs = new DateFormatSymbols();
         String[] months = dfs.getShortMonths();
@@ -146,7 +146,7 @@
                 updateDaySpinner();
             }
         });
-        mYearPicker = (NumberPicker) findViewById(R.id.year);
+        mYearPicker = findViewById(R.id.year);
         mYearPicker.setOnLongPressUpdateInterval(100);
         mYearPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
             public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
@@ -158,7 +158,7 @@
             }
         });
 
-        mYearToggle = (CheckBox) findViewById(R.id.yearToggle);
+        mYearToggle = findViewById(R.id.yearToggle);
         mYearToggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
             @Override
             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
@@ -229,7 +229,7 @@
         /* Remove the 3 pickers from their parent and then add them back in the
          * required order.
          */
-        LinearLayout parent = (LinearLayout) findViewById(R.id.parent);
+        LinearLayout parent = findViewById(R.id.parent);
         parent.removeAllViews();
 
         boolean quoted = false;
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
index 0defe92..134c2e0 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
@@ -82,7 +82,7 @@
 
         ListAdapter adapter = new SimpleListAdapter(this);
 
-        final ListView list = (ListView) findViewById(R.id.list);
+        final ListView list = findViewById(R.id.list);
         list.setAdapter(adapter);
         
         registerForContextMenu(list);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/StackActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/StackActivity.java
index 5655adf..262b0e9 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/StackActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/StackActivity.java
@@ -35,7 +35,7 @@
 
         setContentView(R.layout.stack);
 
-        StackView stack = (StackView) findViewById(R.id.stack_view);
+        StackView stack = findViewById(R.id.stack_view);
         stack.setAdapter(new ArrayAdapter<Drawable>(this, android.R.layout.simple_list_item_1,
                 android.R.id.text1, new Drawable[] {
             getResources().getDrawable(R.drawable.sunset1),
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TransformsAndAnimationsActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TransformsAndAnimationsActivity.java
index 684d179..b5a5e02 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/TransformsAndAnimationsActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TransformsAndAnimationsActivity.java
@@ -55,23 +55,23 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.transforms_and_animations);
 
-        button1 = (Button) findViewById(R.id.button1);
-        button2 = (Button) findViewById(R.id.button2);
-        button3 = (Button) findViewById(R.id.button3);
-        button1a = (Button) findViewById(R.id.button1a);
-        button2a = (Button) findViewById(R.id.button2a);
-        button3a = (Button) findViewById(R.id.button3a);
-        button1b = (Button) findViewById(R.id.button1b);
-        button2b = (Button) findViewById(R.id.button2b);
-        button3b = (Button) findViewById(R.id.button3b);
-        button4 = (Button) findViewById(R.id.button4);
-        button5 = (Button) findViewById(R.id.button5);
-        button6 = (Button) findViewById(R.id.button6);
-        button7 = (Button) findViewById(R.id.button7);
-        button8 = (Button) findViewById(R.id.button8);
-        layersNoneCB = (CheckBox) findViewById(R.id.layersNoneCB);
-        layersHardwareCB = (CheckBox) findViewById(R.id.layersHwCB);
-        layersSoftwareCB = (CheckBox) findViewById(R.id.layersSwCB);
+        button1 = findViewById(R.id.button1);
+        button2 = findViewById(R.id.button2);
+        button3 = findViewById(R.id.button3);
+        button1a = findViewById(R.id.button1a);
+        button2a = findViewById(R.id.button2a);
+        button3a = findViewById(R.id.button3a);
+        button1b = findViewById(R.id.button1b);
+        button2b = findViewById(R.id.button2b);
+        button3b = findViewById(R.id.button3b);
+        button4 = findViewById(R.id.button4);
+        button5 = findViewById(R.id.button5);
+        button6 = findViewById(R.id.button6);
+        button7 = findViewById(R.id.button7);
+        button8 = findViewById(R.id.button8);
+        layersNoneCB = findViewById(R.id.layersNoneCB);
+        layersHardwareCB = findViewById(R.id.layersHwCB);
+        layersSoftwareCB = findViewById(R.id.layersSwCB);
 
         layersNoneCB.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
             @Override
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TransparentListActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TransparentListActivity.java
index ffb8689..deb8585 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/TransparentListActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TransparentListActivity.java
@@ -84,7 +84,7 @@
 
         ListAdapter adapter = new SimpleListAdapter(this);
 
-        ListView list = (ListView) findViewById(R.id.list);
+        ListView list = findViewById(R.id.list);
         list.setAdapter(adapter);
         list.setCacheColorHint(0);
         list.setVerticalFadingEdgeEnabled(true);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayerInvalidationActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayerInvalidationActivity.java
index 6d47d6c..a261fb7 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayerInvalidationActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayerInvalidationActivity.java
@@ -49,13 +49,13 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.view_layer_invalidation);
 
-        container = (LinearLayout) findViewById(R.id.container);
-        final LinearLayout container1 = (LinearLayout) findViewById(R.id.container1);
-        final LinearLayout container2 = (LinearLayout) findViewById(R.id.container2);
-        final LinearLayout container3 = (LinearLayout) findViewById(R.id.container3);
-        nestedStatusTV = (TextView) findViewById(R.id.nestedStatus);
-        invalidateStatusTV = (TextView) findViewById(R.id.invalidateStatus);
-        final TextView tva = (TextView) findViewById(R.id.textviewa);
+        container = findViewById(R.id.container);
+        final LinearLayout container1 = findViewById(R.id.container1);
+        final LinearLayout container2 = findViewById(R.id.container2);
+        final LinearLayout container3 = findViewById(R.id.container3);
+        nestedStatusTV = findViewById(R.id.nestedStatus);
+        invalidateStatusTV = findViewById(R.id.invalidateStatus);
+        final TextView tva = findViewById(R.id.textviewa);
 
         topLayouts.add(container1);
         topLayouts.add(container2);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity.java
index 7168478..07dc0a1 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity.java
@@ -94,7 +94,7 @@
     }
 
     private void setupList(int listId) {
-        final ListView list = (ListView) findViewById(listId);
+        final ListView list = findViewById(listId);
         list.setAdapter(new SimpleListAdapter(this));
     }
 
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java
index e65dd63..96cf43e 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java
@@ -39,7 +39,7 @@
     }
 
     private void setupList(int listId) {
-        final ListView list = (ListView) findViewById(listId);
+        final ListView list = findViewById(listId);
         list.setAdapter(new SimpleListAdapter(this));
         list.setLayerType(View.LAYER_TYPE_HARDWARE, null);
         ((View) list.getParent()).setLayerType(View.LAYER_TYPE_HARDWARE, null);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity4.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity4.java
index 17f78af..1f3f874 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity4.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity4.java
@@ -47,7 +47,7 @@
     }
     
     private void setupList(int listId) {
-        final ListView list = (ListView) findViewById(listId);
+        final ListView list = findViewById(listId);
         list.setAdapter(new SimpleListAdapter(this));
         list.setLayerType(View.LAYER_TYPE_HARDWARE, null);
     }
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity5.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity5.java
index 2dd7b6a..715da20 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity5.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity5.java
@@ -113,7 +113,7 @@
     }
     
     private void setupList(int listId) {
-        final ListView list = (ListView) findViewById(listId);
+        final ListView list = findViewById(listId);
         list.setAdapter(new SimpleListAdapter(this));
     }
 
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewPropertyAlphaActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewPropertyAlphaActivity.java
index 738801d..9ae3811 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewPropertyAlphaActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewPropertyAlphaActivity.java
@@ -60,12 +60,12 @@
                 startAnim(R.id.imageview);
                 startAnim(myViewAlphaDefault);
                 startAnim(myViewAlphaHandled);
-                EditText selectedText = (EditText) findViewById(R.id.selectedtext);
+                EditText selectedText = findViewById(R.id.selectedtext);
                 selectedText.setSelection(3, 8);
             }
         }, 2000);
         
-        Button invalidator = (Button) findViewById(R.id.invalidateButton);
+        Button invalidator = findViewById(R.id.invalidateButton);
         invalidator.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
@@ -74,7 +74,7 @@
             }
         });
 
-        TextView textView = (TextView) findViewById(R.id.spantext);
+        TextView textView = findViewById(R.id.spantext);
         if (textView != null) {
             SpannableStringBuilder text =
                     new SpannableStringBuilder("Now this is a short text message with spans");
@@ -93,7 +93,7 @@
             textView.setText(text);
         }
         
-        LinearLayout container = (LinearLayout) findViewById(R.id.container);
+        LinearLayout container = findViewById(R.id.container);
         myViewAlphaDefault = new MyView(this, false);
         myViewAlphaDefault.setLayoutParams(new LinearLayout.LayoutParams(75, 75));
         container.addView(myViewAlphaDefault);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ZOrderingActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ZOrderingActivity.java
index 45e77ed..08979bc 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ZOrderingActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ZOrderingActivity.java
@@ -12,7 +12,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.z_ordering);
 
-        ViewGroup grandParent = (ViewGroup) findViewById(R.id.parent);
+        ViewGroup grandParent = findViewById(R.id.parent);
         if (grandParent == null) throw new IllegalStateException();
         View.OnClickListener l = new View.OnClickListener() {
             @Override
diff --git a/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityLandscape.java b/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityLandscape.java
index 292bbd2..6115fd5 100644
--- a/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityLandscape.java
+++ b/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityLandscape.java
@@ -50,7 +50,7 @@
 
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
                android.R.layout.simple_dropdown_item_1line, COUNTRIES);
-       AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.edit);
+       AutoCompleteTextView textView = findViewById(R.id.edit);
        textView.setAdapter(adapter);
    }
 
diff --git a/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityPortrait.java b/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityPortrait.java
index 570cb6b..253c50f 100644
--- a/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityPortrait.java
+++ b/tests/ImfTest/src/com/android/imftest/samples/AutoCompleteTextViewActivityPortrait.java
@@ -45,7 +45,7 @@
 
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
                android.R.layout.simple_dropdown_item_1line, COUNTRIES);
-       AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.edit);
+       AutoCompleteTextView textView = findViewById(R.id.edit);
        textView.setAdapter(adapter);
    }
 
diff --git a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java
index 5aa0d4f..51cdbb5 100644
--- a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java
+++ b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/MainActivity.java
@@ -56,16 +56,16 @@
         stopJobColor = getColor(R.color.stop_received);
 
         // Set up UI.
-        mShowStartView = (TextView) findViewById(R.id.onstart_textview);
-        mShowStopView = (TextView) findViewById(R.id.onstop_textview);
-        mParamsTextView = (TextView) findViewById(R.id.task_params);
-        mDelayEditText = (EditText) findViewById(R.id.delay_time);
-        mDeadlineEditText = (EditText) findViewById(R.id.deadline_time);
-        mWiFiConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_unmetered);
-        mAnyConnectivityRadioButton = (RadioButton) findViewById(R.id.checkbox_any);
-        mRequiresChargingCheckBox = (CheckBox) findViewById(R.id.checkbox_charging);
-        mRequiresIdleCheckbox = (CheckBox) findViewById(R.id.checkbox_idle);
-        mIsPersistedCheckbox = (CheckBox) findViewById(R.id.checkbox_persisted);
+        mShowStartView = findViewById(R.id.onstart_textview);
+        mShowStopView = findViewById(R.id.onstop_textview);
+        mParamsTextView = findViewById(R.id.task_params);
+        mDelayEditText = findViewById(R.id.delay_time);
+        mDeadlineEditText = findViewById(R.id.deadline_time);
+        mWiFiConnectivityRadioButton = findViewById(R.id.checkbox_unmetered);
+        mAnyConnectivityRadioButton = findViewById(R.id.checkbox_any);
+        mRequiresChargingCheckBox = findViewById(R.id.checkbox_charging);
+        mRequiresIdleCheckbox = findViewById(R.id.checkbox_idle);
+        mIsPersistedCheckbox = findViewById(R.id.checkbox_persisted);
 
         mServiceComponent = new ComponentName(this, TestJobService.class);
         // Start service and provide it a way to communicate with us.
diff --git a/tests/LargeAssetTest/src/com/android/largeassettest/LargeAssetTest.java b/tests/LargeAssetTest/src/com/android/largeassettest/LargeAssetTest.java
index e3a9cf4..612c53e 100644
--- a/tests/LargeAssetTest/src/com/android/largeassettest/LargeAssetTest.java
+++ b/tests/LargeAssetTest/src/com/android/largeassettest/LargeAssetTest.java
@@ -43,8 +43,8 @@
         super.onCreate(icicle);
         setContentView(R.layout.lat);
 
-        mResultText = (TextView) findViewById(R.id.result);
-        mValidateButton = (Button) findViewById(R.id.validate);
+        mResultText = findViewById(R.id.result);
+        mValidateButton = findViewById(R.id.validate);
 
         mValidateButton.setOnClickListener(mClickListener);
     }
diff --git a/tests/LowStorageTest/src/com/android/lowstoragetest/LowStorageTest.java b/tests/LowStorageTest/src/com/android/lowstoragetest/LowStorageTest.java
index 9f297aa..c0091ad 100644
--- a/tests/LowStorageTest/src/com/android/lowstoragetest/LowStorageTest.java
+++ b/tests/LowStorageTest/src/com/android/lowstoragetest/LowStorageTest.java
@@ -52,9 +52,9 @@
         StatFs stat = new StatFs(path.getPath());
         int totalBlocks = stat.getBlockCount();
         mBlockSize = (int) (stat.getBlockSize());
-        TextView startSizeTextView = (TextView) findViewById(R.id.totalsize);
+        TextView startSizeTextView = findViewById(R.id.totalsize);
         startSizeTextView.setText(Long.toString((totalBlocks * mBlockSize) / BYTE_SIZE));
-        Button button = (Button) findViewById(R.id.button_run);
+        Button button = findViewById(R.id.button_run);
         button.setOnClickListener(mStartListener);
     }
 
@@ -121,9 +121,9 @@
             File path = Environment.getDataDirectory();
             StatFs stat = new StatFs(path.getPath());
             long availableBlocks = stat.getAvailableBlocks();
-            TextView freeSizeTextView = (TextView) findViewById(R.id.freesize);
+            TextView freeSizeTextView = findViewById(R.id.freesize);
             freeSizeTextView.setText(Long.toString((availableBlocks * mBlockSize) / BYTE_SIZE));
-            TextView statusTextView = (TextView) findViewById(R.id.status);
+            TextView statusTextView = findViewById(R.id.status);
             statusTextView.setText("Finished. You can start the test now.");
         } catch (Exception e) {
             Log.v(TAG, e.toString());
diff --git a/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java b/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java
index 2ff3e20..85cc8fb 100644
--- a/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java
+++ b/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java
@@ -68,16 +68,16 @@
         mPlayer = new PlayerController(this, OnePlayerService.getServiceIntent(this));
 
 
-        mStartButton = (Button) findViewById(R.id.start_button);
-        mPlayButton = (Button) findViewById(R.id.play_button);
-        mRouteButton = (Button) findViewById(R.id.route_button);
-        mStatusView = (TextView) findViewById(R.id.status);
-        mContentText = (EditText) findViewById(R.id.content);
-        mNextContentText = (EditText) findViewById(R.id.next_content);
-        mHasVideo = (CheckBox) findViewById(R.id.has_video);
-        mArtView = (ImageView) findViewById(R.id.art);
+        mStartButton = findViewById(R.id.start_button);
+        mPlayButton = findViewById(R.id.play_button);
+        mRouteButton = findViewById(R.id.route_button);
+        mStatusView = findViewById(R.id.status);
+        mContentText = findViewById(R.id.content);
+        mNextContentText = findViewById(R.id.next_content);
+        mHasVideo = findViewById(R.id.has_video);
+        mArtView = findViewById(R.id.art);
 
-        final Button artPicker = (Button) findViewById(R.id.art_picker);
+        final Button artPicker = findViewById(R.id.art_picker);
         artPicker.setOnClickListener(mButtonListener);
 
         mStartButton.setOnClickListener(mButtonListener);
diff --git a/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java
index ee4c834..241206d 100644
--- a/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java
+++ b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java
@@ -43,7 +43,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
-        ListView lv = (ListView) findViewById(android.R.id.list);
+        ListView lv = findViewById(android.R.id.list);
         lv.setDrawSelectorOnTop(true);
         lv.setAdapter(new SimpleAdapter(this, SAMPLES,
                 R.layout.item_layout, new String[] { KEY_NAME },
@@ -55,7 +55,7 @@
     @Override
     protected void onResume() {
         super.onResume();
-        ListView lv = (ListView) findViewById(android.R.id.list);
+        ListView lv = findViewById(android.R.id.list);
         for (int i = 0; i < lv.getChildCount(); i++) {
             lv.getChildAt(i).animate().translationY(0).setDuration(DURATION);
         }
diff --git a/tests/RenderThreadTest/src/com/example/renderthread/SubActivity.java b/tests/RenderThreadTest/src/com/example/renderthread/SubActivity.java
index 892cbae..22fc691 100644
--- a/tests/RenderThreadTest/src/com/example/renderthread/SubActivity.java
+++ b/tests/RenderThreadTest/src/com/example/renderthread/SubActivity.java
@@ -39,7 +39,7 @@
     @Override
     protected void onResume() {
         super.onResume();
-        ViewGroup container = (ViewGroup) findViewById(R.id.my_container);
+        ViewGroup container = findViewById(R.id.my_container);
         int dx = getWindowManager().getDefaultDisplay().getWidth();
         for (int i = 0; i < container.getChildCount(); i++) {
             View child = container.getChildAt(i);
diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestActivity.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestActivity.java
index 4841bc5..c3c4cf5 100644
--- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestActivity.java
+++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerTestActivity.java
@@ -81,14 +81,14 @@
 
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
-        mDebugView = (TextView) findViewById(R.id.console);
-        mScrollView = (ScrollView) findViewById(R.id.scroller_id);
-        mRadioGroup = (RadioGroup) findViewById(R.id.model_group_id);
-        mPlayTriggerButton = (Button) findViewById(R.id.play_trigger_id);
+        mDebugView = findViewById(R.id.console);
+        mScrollView = findViewById(R.id.scroller_id);
+        mRadioGroup = findViewById(R.id.model_group_id);
+        mPlayTriggerButton = findViewById(R.id.play_trigger_id);
         mDebugView.setText(mDebugView.getText(), TextView.BufferType.EDITABLE);
         mDebugView.setMovementMethod(new ScrollingMovementMethod());
-        mCaptureAudioCheckBox = (CheckBox) findViewById(R.id.caputre_check_box);
-        mPlayCapturedAudioButton = (Button) findViewById(R.id.play_captured_id);
+        mCaptureAudioCheckBox = findViewById(R.id.caputre_check_box);
+        mPlayCapturedAudioButton = findViewById(R.id.play_captured_id);
         mHandler = new Handler();
         mButtonModelUuidMap = new HashMap();
         mModelButtons = new HashMap();
diff --git a/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java b/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
index 7c13974..7632a6e 100644
--- a/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
+++ b/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java
@@ -180,7 +180,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_touch_latency);
 
-        mTouchView = (TouchLatencyView) findViewById(R.id.canvasView);
+        mTouchView = findViewById(R.id.canvasView);
     }
 
 
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java b/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java
index 54c44e2..9985357 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ClippingText.java
@@ -42,7 +42,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.clipping_text_1);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
         mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.clipping_text_1, this);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java b/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java
index f687da3..86ecf8e 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ContactsExpansion.java
@@ -49,7 +49,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.contacts_list);
-        ViewGroup contactsContainer = (ViewGroup) findViewById(R.id.contactsContainer);
+        ViewGroup contactsContainer = findViewById(R.id.contactsContainer);
 
         int contactsIndex = 0;
         addContact(contactsContainer, contactsIndex, R.drawable.self_portrait_square_100);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java b/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
index 5bb0e77..0d41d64 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossFadeDemo.java
@@ -38,7 +38,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.crossfade);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
         mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.crossfade, this);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
index 1f278b9..1fb732e 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeImage.java
@@ -41,10 +41,10 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.crossfade_image);
 
-        ViewGroup container = (ViewGroup) findViewById(R.id.container);
+        ViewGroup container = findViewById(R.id.container);
         mSceneRoot = container;
 
-        mImageView = (ImageView) findViewById(R.id.contact_picture);
+        mImageView = findViewById(R.id.contact_picture);
         mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
 
         Crossfade mCrossfade = new Crossfade();
diff --git a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java
index 469ee8b..15d15351 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/CrossfadeMultiple.java
@@ -49,12 +49,12 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.crossfade_multiple);
 
-        ViewGroup container = (ViewGroup) findViewById(R.id.container);
+        ViewGroup container = findViewById(R.id.container);
         mSceneRoot = container;
 
-        mButton = (Button) findViewById(R.id.button);
-        mImageView = (ImageView) findViewById(R.id.imageview);
-        mTextView = (TextView) findViewById(R.id.textview);
+        mButton = findViewById(R.id.button);
+        mImageView = findViewById(R.id.imageview);
+        mTextView = findViewById(R.id.textview);
 
         mCrossfade = new Crossfade();
         mCrossfade.addTarget(R.id.button).addTarget(R.id.textview).addTarget(R.id.imageview);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo0.java b/tests/TransitionTests/src/com/android/transitiontests/Demo0.java
index d52ab1d..e172904 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo0.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo0.java
@@ -35,7 +35,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.search_screen);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
         mCurrentScene = SEARCH_SCREEN;
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo1.java b/tests/TransitionTests/src/com/android/transitiontests/Demo1.java
index 5b5eb15..e92dd03 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo1.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo1.java
@@ -40,7 +40,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.search_screen);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
 //        mResultsScreen = new MyScene(mSceneRoot, R.layout.results_screen);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo2.java b/tests/TransitionTests/src/com/android/transitiontests/Demo2.java
index 0f3257b..c26723b 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo2.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo2.java
@@ -38,7 +38,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.search_screen);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
     }
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo3.java b/tests/TransitionTests/src/com/android/transitiontests/Demo3.java
index 0ffa1f5..094ab97 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo3.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo3.java
@@ -38,7 +38,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.search_screen);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
         mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo4.java b/tests/TransitionTests/src/com/android/transitiontests/Demo4.java
index 3aadbb0..af67f26 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo4.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo4.java
@@ -38,7 +38,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.search_screen);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
         mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Demo5.java b/tests/TransitionTests/src/com/android/transitiontests/Demo5.java
index c36abda..f01a29d 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Demo5.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Demo5.java
@@ -33,7 +33,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.search_screen);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
         mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java b/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java
index d497abe..40bf975 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/FadingHierarchy.java
@@ -34,11 +34,11 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.fading_hierarchy);
 
-        mContainer = (ViewGroup) findViewById(R.id.container);
-        mRemovingContainer = (ViewGroup) findViewById(R.id.removingContainer);
+        mContainer = findViewById(R.id.container);
+        mRemovingContainer = findViewById(R.id.removingContainer);
         mInnerContainerParent = (ViewGroup) mRemovingContainer.getParent();
 
-        mRemovingButton = (Button) findViewById(R.id.removingButton);
+        mRemovingButton = findViewById(R.id.removingButton);
     }
 
     public void sendMessage(View view) {
diff --git a/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java b/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java
index 29fb868..8307366 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/FadingTest.java
@@ -43,13 +43,13 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.fading_test);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
 
-        mRemovingButton = (Button) findViewById(R.id.removingButton);
-        mInvisibleButton = (Button) findViewById(R.id.invisibleButton);
-        mGoneButton = (Button) findViewById(R.id.goneButton);
+        mRemovingButton = findViewById(R.id.removingButton);
+        mInvisibleButton = findViewById(R.id.invisibleButton);
+        mGoneButton = findViewById(R.id.goneButton);
 
         mGoneButton.setOnClickListener(new View.OnClickListener() {
             @Override
diff --git a/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java b/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java
index a06ba8f..025e4e3 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/InstanceTargets.java
@@ -37,7 +37,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.instance_targets);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container;
     }
 
diff --git a/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java b/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
index c26e93f..6186150 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/InterruptionTest.java
@@ -40,17 +40,17 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.interruption);
 
-        ViewGroup sceneRoot = (ViewGroup) findViewById(R.id.sceneRoot);
+        ViewGroup sceneRoot = findViewById(R.id.sceneRoot);
 
         mScene1 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_1, this);
         mScene2 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_2, this);
         mScene3 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_3, this);
         mScene4 = Scene.getSceneForLayout(sceneRoot, R.layout.interruption_inner_4, this);
 
-        mScene1RB = (RadioButton) findViewById(R.id.scene1RB);
-        mScene2RB = (RadioButton) findViewById(R.id.scene2RB);
-        mScene3RB = (RadioButton) findViewById(R.id.scene3RB);
-        mScene4RB = (RadioButton) findViewById(R.id.scene4RB);
+        mScene1RB = findViewById(R.id.scene1RB);
+        mScene2RB = findViewById(R.id.scene2RB);
+        mScene3RB = findViewById(R.id.scene3RB);
+        mScene4RB = findViewById(R.id.scene4RB);
 
         ChangeBounds changeBounds1 = new ChangeBounds();
         changeBounds1.addTarget(R.id.button);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java b/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
index 251bf24..45b8286 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
@@ -47,9 +47,9 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.list_view_add_remove);
 
-        final LinearLayout container = (LinearLayout) findViewById(R.id.container);
+        final LinearLayout container = findViewById(R.id.container);
 
-        final ListView listview = (ListView) findViewById(R.id.listview);
+        final ListView listview = findViewById(R.id.listview);
         for (int i = 0; i < 200; ++i) {
             numList.add(Integer.toString(i));
         }
diff --git a/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java b/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java
index 92bbb85..96b018b 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/LoginActivity.java
@@ -40,7 +40,7 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_login);
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
         mLoginScene = Scene.getSceneForLayout(mSceneRoot, R.layout.activity_login, this);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/OverlayTest.java b/tests/TransitionTests/src/com/android/transitiontests/OverlayTest.java
index ef8cd37..384762b 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/OverlayTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/OverlayTest.java
@@ -32,12 +32,12 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.overlay_test);
 
-        mContainer = (ViewGroup) findViewById(R.id.container);
+        mContainer = findViewById(R.id.container);
         mRoot = (ViewGroup) mContainer.getParent();
     }
 
     public void onClick(View view) {
-        final Button fadingButton = (Button) findViewById(R.id.fadingButton);
+        final Button fadingButton = findViewById(R.id.fadingButton);
         if (fadingButton != null) {
             mContainer.removeView(fadingButton);
             mRoot.getOverlay().add(fadingButton);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java b/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java
index 1ee8621..772ddc7 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/Reparenting.java
@@ -34,9 +34,9 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.reparenting);
 
-        ViewGroup container = (ViewGroup) findViewById(R.id.container);
-        mContainer1 = (ViewGroup) findViewById(R.id.container1);
-        mContainer2 = (ViewGroup) findViewById(R.id.container2);
+        ViewGroup container = findViewById(R.id.container);
+        mContainer1 = findViewById(R.id.container1);
+        mContainer2 = findViewById(R.id.container2);
         System.out.println("container 1 and 2 " + mContainer1 + ", " + mContainer2);
 
         setupButtons(0, mContainer1);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java b/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java
index 1aee258..96d3ae1 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ResourceLoadingTest.java
@@ -39,7 +39,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.search_screen);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
         mCurrentScene = SEARCH_SCREEN;
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java
index 7504058..7ee4b3e 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTargets.java
@@ -39,7 +39,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.search_screen);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
         mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java
index 23b28ec..9333ea1 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestAutoTransition.java
@@ -37,7 +37,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.search_screen);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
         mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java
index ecf5ef3..a01f638 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ScenesTestv21.java
@@ -39,7 +39,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.search_screen);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
         mSearchScreen = Scene.getSceneForLayout(mSceneRoot, R.layout.search_screen, this);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java b/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java
index c550e92..5f4560cc 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/SequenceTest.java
@@ -41,12 +41,12 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.fading_test);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
-        mRemovingButton = (Button) findViewById(R.id.removingButton);
-        mInvisibleButton = (Button) findViewById(R.id.invisibleButton);
-        mGoneButton = (Button) findViewById(R.id.goneButton);
+        mRemovingButton = findViewById(R.id.removingButton);
+        mInvisibleButton = findViewById(R.id.invisibleButton);
+        mGoneButton = findViewById(R.id.goneButton);
 
         mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test, this);
         mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_scene_2, this);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java b/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java
index 92b169e..f478cb8 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/SequenceTestSimple.java
@@ -42,10 +42,10 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.fading_test_simple);
 
-        View container = (View) findViewById(R.id.container);
+        View container = findViewById(R.id.container);
         mSceneRoot = (ViewGroup) container.getParent();
 
-        mRemovingButton = (Button) findViewById(R.id.removingButton);
+        mRemovingButton = findViewById(R.id.removingButton);
 
         mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_simple, this);
         mScene2 = Scene.getSceneForLayout(mSceneRoot, R.layout.fading_test_simple2, this);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java b/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java
index 9b246ad..8819c40 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/SurfaceAndTextureViews.java
@@ -48,8 +48,8 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.surface_texture_views);
 
-        final ViewGroup container = (ViewGroup) findViewById(R.id.container);
-        Button toggleButton = (Button) findViewById(R.id.toggleButton);
+        final ViewGroup container = findViewById(R.id.container);
+        Button toggleButton = findViewById(R.id.toggleButton);
 
         mView = new SimpleView(this);
         mView.setId(0);
diff --git a/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java b/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java
index c824956..b2b24bc 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/UniqueIds.java
@@ -40,7 +40,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.unique_id_test);
 
-        LinearLayout container = (LinearLayout) findViewById(R.id.container);
+        LinearLayout container = findViewById(R.id.container);
         LayoutInflater inflater = getLayoutInflater();
         Button button = (Button) inflater.inflate(R.layout.button_template, null);
         container.addView(button);
diff --git a/tests/UiBench/src/com/android/test/uibench/ActivityTransition.java b/tests/UiBench/src/com/android/test/uibench/ActivityTransition.java
index 0a069c2..c212c4c 100644
--- a/tests/UiBench/src/com/android/test/uibench/ActivityTransition.java
+++ b/tests/UiBench/src/com/android/test/uibench/ActivityTransition.java
@@ -94,7 +94,7 @@
         setupHero();
 
         // Ensure that all images are visible regardless of orientation.
-        GridLayout gridLayout = (GridLayout) findViewById(R.id.transition_grid_layout);
+        GridLayout gridLayout = findViewById(R.id.transition_grid_layout);
         boolean isPortrait =
                 getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
         gridLayout.setRowCount(isPortrait ? 4 : 2);
@@ -105,7 +105,7 @@
         String name = getIntent().getStringExtra(KEY_ID);
         mHero = null;
         if (name != null) {
-            mHero = (ImageView) findViewById(getIdForKey(name));
+            mHero = findViewById(getIdForKey(name));
             setEnterSharedElementCallback(new SharedElementCallback() {
                 @Override
                 public void onMapSharedElements(List<String> names,
diff --git a/tests/UiBench/src/com/android/test/uibench/ActivityTransitionDetails.java b/tests/UiBench/src/com/android/test/uibench/ActivityTransitionDetails.java
index a654c61..a4d57e1 100644
--- a/tests/UiBench/src/com/android/test/uibench/ActivityTransitionDetails.java
+++ b/tests/UiBench/src/com/android/test/uibench/ActivityTransitionDetails.java
@@ -39,7 +39,7 @@
         super.onCreate(savedInstanceState);
         getWindow().setBackgroundDrawable(new ColorDrawable(Color.DKGRAY));
         setContentView(R.layout.activity_transition_details);
-        ImageView titleImage = (ImageView) findViewById(R.id.titleImage);
+        ImageView titleImage = findViewById(R.id.titleImage);
         titleImage.setImageDrawable(getHeroDrawable());
     }
 
diff --git a/tests/UiBench/src/com/android/test/uibench/BitmapUploadActivity.java b/tests/UiBench/src/com/android/test/uibench/BitmapUploadActivity.java
index e2bf897..235e0e6 100644
--- a/tests/UiBench/src/com/android/test/uibench/BitmapUploadActivity.java
+++ b/tests/UiBench/src/com/android/test/uibench/BitmapUploadActivity.java
@@ -80,7 +80,7 @@
         setContentView(R.layout.activity_bitmap_upload);
 
         // animate color to force bitmap uploads
-        UploadView uploadView = (UploadView) findViewById(R.id.upload_view);
+        UploadView uploadView = findViewById(R.id.upload_view);
         ObjectAnimator colorValueAnimator = ObjectAnimator.ofInt(uploadView, "colorValue", 0, 255);
         colorValueAnimator.setRepeatMode(ValueAnimator.REVERSE);
         colorValueAnimator.setRepeatCount(ValueAnimator.INFINITE);
diff --git a/tests/UiBench/src/com/android/test/uibench/ClippedListActivity.java b/tests/UiBench/src/com/android/test/uibench/ClippedListActivity.java
index 7454124..fee7480 100644
--- a/tests/UiBench/src/com/android/test/uibench/ClippedListActivity.java
+++ b/tests/UiBench/src/com/android/test/uibench/ClippedListActivity.java
@@ -35,16 +35,16 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_navigation_drawer);
-        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+        Toolbar toolbar = findViewById(R.id.toolbar);
         setSupportActionBar(toolbar);
-        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+        DrawerLayout drawer = findViewById(R.id.drawer_layout);
         ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                 this, drawer, toolbar, R.string.navigation_drawer_open,
                 R.string.navigation_drawer_close);
         drawer.setDrawerListener(toggle);
         toggle.syncState();
 
-        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
+        NavigationView navigationView = findViewById(R.id.nav_view);
         navigationView.setNavigationItemSelectedListener(this);
 
         FragmentManager fm = getSupportFragmentManager();
@@ -59,7 +59,7 @@
 
     @Override
     public boolean onNavigationItemSelected(MenuItem item) {
-        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+        DrawerLayout drawer = findViewById(R.id.drawer_layout);
         drawer.closeDrawer(GravityCompat.START);
         return true;
     }
diff --git a/tests/UiBench/src/com/android/test/uibench/NavigationDrawerActivity.java b/tests/UiBench/src/com/android/test/uibench/NavigationDrawerActivity.java
index 1d68767..a541104 100644
--- a/tests/UiBench/src/com/android/test/uibench/NavigationDrawerActivity.java
+++ b/tests/UiBench/src/com/android/test/uibench/NavigationDrawerActivity.java
@@ -31,22 +31,22 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_navigation_drawer);
-        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+        Toolbar toolbar = findViewById(R.id.toolbar);
         setSupportActionBar(toolbar);
-        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+        DrawerLayout drawer = findViewById(R.id.drawer_layout);
         ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                 this, drawer, toolbar, R.string.navigation_drawer_open,
                 R.string.navigation_drawer_close);
         drawer.setDrawerListener(toggle);
         toggle.syncState();
 
-        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
+        NavigationView navigationView = findViewById(R.id.nav_view);
         navigationView.setNavigationItemSelectedListener(this);
     }
 
     @Override
     public boolean onNavigationItemSelected(MenuItem item) {
-        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+        DrawerLayout drawer = findViewById(R.id.drawer_layout);
         drawer.closeDrawer(GravityCompat.START);
         return true;
     }
diff --git a/tests/UiBench/src/com/android/test/uibench/RenderingJitter.java b/tests/UiBench/src/com/android/test/uibench/RenderingJitter.java
index e2a9bcb..e1df7d3 100644
--- a/tests/UiBench/src/com/android/test/uibench/RenderingJitter.java
+++ b/tests/UiBench/src/com/android/test/uibench/RenderingJitter.java
@@ -85,12 +85,12 @@
         View content = findViewById(android.R.id.content);
         content.setBackground(new AnimatedBackgroundDrawable());
         content.setKeepScreenOn(true);
-        mJitterReport = (TextView) findViewById(R.id.jitter_mma);
-        mMostlyTotalFrameTimeReport = (TextView) findViewById(R.id.totalish_mma);
-        mUiFrameTimeReport = (TextView) findViewById(R.id.ui_frametime_mma);
-        mRenderThreadTimeReport = (TextView) findViewById(R.id.rt_frametime_mma);
-        mTotalFrameTimeReport = (TextView) findViewById(R.id.total_mma);
-        mGraph = (PointGraphView) findViewById(R.id.graph);
+        mJitterReport = findViewById(R.id.jitter_mma);
+        mMostlyTotalFrameTimeReport = findViewById(R.id.totalish_mma);
+        mUiFrameTimeReport = findViewById(R.id.ui_frametime_mma);
+        mRenderThreadTimeReport = findViewById(R.id.rt_frametime_mma);
+        mTotalFrameTimeReport = findViewById(R.id.total_mma);
+        mGraph = findViewById(R.id.graph);
         mJitterReport.setText("abcdefghijklmnopqrstuvwxyz");
         mMostlyTotalFrameTimeReport.setText("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
         mUiFrameTimeReport.setText("0123456789");
diff --git a/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/src/com/android/hardware/usb/externalmanagementtest/UsbHostManagementActivity.java b/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/src/com/android/hardware/usb/externalmanagementtest/UsbHostManagementActivity.java
index 2d9226f..af8b846 100644
--- a/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/src/com/android/hardware/usb/externalmanagementtest/UsbHostManagementActivity.java
+++ b/tests/UsbHostExternalManagmentTest/UsbHostExternalManagmentTestApp/src/com/android/hardware/usb/externalmanagementtest/UsbHostManagementActivity.java
@@ -68,12 +68,12 @@
         Log.i(TAG, "onCreate");
         super.onCreate(savedInstanceState);
         setContentView(R.layout.host_management);
-        mDeviceInfoText = (TextView) findViewById(R.id.device_info_text);
-        mStartAoapButton = (Button) findViewById(R.id.start_aoap_button);
-        mStartAoapActivityButton = (Button) findViewById(R.id.start_aoap_activity_button);
-        mAoapAppLog = (TextView) findViewById(R.id.aoap_apps_text);
-        mResetUsbButton = (Button) findViewById(R.id.reset_button);
-        mFinishButton = (Button) findViewById(R.id.finish_button);
+        mDeviceInfoText = findViewById(R.id.device_info_text);
+        mStartAoapButton = findViewById(R.id.start_aoap_button);
+        mStartAoapActivityButton = findViewById(R.id.start_aoap_activity_button);
+        mAoapAppLog = findViewById(R.id.aoap_apps_text);
+        mResetUsbButton = findViewById(R.id.reset_button);
+        mFinishButton = findViewById(R.id.finish_button);
 
         Intent intent = getIntent();
         if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableAttr.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableAttr.java
index 8de2f6b..47ca482 100644
--- a/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableAttr.java
+++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/AnimatedVectorDrawableAttr.java
@@ -25,7 +25,7 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_animated_vector_drawable_attr);
 
-        ImageView avdIv = (ImageView) findViewById(R.id.avd);
+        ImageView avdIv = findViewById(R.id.avd);
         AnimatedVectorDrawable avd = (AnimatedVectorDrawable) avdIv.getDrawable();
         avd.start();
     }
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/StartVoiceInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/StartVoiceInteractionActivity.java
index 41058c9..733f602 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/StartVoiceInteractionActivity.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/StartVoiceInteractionActivity.java
@@ -55,9 +55,9 @@
         mPickButton.setOnClickListener(this);
         mCancelButton = (Button)findViewById(R.id.cancel);
         mCancelButton.setOnClickListener(this);
-        mStartButton = (Button) findViewById(R.id.start);
+        mStartButton = findViewById(R.id.start);
         mStartButton.setOnClickListener(this);
-        mStopButton = (Button) findViewById(R.id.stop);
+        mStopButton = findViewById(R.id.stop);
         mStopButton.setOnClickListener(this);
 
         mLog.append("Local Voice Interaction Supported = " + isLocalVoiceInteractionSupported());
diff --git a/tests/WallpaperTest/src/com/example/wallpapertest/MainActivity.java b/tests/WallpaperTest/src/com/example/wallpapertest/MainActivity.java
index 7880f67..63e11a7 100644
--- a/tests/WallpaperTest/src/com/example/wallpapertest/MainActivity.java
+++ b/tests/WallpaperTest/src/com/example/wallpapertest/MainActivity.java
@@ -58,28 +58,28 @@
         mWallpaperManager = (WallpaperManager)getSystemService(Context.WALLPAPER_SERVICE);
         mWindowManager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
 
-        mDimenWidthView = (TextView) findViewById(R.id.dimen_width);
+        mDimenWidthView = findViewById(R.id.dimen_width);
         mDimenWidthView.addTextChangedListener(mTextWatcher);
-        mDimenHeightView = (TextView) findViewById(R.id.dimen_height);
+        mDimenHeightView = findViewById(R.id.dimen_height);
         mDimenHeightView.addTextChangedListener(mTextWatcher);
 
-        mWallOffXView = (TextView) findViewById(R.id.walloff_x);
+        mWallOffXView = findViewById(R.id.walloff_x);
         mWallOffXView.addTextChangedListener(mTextWatcher);
-        mWallOffYView = (TextView) findViewById(R.id.walloff_y);
+        mWallOffYView = findViewById(R.id.walloff_y);
         mWallOffYView.addTextChangedListener(mTextWatcher);
 
-        mPaddingLeftView = (TextView) findViewById(R.id.padding_left);
+        mPaddingLeftView = findViewById(R.id.padding_left);
         mPaddingLeftView.addTextChangedListener(mTextWatcher);
-        mPaddingRightView = (TextView) findViewById(R.id.padding_right);
+        mPaddingRightView = findViewById(R.id.padding_right);
         mPaddingRightView.addTextChangedListener(mTextWatcher);
-        mPaddingTopView = (TextView) findViewById(R.id.padding_top);
+        mPaddingTopView = findViewById(R.id.padding_top);
         mPaddingTopView.addTextChangedListener(mTextWatcher);
-        mPaddingBottomView = (TextView) findViewById(R.id.padding_bottom);
+        mPaddingBottomView = findViewById(R.id.padding_bottom);
         mPaddingBottomView.addTextChangedListener(mTextWatcher);
 
-        mDispOffXView = (TextView) findViewById(R.id.dispoff_x);
+        mDispOffXView = findViewById(R.id.dispoff_x);
         mDispOffXView.addTextChangedListener(mTextWatcher);
-        mDispOffYView = (TextView) findViewById(R.id.dispoff_y);
+        mDispOffYView = findViewById(R.id.dispoff_y);
         mDispOffYView.addTextChangedListener(mTextWatcher);
 
         updateDimens();
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
index d819b96..d11565a 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
@@ -45,7 +45,9 @@
 import android.net.metrics.RaEvent;
 import android.net.metrics.ValidationProbeEvent;
 import android.test.suitebuilder.annotation.SmallTest;
+import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
 import java.util.Arrays;
+import java.util.List;
 import junit.framework.TestCase;
 
 // TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
@@ -57,7 +59,7 @@
                 aType(IpReachabilityEvent.class),
                 anInt(IpReachabilityEvent.NUD_FAILED));
 
-        String want = joinLines(
+        String want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -70,13 +72,13 @@
                 "    if_name: \"\"",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
         verifySerialization(want, ev);
 
         ev.netId = 123;
         ev.transports = 3; // transports have priority for inferrence of link layer
         ev.ifname = "wlan0";
-        want = joinLines(
+        want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -89,12 +91,12 @@
                 "    if_name: \"\"",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
         verifySerialization(want, ev);
 
         ev.transports = 1;
         ev.ifname = null;
-        want = joinLines(
+        want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -107,12 +109,12 @@
                 "    if_name: \"\"",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
         verifySerialization(want, ev);
 
         ev.transports = 0;
         ev.ifname = "not_inferred";
-        want = joinLines(
+        want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"not_inferred\"",
@@ -125,11 +127,11 @@
                 "    if_name: \"\"",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
         verifySerialization(want, ev);
 
         ev.ifname = "bt-pan";
-        want = joinLines(
+        want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -142,11 +144,11 @@
                 "    if_name: \"\"",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
         verifySerialization(want, ev);
 
         ev.ifname = "rmnet_ipa0";
-        want = joinLines(
+        want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -159,11 +161,11 @@
                 "    if_name: \"\"",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
         verifySerialization(want, ev);
 
         ev.ifname = "wlan0";
-        want = joinLines(
+        want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -176,7 +178,7 @@
                 "    if_name: \"\"",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
         verifySerialization(want, ev);
     }
 
@@ -190,7 +192,7 @@
                 aBool(true),
                 aBool(false));
 
-        String want = joinLines(
+        String want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -211,7 +213,7 @@
                 "    transport_types: 3",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
 
         verifySerialization(want, ev);
     }
@@ -223,7 +225,7 @@
                 aString("SomeState"),
                 anInt(192));
 
-        String want = joinLines(
+        String want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -237,7 +239,7 @@
                 "    state_transition: \"SomeState\"",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
 
         verifySerialization(want, ev);
     }
@@ -248,7 +250,7 @@
                 aType(DhcpErrorEvent.class),
                 anInt(DhcpErrorEvent.L4_NOT_UDP));
 
-        String want = joinLines(
+        String want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -262,59 +264,7 @@
                 "    error_code: 50397184",
                 "  >",
                 ">",
-                "version: 2");
-
-        verifySerialization(want, ev);
-    }
-
-    @SmallTest
-    public void testDnsEventSerialization() {
-        ConnectivityMetricsEvent ev = describeIpEvent(
-                aType(DnsEvent.class),
-                anInt(101),
-                aByteArray(b(1), b(1), b(2), b(1), b(1), b(1), b(2), b(2)),
-                aByteArray(b(0), b(0), b(22), b(3), b(1), b(0), b(200), b(178)),
-                anIntArray(3456, 267, 1230, 45, 2111, 450, 638, 1300));
-
-        String want = joinLines(
-                "dropped_events: 0",
-                "events <",
-                "  if_name: \"\"",
-                "  link_layer: 0",
-                "  network_id: 0",
-                "  time_ms: 1",
-                "  transports: 0",
-                "  dns_lookup_batch <",
-                "    event_types: 1",
-                "    event_types: 1",
-                "    event_types: 2",
-                "    event_types: 1",
-                "    event_types: 1",
-                "    event_types: 1",
-                "    event_types: 2",
-                "    event_types: 2",
-                "    latencies_ms: 3456",
-                "    latencies_ms: 267",
-                "    latencies_ms: 1230",
-                "    latencies_ms: 45",
-                "    latencies_ms: 2111",
-                "    latencies_ms: 450",
-                "    latencies_ms: 638",
-                "    latencies_ms: 1300",
-                "    network_id <",
-                "      network_id: 101",
-                "    >",
-                "    return_codes: 0",
-                "    return_codes: 0",
-                "    return_codes: 22",
-                "    return_codes: 3",
-                "    return_codes: 1",
-                "    return_codes: 0",
-                "    return_codes: 200",
-                "    return_codes: 178",
-                "  >",
-                ">",
-                "version: 2");
+                "version: 2\n");
 
         verifySerialization(want, ev);
     }
@@ -326,7 +276,7 @@
                 anInt(IpManagerEvent.PROVISIONING_OK),
                 aLong(5678));
 
-        String want = joinLines(
+        String want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -340,7 +290,7 @@
                 "    latency_ms: 5678",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
 
         verifySerialization(want, ev);
     }
@@ -351,7 +301,7 @@
                 aType(IpReachabilityEvent.class),
                 anInt(IpReachabilityEvent.NUD_FAILED));
 
-        String want = joinLines(
+        String want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -364,7 +314,7 @@
                 "    if_name: \"\"",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
 
         verifySerialization(want, ev);
     }
@@ -377,7 +327,7 @@
                 anInt(5),
                 aLong(20410));
 
-        String want = joinLines(
+        String want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -393,7 +343,7 @@
                 "    >",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
 
         verifySerialization(want, ev);
     }
@@ -406,7 +356,7 @@
                 anInt(ValidationProbeEvent.PROBE_HTTP),
                 anInt(204));
 
-        String want = joinLines(
+        String want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -420,7 +370,7 @@
                 "    probe_type: 1",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
 
         verifySerialization(want, ev);
     }
@@ -436,7 +386,7 @@
                 anInt(2048),
                 anInt(3));
 
-        String want = joinLines(
+        String want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -454,7 +404,7 @@
                 "    program_length: 2048",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
 
         verifySerialization(want, ev);
     }
@@ -474,7 +424,7 @@
                 anInt(3),
                 anInt(2048));
 
-        String want = joinLines(
+        String want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -495,7 +445,7 @@
                 "    zero_lifetime_ras: 1",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
 
         verifySerialization(want, ev);
     }
@@ -511,7 +461,7 @@
                 aLong(1000),
                 aLong(-1));
 
-        String want = joinLines(
+        String want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -528,28 +478,20 @@
                 "    router_lifetime: 2000",
                 "  >",
                 ">",
-                "version: 2");
+                "version: 2\n");
 
         verifySerialization(want, ev);
     }
 
     static void verifySerialization(String want, ConnectivityMetricsEvent... input) {
         try {
-            byte[] got = IpConnectivityEventBuilder.serialize(0,
-                    IpConnectivityEventBuilder.toProto(Arrays.asList(input)));
+            List<IpConnectivityEvent> proto =
+                    IpConnectivityEventBuilder.toProto(Arrays.asList(input));
+            byte[] got = IpConnectivityEventBuilder.serialize(0, proto);
             IpConnectivityLog log = IpConnectivityLog.parseFrom(got);
             assertEquals(want, log.toString());
         } catch (Exception e) {
             fail(e.toString());
         }
     }
-
-    static String joinLines(String ... elems) {
-        StringBuilder b = new StringBuilder();
-        for (String s : elems) {
-            b.append(s);
-            b.append("\n");
-        }
-        return b.toString();
-    }
 }
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index 68786d0..e01469b 100644
--- a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -16,12 +16,22 @@
 
 package com.android.server.connectivity;
 
+import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
+import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.content.Context;
+import android.net.ConnectivityManager;
 import android.net.ConnectivityMetricsEvent;
 import android.net.IIpConnectivityMetrics;
+import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.ApfStats;
 import android.net.metrics.DefaultNetworkEvent;
@@ -31,7 +41,9 @@
 import android.net.metrics.IpReachabilityEvent;
 import android.net.metrics.RaEvent;
 import android.net.metrics.ValidationProbeEvent;
+import android.system.OsConstants;
 import android.os.Parcelable;
+import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Base64;
 import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass;
@@ -41,26 +53,38 @@
 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 org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
-public class IpConnectivityMetricsTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IpConnectivityMetricsTest {
     static final IpReachabilityEvent FAKE_EV =
             new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED);
 
+    private static final String EXAMPLE_IPV4 = "192.0.2.1";
+    private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1";
+
     @Mock Context mCtx;
     @Mock IIpConnectivityMetrics mMockService;
+    @Mock ConnectivityManager mCm;
 
     IpConnectivityMetrics mService;
+    NetdEventListenerService mNetdListener;
 
+    @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mService = new IpConnectivityMetrics(mCtx, (ctx) -> 2000);
+        mNetdListener = new NetdEventListenerService(mCm);
+        mService.mNetdListener = mNetdListener;
     }
 
-    @SmallTest
+    @Test
     public void testLoggingEvents() throws Exception {
         IpConnectivityLog logger = new IpConnectivityLog(mMockService);
 
@@ -74,7 +98,7 @@
         assertEventsEqual(expectedEvent(3), got.get(2));
     }
 
-    @SmallTest
+    @Test
     public void testLoggingEventsWithMultipleCallers() throws Exception {
         IpConnectivityLog logger = new IpConnectivityLog(mMockService);
 
@@ -91,7 +115,7 @@
             }.start();
         }
 
-        List<ConnectivityMetricsEvent> got = verifyEvents(nCallers * nEvents, 100);
+        List<ConnectivityMetricsEvent> got = verifyEvents(nCallers * nEvents, 200);
         Collections.sort(got, EVENT_COMPARATOR);
         Iterator<ConnectivityMetricsEvent> iter = got.iterator();
         for (int i = 0; i < nCallers; i++) {
@@ -102,7 +126,7 @@
         }
     }
 
-    @SmallTest
+    @Test
     public void testBufferFlushing() {
         String output1 = getdump("flush");
         assertEquals("", output1);
@@ -115,7 +139,7 @@
         assertEquals("", output3);
     }
 
-    @SmallTest
+    @Test
     public void testRateLimiting() {
         final IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
         final ApfProgramEvent ev = new ApfProgramEvent();
@@ -137,11 +161,19 @@
         assertEquals("", output2);
     }
 
-    @SmallTest
-    public void testEndToEndLogging() {
+    @Test
+    public void testEndToEndLogging() throws Exception {
         // TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
         IpConnectivityLog logger = new IpConnectivityLog(mService.impl);
 
+        NetworkCapabilities ncWifi = new NetworkCapabilities();
+        NetworkCapabilities ncCell = new NetworkCapabilities();
+        ncWifi.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
+        ncCell.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+
+        when(mCm.getNetworkCapabilities(new Network(100))).thenReturn(ncWifi);
+        when(mCm.getNetworkCapabilities(new Network(101))).thenReturn(ncCell);
+
         ApfStats apfStats = new ApfStats();
         apfStats.durationMs = 45000;
         apfStats.receivedRas = 10;
@@ -177,7 +209,22 @@
             logger.log(ev);
         }
 
-        String want = joinLines(
+        // netId, errno, latency, destination
+        connectEvent(100, OsConstants.EALREADY, 0, EXAMPLE_IPV4);
+        connectEvent(100, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6);
+        connectEvent(100, 0, 110, EXAMPLE_IPV4);
+        connectEvent(101, 0, 23, EXAMPLE_IPV4);
+        connectEvent(101, 0, 45, EXAMPLE_IPV6);
+        connectEvent(100, OsConstants.EAGAIN, 0, EXAMPLE_IPV4);
+
+        // netId, type, return code, latency
+        dnsEvent(100, EVENT_GETADDRINFO, 0, 3456);
+        dnsEvent(100, EVENT_GETADDRINFO, 3, 45);
+        dnsEvent(100, EVENT_GETHOSTBYNAME, 0, 638);
+        dnsEvent(101, EVENT_GETADDRINFO, 0, 56);
+        dnsEvent(101, EVENT_GETHOSTBYNAME, 0, 34);
+
+        String want = String.join("\n",
                 "dropped_events: 0",
                 "events <",
                 "  if_name: \"\"",
@@ -279,7 +326,71 @@
                 "    router_lifetime: 2000",
                 "  >",
                 ">",
-                "version: 2");
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 4",
+                "  network_id: 100",
+                "  time_ms: 0",
+                "  transports: 2",
+                "  connect_statistics <",
+                "    connect_blocking_count: 1",
+                "    connect_count: 3",
+                "    errnos_counters <",
+                "      key: 11",
+                "      value: 1",
+                "    >",
+                "    ipv6_addr_count: 1",
+                "    latencies_ms: 110",
+                "  >",
+                ">",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 2",
+                "  network_id: 101",
+                "  time_ms: 0",
+                "  transports: 1",
+                "  connect_statistics <",
+                "    connect_blocking_count: 2",
+                "    connect_count: 2",
+                "    ipv6_addr_count: 1",
+                "    latencies_ms: 23",
+                "    latencies_ms: 45",
+                "  >",
+                ">",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 4",
+                "  network_id: 100",
+                "  time_ms: 0",
+                "  transports: 2",
+                "  dns_lookup_batch <",
+                "    event_types: 1",
+                "    event_types: 1",
+                "    event_types: 2",
+                "    latencies_ms: 3456",
+                "    latencies_ms: 45",
+                "    latencies_ms: 638",
+                "    return_codes: 0",
+                "    return_codes: 3",
+                "    return_codes: 0",
+                "  >",
+                ">",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 2",
+                "  network_id: 101",
+                "  time_ms: 0",
+                "  transports: 1",
+                "  dns_lookup_batch <",
+                "    event_types: 1",
+                "    event_types: 2",
+                "    latencies_ms: 56",
+                "    latencies_ms: 34",
+                "    return_codes: 0",
+                "    return_codes: 0",
+                "  >",
+                ">",
+                "version: 2\n");
 
         verifySerialization(want, getdump("flush"));
     }
@@ -291,6 +402,14 @@
         return buffer.toString();
     }
 
+    void connectEvent(int netid, int error, int latencyMs, String ipAddr) throws Exception {
+        mNetdListener.onConnectEvent(netid, error, latencyMs, ipAddr, 80, 1);
+    }
+
+    void dnsEvent(int netId, int type, int result, int latency) throws Exception {
+        mNetdListener.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
+    }
+
     List<ConnectivityMetricsEvent> verifyEvents(int n, int timeoutMs) throws Exception {
         ArgumentCaptor<ConnectivityMetricsEvent> captor =
                 ArgumentCaptor.forClass(ConnectivityMetricsEvent.class);
diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
index 0ab4406..f98ab3d 100644
--- a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
@@ -16,190 +16,182 @@
 
 package com.android.server.connectivity;
 
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.net.metrics.ConnectStats;
-import android.net.metrics.DnsEvent;
-import android.net.metrics.INetdEventListener;
-import android.net.metrics.IpConnectivityLog;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.system.OsConstants;
-import android.test.suitebuilder.annotation.SmallTest;
-import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
-import java.io.FileOutputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.OptionalInt;
-import java.util.stream.IntStream;
-import junit.framework.TestCase;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
+import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
+import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
-public class NetdEventListenerServiceTest extends TestCase {
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.support.test.runner.AndroidJUnit4;
+import android.system.OsConstants;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Base64;
+import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.DNSLookupBatch;
+import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
+import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityLog;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
-    // TODO: read from NetdEventListenerService after this constant is read from system property
-    static final int BATCH_SIZE = 100;
-    static final int EVENT_TYPE = INetdEventListener.EVENT_GETADDRINFO;
-    // TODO: read from INetdEventListener
-    static final int RETURN_CODE = 1;
-
-    static final byte[] EVENT_TYPES  = new byte[BATCH_SIZE];
-    static final byte[] RETURN_CODES = new byte[BATCH_SIZE];
-    static final int[] LATENCIES     = new int[BATCH_SIZE];
-    static {
-        for (int i = 0; i < BATCH_SIZE; i++) {
-            EVENT_TYPES[i] = EVENT_TYPE;
-            RETURN_CODES[i] = RETURN_CODE;
-            LATENCIES[i] = i;
-        }
-    }
-
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NetdEventListenerServiceTest {
     private static final String EXAMPLE_IPV4 = "192.0.2.1";
     private static final String EXAMPLE_IPV6 = "2001:db8:1200::2:1";
 
     NetdEventListenerService mNetdEventListenerService;
+    ConnectivityManager mCm;
 
-    @Mock ConnectivityManager mCm;
-    @Mock IpConnectivityLog mLog;
-    ArgumentCaptor<NetworkCallback> mCallbackCaptor;
-    ArgumentCaptor<DnsEvent> mDnsEvCaptor;
-
+    @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mCallbackCaptor = ArgumentCaptor.forClass(NetworkCallback.class);
-        mDnsEvCaptor = ArgumentCaptor.forClass(DnsEvent.class);
-        mNetdEventListenerService = new NetdEventListenerService(mCm, mLog);
+        NetworkCapabilities ncWifi = new NetworkCapabilities();
+        NetworkCapabilities ncCell = new NetworkCapabilities();
+        ncWifi.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
+        ncCell.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
 
-        verify(mCm, times(1)).registerNetworkCallback(any(), mCallbackCaptor.capture());
+        mCm = mock(ConnectivityManager.class);
+        when(mCm.getNetworkCapabilities(new Network(100))).thenReturn(ncWifi);
+        when(mCm.getNetworkCapabilities(new Network(101))).thenReturn(ncCell);
+
+        mNetdEventListenerService = new NetdEventListenerService(mCm);
     }
 
-    @SmallTest
-    public void testOneDnsBatch() throws Exception {
-        log(105, LATENCIES);
-        log(106, Arrays.copyOf(LATENCIES, BATCH_SIZE - 1)); // one lookup short of a batch event
+    @Test
+    public void testDnsLogging() throws Exception {
+        asyncDump(100);
 
-        verifyLoggedDnsEvents(new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES));
+        dnsEvent(100, EVENT_GETADDRINFO, 0, 3456);
+        dnsEvent(100, EVENT_GETADDRINFO, 0, 267);
+        dnsEvent(100, EVENT_GETHOSTBYNAME, 22, 1230);
+        dnsEvent(100, EVENT_GETADDRINFO, 3, 45);
+        dnsEvent(100, EVENT_GETADDRINFO, 1, 2111);
+        dnsEvent(100, EVENT_GETADDRINFO, 0, 450);
+        dnsEvent(100, EVENT_GETHOSTBYNAME, 200, 638);
+        dnsEvent(100, EVENT_GETHOSTBYNAME, 178, 1300);
+        dnsEvent(101, EVENT_GETADDRINFO, 0, 56);
+        dnsEvent(101, EVENT_GETADDRINFO, 0, 78);
+        dnsEvent(101, EVENT_GETADDRINFO, 0, 14);
+        dnsEvent(101, EVENT_GETHOSTBYNAME, 0, 56);
+        dnsEvent(101, EVENT_GETADDRINFO, 0, 78);
+        dnsEvent(101, EVENT_GETADDRINFO, 0, 14);
 
-        log(106, Arrays.copyOfRange(LATENCIES, BATCH_SIZE - 1, BATCH_SIZE));
-
-        mDnsEvCaptor = ArgumentCaptor.forClass(DnsEvent.class); // reset argument captor
-        verifyLoggedDnsEvents(
-            new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES),
-            new DnsEvent(106, EVENT_TYPES, RETURN_CODES, LATENCIES));
+        String got = flushStatistics();
+        String want = String.join("\n",
+                "dropped_events: 0",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 4",
+                "  network_id: 100",
+                "  time_ms: 0",
+                "  transports: 2",
+                "  dns_lookup_batch <",
+                "    event_types: 1",
+                "    event_types: 1",
+                "    event_types: 2",
+                "    event_types: 1",
+                "    event_types: 1",
+                "    event_types: 1",
+                "    event_types: 2",
+                "    event_types: 2",
+                "    latencies_ms: 3456",
+                "    latencies_ms: 267",
+                "    latencies_ms: 1230",
+                "    latencies_ms: 45",
+                "    latencies_ms: 2111",
+                "    latencies_ms: 450",
+                "    latencies_ms: 638",
+                "    latencies_ms: 1300",
+                "    return_codes: 0",
+                "    return_codes: 0",
+                "    return_codes: 22",
+                "    return_codes: 3",
+                "    return_codes: 1",
+                "    return_codes: 0",
+                "    return_codes: 200",
+                "    return_codes: 178",
+                "  >",
+                ">",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 2",
+                "  network_id: 101",
+                "  time_ms: 0",
+                "  transports: 1",
+                "  dns_lookup_batch <",
+                "    event_types: 1",
+                "    event_types: 1",
+                "    event_types: 1",
+                "    event_types: 2",
+                "    event_types: 1",
+                "    event_types: 1",
+                "    latencies_ms: 56",
+                "    latencies_ms: 78",
+                "    latencies_ms: 14",
+                "    latencies_ms: 56",
+                "    latencies_ms: 78",
+                "    latencies_ms: 14",
+                "    return_codes: 0",
+                "    return_codes: 0",
+                "    return_codes: 0",
+                "    return_codes: 0",
+                "    return_codes: 0",
+                "    return_codes: 0",
+                "  >",
+                ">",
+                "version: 2\n");
+        assertEquals(want, got);
     }
 
-    @SmallTest
-    public void testSeveralDmsBatches() throws Exception {
-        log(105, LATENCIES);
-        log(106, LATENCIES);
-        log(105, LATENCIES);
-        log(107, LATENCIES);
-
-        verifyLoggedDnsEvents(
-            new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES),
-            new DnsEvent(106, EVENT_TYPES, RETURN_CODES, LATENCIES),
-            new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES),
-            new DnsEvent(107, EVENT_TYPES, RETURN_CODES, LATENCIES));
-    }
-
-    @SmallTest
-    public void testDnsBatchAndNetworkLost() throws Exception {
-        byte[] eventTypes = Arrays.copyOf(EVENT_TYPES, 20);
-        byte[] returnCodes = Arrays.copyOf(RETURN_CODES, 20);
-        int[] latencies = Arrays.copyOf(LATENCIES, 20);
-
-        log(105, LATENCIES);
-        log(105, latencies);
-        mCallbackCaptor.getValue().onLost(new Network(105));
-        log(105, LATENCIES);
-
-        verifyLoggedDnsEvents(
-            new DnsEvent(105, eventTypes, returnCodes, latencies),
-            new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES),
-            new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES));
-    }
-
-    @SmallTest
-    public void testConcurrentDnsBatchesAndDumps() throws Exception {
-        final long stop = System.currentTimeMillis() + 100;
-        final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null"));
-        new Thread() {
-            public void run() {
-                while (System.currentTimeMillis() < stop) {
-                    mNetdEventListenerService.dump(pw);
-                }
-            }
-        }.start();
-
-        logDnsAsync(105, LATENCIES);
-        logDnsAsync(106, LATENCIES);
-        logDnsAsync(107, LATENCIES);
-
-        verifyLoggedDnsEvents(500,
-            new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES),
-            new DnsEvent(106, EVENT_TYPES, RETURN_CODES, LATENCIES),
-            new DnsEvent(107, EVENT_TYPES, RETURN_CODES, LATENCIES));
-    }
-
-    @SmallTest
-    public void testConcurrentDnsBatchesAndNetworkLoss() throws Exception {
-        logDnsAsync(105, LATENCIES);
-        Thread.sleep(10L);
-        // call onLost() asynchronously to logDnsAsync's onDnsEvent() calls.
-        mCallbackCaptor.getValue().onLost(new Network(105));
-
-        // do not verify batch with unpredictable length
-        verify(mLog, timeout(500).times(1)).log(any(Parcelable.class));
-    }
-
-    @SmallTest
+    @Test
     public void testConnectLogging() throws Exception {
+        asyncDump(100);
+
         final int OK = 0;
         Thread[] logActions = {
             // ignored
-            connectEventAction(OsConstants.EALREADY, 0, EXAMPLE_IPV4),
-            connectEventAction(OsConstants.EALREADY, 0, EXAMPLE_IPV6),
-            connectEventAction(OsConstants.EINPROGRESS, 0, EXAMPLE_IPV4),
-            connectEventAction(OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6),
-            connectEventAction(OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6),
+            connectEventAction(100, OsConstants.EALREADY, 0, EXAMPLE_IPV4),
+            connectEventAction(100, OsConstants.EALREADY, 0, EXAMPLE_IPV6),
+            connectEventAction(100, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV4),
+            connectEventAction(101, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6),
+            connectEventAction(101, OsConstants.EINPROGRESS, 0, EXAMPLE_IPV6),
             // valid latencies
-            connectEventAction(OK, 110, EXAMPLE_IPV4),
-            connectEventAction(OK, 23, EXAMPLE_IPV4),
-            connectEventAction(OK, 45, EXAMPLE_IPV4),
-            connectEventAction(OK, 56, EXAMPLE_IPV4),
-            connectEventAction(OK, 523, EXAMPLE_IPV6),
-            connectEventAction(OK, 214, EXAMPLE_IPV6),
-            connectEventAction(OK, 67, EXAMPLE_IPV6),
+            connectEventAction(100, OK, 110, EXAMPLE_IPV4),
+            connectEventAction(100, OK, 23, EXAMPLE_IPV4),
+            connectEventAction(100, OK, 45, EXAMPLE_IPV4),
+            connectEventAction(101, OK, 56, EXAMPLE_IPV4),
+            connectEventAction(101, OK, 523, EXAMPLE_IPV6),
+            connectEventAction(101, OK, 214, EXAMPLE_IPV6),
+            connectEventAction(101, OK, 67, EXAMPLE_IPV6),
             // errors
-            connectEventAction(OsConstants.EPERM, 0, EXAMPLE_IPV4),
-            connectEventAction(OsConstants.EPERM, 0, EXAMPLE_IPV4),
-            connectEventAction(OsConstants.EAGAIN, 0, EXAMPLE_IPV4),
-            connectEventAction(OsConstants.EACCES, 0, EXAMPLE_IPV4),
-            connectEventAction(OsConstants.EACCES, 0, EXAMPLE_IPV4),
-            connectEventAction(OsConstants.EACCES, 0, EXAMPLE_IPV6),
-            connectEventAction(OsConstants.EADDRINUSE, 0, EXAMPLE_IPV4),
-            connectEventAction(OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV4),
-            connectEventAction(OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV6),
-            connectEventAction(OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV6),
-            connectEventAction(OsConstants.ECONNREFUSED, 0, EXAMPLE_IPV4),
+            connectEventAction(100, OsConstants.EPERM, 0, EXAMPLE_IPV4),
+            connectEventAction(101, OsConstants.EPERM, 0, EXAMPLE_IPV4),
+            connectEventAction(100, OsConstants.EAGAIN, 0, EXAMPLE_IPV4),
+            connectEventAction(100, OsConstants.EACCES, 0, EXAMPLE_IPV4),
+            connectEventAction(101, OsConstants.EACCES, 0, EXAMPLE_IPV4),
+            connectEventAction(101, OsConstants.EACCES, 0, EXAMPLE_IPV6),
+            connectEventAction(100, OsConstants.EADDRINUSE, 0, EXAMPLE_IPV4),
+            connectEventAction(101, OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV4),
+            connectEventAction(100, OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV6),
+            connectEventAction(100, OsConstants.ETIMEDOUT, 0, EXAMPLE_IPV6),
+            connectEventAction(101, OsConstants.ECONNREFUSED, 0, EXAMPLE_IPV4),
         };
 
         for (Thread t : logActions) {
@@ -209,113 +201,124 @@
             t.join();
         }
 
-        List<IpConnectivityEvent> events = new ArrayList<>();
-        mNetdEventListenerService.flushStatistics(events);
-
-        IpConnectivityEvent got = events.get(0);
+        String got = flushStatistics();
         String want = String.join("\n",
-                "if_name: \"\"",
-                "link_layer: 0",
-                "network_id: 0",
-                "time_ms: 0",
-                "transports: 0",
-                "connect_statistics <",
-                "  connect_blocking_count: 7",
-                "  connect_count: 12",
-                "  errnos_counters <",
-                "    key: 1",
-                "    value: 2",
+                "dropped_events: 0",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 4",
+                "  network_id: 100",
+                "  time_ms: 0",
+                "  transports: 2",
+                "  connect_statistics <",
+                "    connect_blocking_count: 3",
+                "    connect_count: 6",
+                "    errnos_counters <",
+                "      key: 1",
+                "      value: 1",
+                "    >",
+                "    errnos_counters <",
+                "      key: 11",
+                "      value: 1",
+                "    >",
+                "    errnos_counters <",
+                "      key: 13",
+                "      value: 1",
+                "    >",
+                "    errnos_counters <",
+                "      key: 98",
+                "      value: 1",
+                "    >",
+                "    errnos_counters <",
+                "      key: 110",
+                "      value: 2",
+                "    >",
+                "    ipv6_addr_count: 1",
+                "    latencies_ms: 23",
+                "    latencies_ms: 45",
+                "    latencies_ms: 110",
                 "  >",
-                "  errnos_counters <",
-                "    key: 11",
-                "    value: 1",
+                ">",
+                "events <",
+                "  if_name: \"\"",
+                "  link_layer: 2",
+                "  network_id: 101",
+                "  time_ms: 0",
+                "  transports: 1",
+                "  connect_statistics <",
+                "    connect_blocking_count: 4",
+                "    connect_count: 6",
+                "    errnos_counters <",
+                "      key: 1",
+                "      value: 1",
+                "    >",
+                "    errnos_counters <",
+                "      key: 13",
+                "      value: 2",
+                "    >",
+                "    errnos_counters <",
+                "      key: 110",
+                "      value: 1",
+                "    >",
+                "    errnos_counters <",
+                "      key: 111",
+                "      value: 1",
+                "    >",
+                "    ipv6_addr_count: 5",
+                "    latencies_ms: 56",
+                "    latencies_ms: 67",
+                "    latencies_ms: 214",
+                "    latencies_ms: 523",
                 "  >",
-                "  errnos_counters <",
-                "    key: 13",
-                "    value: 3",
-                "  >",
-                "  errnos_counters <",
-                "    key: 98",
-                "    value: 1",
-                "  >",
-                "  errnos_counters <",
-                "    key: 110",
-                "    value: 3",
-                "  >",
-                "  errnos_counters <",
-                "    key: 111",
-                "    value: 1",
-                "  >",
-                "  ipv6_addr_count: 6",
-                "  latencies_ms: 23",
-                "  latencies_ms: 45",
-                "  latencies_ms: 56",
-                "  latencies_ms: 67",
-                "  latencies_ms: 110",
-                "  latencies_ms: 214",
-                "  latencies_ms: 523",
-                ">\n");
-        verifyConnectEvent(want, got);
+                ">",
+                "version: 2\n");
+        assertEquals(want, got);
     }
 
-    Thread connectEventAction(int error, int latencyMs, String ipAddr) {
+    Thread connectEventAction(int netId, int error, int latencyMs, String ipAddr) {
         return new Thread(() -> {
             try {
-                mNetdEventListenerService.onConnectEvent(100, error, latencyMs, ipAddr, 80, 1);
+                mNetdEventListenerService.onConnectEvent(netId, error, latencyMs, ipAddr, 80, 1);
             } catch (Exception e) {
                 fail(e.toString());
             }
         });
     }
 
-    void log(int netId, int[] latencies) {
-        try {
-            for (int l : latencies) {
-                mNetdEventListenerService.onDnsEvent(netId, EVENT_TYPE, RETURN_CODE, l, null, null,
-                        0, 0);
+    void dnsEvent(int netId, int type, int result, int latency) throws Exception {
+        mNetdEventListenerService.onDnsEvent(netId, type, result, latency, "", null, 0, 0);
+    }
+
+    void asyncDump(long durationMs) throws Exception {
+        final long stop = System.currentTimeMillis() + durationMs;
+        final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null"));
+        new Thread(() -> {
+            while (System.currentTimeMillis() < stop) {
+                mNetdEventListenerService.dump(pw);
             }
-        } catch (RemoteException re) {
-            throw re.rethrowFromSystemServer();
-        }
+        }).start();
     }
 
-    void logDnsAsync(int netId, int[] latencies) {
-        new Thread(() -> log(netId, latencies)).start();
-    }
+    // TODO: instead of comparing textpb to textpb, parse textpb and compare proto to proto.
+    String flushStatistics() throws Exception {
+        IpConnectivityMetrics metricsService =
+                new IpConnectivityMetrics(mock(Context.class), (ctx) -> 2000);
+        metricsService.mNetdListener = mNetdEventListenerService;
 
-    void verifyLoggedDnsEvents(DnsEvent... expected) {
-        verifyLoggedDnsEvents(0, expected);
-    }
-
-    void verifyLoggedDnsEvents(int wait, DnsEvent... expectedEvents) {
-        verify(mLog, timeout(wait).times(expectedEvents.length)).log(mDnsEvCaptor.capture());
-        for (DnsEvent got : mDnsEvCaptor.getAllValues()) {
-            OptionalInt index = IntStream.range(0, expectedEvents.length)
-                    .filter(i -> dnsEventsEqual(expectedEvents[i], got))
-                    .findFirst();
-            // Don't match same expected event more than once.
-            index.ifPresent(i -> expectedEvents[i] = null);
-            assertTrue(index.isPresent());
-        }
-    }
-
-    /** equality function for DnsEvent to avoid overriding equals() and hashCode(). */
-    static boolean dnsEventsEqual(DnsEvent expected, DnsEvent got) {
-        return (expected == got) || ((expected != null) && (got != null)
-                && (expected.netId == got.netId)
-                && Arrays.equals(expected.eventTypes, got.eventTypes)
-                && Arrays.equals(expected.returnCodes, got.returnCodes)
-                && Arrays.equals(expected.latenciesMs, got.latenciesMs));
-    }
-
-    static void verifyConnectEvent(String expected, IpConnectivityEvent got) {
-        try {
-            Arrays.sort(got.getConnectStatistics().latenciesMs);
-            Arrays.sort(got.getConnectStatistics().errnosCounters,
+        StringWriter buffer = new StringWriter();
+        PrintWriter writer = new PrintWriter(buffer);
+        metricsService.impl.dump(null, writer, new String[]{"flush"});
+        byte[] bytes = Base64.decode(buffer.toString(), Base64.DEFAULT);
+        IpConnectivityLog log = IpConnectivityLog.parseFrom(bytes);
+        for (IpConnectivityEvent ev : log.events) {
+            if (ev.getConnectStatistics() == null) {
+                continue;
+            }
+            // Sort repeated fields of connect() events arriving in non-deterministic order.
+            Arrays.sort(ev.getConnectStatistics().latenciesMs);
+            Arrays.sort(ev.getConnectStatistics().errnosCounters,
                     Comparator.comparingInt((p) -> p.key));
-            assertEquals(expected, got.toString());
-        } catch (Exception e) {
-            fail(e.toString());
         }
+        return log.toString();
     }
 }
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 3d76439..b86188f 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -377,8 +377,8 @@
         versioned_file_desc.config.sdkVersion = (uint16_t)sdk_level;
 
         FileOperation new_file_op;
-        new_file_op.xml_to_flatten =
-            util::make_unique<xml::XmlResource>(versioned_file_desc, doc->root->Clone());
+        new_file_op.xml_to_flatten = util::make_unique<xml::XmlResource>(
+            versioned_file_desc, StringPool{}, doc->root->Clone());
         new_file_op.config = versioned_file_desc.config;
         new_file_op.entry = file_op->entry;
         new_file_op.dst_path =
@@ -1873,7 +1873,8 @@
                             &options.extensions_to_not_compress)
           .OptionalFlagList("--split",
                             "Split resources matching a set of configs out to a Split APK.\n"
-                            "Syntax: path/to/output.apk:<config>[,<config>[...]].",
+                            "Syntax: path/to/output.apk:<config>[,<config>[...]].\n"
+                            "On Windows, use a semicolon ';' separator instead.",
                             &split_args)
           .OptionalSwitch("-v", "Enables verbose logging.", &verbose);
 
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index 8f8e0c8..e99ee8a 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -302,7 +302,8 @@
                             &configs)
           .OptionalFlagList("--split",
                             "Split resources matching a set of configs out to a "
-                            "Split APK.\nSyntax: path/to/output.apk:<config>[,<config>[...]].",
+                            "Split APK.\nSyntax: path/to/output.apk;<config>[,<config>[...]].\n"
+                            "On Windows, use a semicolon ';' separator instead.",
                             &split_args)
           .OptionalSwitch("--enable-sparse-encoding",
                           "Enables encoding sparse entries using a binary search tree.\n"
diff --git a/tools/aapt2/cmd/Util.cpp b/tools/aapt2/cmd/Util.cpp
index fd94bbc..14d4260 100644
--- a/tools/aapt2/cmd/Util.cpp
+++ b/tools/aapt2/cmd/Util.cpp
@@ -57,10 +57,17 @@
   CHECK(out_path != nullptr);
   CHECK(out_split != nullptr);
 
-  std::vector<std::string> parts = util::Split(arg, ':');
+#ifdef _WIN32
+  const char sSeparator = ';';
+#else
+  const char sSeparator = ':';
+#endif
+
+  std::vector<std::string> parts = util::Split(arg, sSeparator);
   if (parts.size() != 2) {
     diag->Error(DiagMessage() << "invalid split parameter '" << arg << "'");
-    diag->Note(DiagMessage() << "should be --split path/to/output.apk:<config>[,<config>...]");
+    diag->Note(DiagMessage() << "should be --split path/to/output.apk" << sSeparator
+                             << "<config>[,<config>...].");
     return false;
   }
 
diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp
index 4a278f63..6055190 100644
--- a/tools/aapt2/xml/XmlDom.cpp
+++ b/tools/aapt2/xml/XmlDom.cpp
@@ -224,7 +224,8 @@
 
   XML_ParserFree(parser);
   if (stack.root) {
-    return util::make_unique<XmlResource>(ResourceFile{{}, {}, source}, std::move(stack.root));
+    return util::make_unique<XmlResource>(ResourceFile{{}, {}, source}, StringPool{},
+                                          std::move(stack.root));
   }
   return {};
 }
@@ -357,7 +358,7 @@
       }
     }
   }
-  return util::make_unique<XmlResource>(ResourceFile{}, std::move(root), std::move(string_pool));
+  return util::make_unique<XmlResource>(ResourceFile{}, std::move(string_pool), std::move(root));
 }
 
 std::unique_ptr<Node> Namespace::Clone() {
diff --git a/tools/aapt2/xml/XmlDom.h b/tools/aapt2/xml/XmlDom.h
index f1d0953..6950c30 100644
--- a/tools/aapt2/xml/XmlDom.h
+++ b/tools/aapt2/xml/XmlDom.h
@@ -128,8 +128,13 @@
 class XmlResource {
  public:
   ResourceFile file;
-  std::unique_ptr<xml::Node> root;
+
+  // StringPool must come before the xml::Node. Destructors are called in reverse order, and
+  // the xml::Node may have StringPool references that need to be destroyed before the StringPool
+  // is destroyed.
   StringPool string_pool;
+
+  std::unique_ptr<xml::Node> root;
 };
 
 /**