Merge "Implement construction of container layers"
diff --git a/Android.mk b/Android.mk
index 29454e4..84b708e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -325,6 +325,7 @@
 include $(CLEAR_VARS)
 
 # File names of final API lists
+LOCAL_WHITELIST := $(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST)
 LOCAL_LIGHT_GREYLIST := $(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST)
 LOCAL_DARK_GREYLIST := $(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST)
 LOCAL_BLACKLIST := $(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST)
@@ -374,6 +375,13 @@
 # or have alternative rules for building them. Other rules in the build system
 # should depend on the files in the build folder.
 
+# Merge whitelist from:
+# (1) public API stubs
+# (2) whitelist entries generated by class2greylist (PRIVATE_WHITELIST_INPUTS)
+$(LOCAL_WHITELIST): $(LOCAL_SRC_PUBLIC_API)
+	sort $(LOCAL_SRC_PUBLIC_API) $(PRIVATE_WHITELIST_INPUTS) > $@
+	$(call assert-has-no-duplicates,$@)
+
 # Merge light greylist from multiple files:
 #  (1) manual greylist LOCAL_SRC_GREYLIST
 #  (2) list of usages from vendor apps LOCAL_SRC_VENDOR_LIST
@@ -384,6 +392,7 @@
 #      Automatically adds all methods which match the signatures in
 #      REGEX_SERIALIZATION. These are greylisted in order to allow applications
 #      to write their own serializers.
+#  (5) greylist entries generated by class2greylist (PRIVATE_GREYLIST_INPUTS)
 $(LOCAL_LIGHT_GREYLIST): REGEX_SERIALIZATION := \
     "readObject\(Ljava/io/ObjectInputStream;\)V" \
     "readObjectNoData\(\)V" \
@@ -392,7 +401,7 @@
     "serialPersistentFields:\[Ljava/io/ObjectStreamField;" \
     "writeObject\(Ljava/io/ObjectOutputStream;\)V" \
     "writeReplace\(\)Ljava/lang/Object;"
-$(LOCAL_LIGHT_GREYLIST): $(LOCAL_SRC_ALL)
+$(LOCAL_LIGHT_GREYLIST): $(LOCAL_SRC_ALL) $(LOCAL_WHITELIST)
 	sort $(LOCAL_SRC_GREYLIST) $(LOCAL_SRC_VENDOR_LIST) $(PRIVATE_GREYLIST_INPUTS) \
 	     <(grep -E "\->("$(subst $(space),"|",$(REGEX_SERIALIZATION))")$$" \
 	               $(LOCAL_SRC_PRIVATE_API)) \
@@ -400,6 +409,7 @@
 	     > $@
 	$(call assert-has-no-duplicates,$@)
 	$(call assert-is-subset,$@,$(LOCAL_SRC_PRIVATE_API))
+	$(call assert-has-no-overlap,$@,$(LOCAL_WHITELIST))
 	$(call assert-has-no-overlap,$@,$(LOCAL_SRC_FORCE_BLACKLIST))
 
 # Generate dark greylist as remaining classes and class members in the same
@@ -412,9 +422,9 @@
 #       name but do not contain another forward-slash in the class name, e.g.
 #       matching '^Lpackage/subpackage/[^/;]*;'
 #   (4) subtract entries shared with LOCAL_LIGHT_GREYLIST
-$(LOCAL_DARK_GREYLIST): $(LOCAL_SRC_ALL) $(LOCAL_LIGHT_GREYLIST)
-	comm -13 <(sort $(LOCAL_LIGHT_GREYLIST) $(LOCAL_SRC_FORCE_BLACKLIST)) \
-	         <(cat $(LOCAL_SRC_PUBLIC_API) $(LOCAL_LIGHT_GREYLIST) | \
+$(LOCAL_DARK_GREYLIST): $(LOCAL_SRC_ALL) $(LOCAL_WHITELIST) $(LOCAL_LIGHT_GREYLIST)
+	comm -13 <(sort $(LOCAL_WHITELIST) $(LOCAL_LIGHT_GREYLIST) $(LOCAL_SRC_FORCE_BLACKLIST)) \
+	         <(cat $(LOCAL_WHITELIST) $(LOCAL_LIGHT_GREYLIST) | \
 	               sed 's/\->.*//' | sed 's/\(.*\/\).*/\1/' | sort | uniq | \
 	               while read PKG_NAME; do \
 	                   grep -E "^$${PKG_NAME}[^/;]*;" $(LOCAL_SRC_PRIVATE_API); \
@@ -422,16 +432,18 @@
 	         > $@
 	$(call assert-is-subset,$@,$(LOCAL_SRC_PRIVATE_API))
 	$(call assert-has-no-duplicates,$@)
+	$(call assert-has-no-overlap,$@,$(LOCAL_WHITELIST))
 	$(call assert-has-no-overlap,$@,$(LOCAL_LIGHT_GREYLIST))
 	$(call assert-has-no-overlap,$@,$(LOCAL_SRC_FORCE_BLACKLIST))
 
 # Generate blacklist as private API minus (light greylist plus dark greylist).
-$(LOCAL_BLACKLIST): $(LOCAL_SRC_ALL) $(LOCAL_LIGHT_GREYLIST) $(LOCAL_DARK_GREYLIST)
-	comm -13 <(sort $(LOCAL_LIGHT_GREYLIST) $(LOCAL_DARK_GREYLIST)) \
+$(LOCAL_BLACKLIST): $(LOCAL_SRC_ALL) $(LOCAL_WHITELIST) $(LOCAL_LIGHT_GREYLIST) $(LOCAL_DARK_GREYLIST)
+	comm -13 <(sort $(LOCAL_WHITELIST) $(LOCAL_LIGHT_GREYLIST) $(LOCAL_DARK_GREYLIST)) \
 	         <(sort $(LOCAL_SRC_PRIVATE_API)) \
 	         > $@
 	$(call assert-is-subset,$@,$(LOCAL_SRC_PRIVATE_API))
 	$(call assert-has-no-duplicates,$@)
+	$(call assert-has-no-overlap,$@,$(LOCAL_WHITELIST))
 	$(call assert-has-no-overlap,$@,$(LOCAL_LIGHT_GREYLIST))
 	$(call assert-has-no-overlap,$@,$(LOCAL_DARK_GREYLIST))
 	$(call assert-is-subset,$(LOCAL_SRC_FORCE_BLACKLIST),$@)
diff --git a/api/current.txt b/api/current.txt
index 13ea5cc..ca86918 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -57,8 +57,6 @@
     field public static final java.lang.String CALL_PRIVILEGED = "android.permission.CALL_PRIVILEGED";
     field public static final java.lang.String CAMERA = "android.permission.CAMERA";
     field public static final java.lang.String CAPTURE_AUDIO_OUTPUT = "android.permission.CAPTURE_AUDIO_OUTPUT";
-    field public static final java.lang.String CAPTURE_SECURE_VIDEO_OUTPUT = "android.permission.CAPTURE_SECURE_VIDEO_OUTPUT";
-    field public static final java.lang.String CAPTURE_VIDEO_OUTPUT = "android.permission.CAPTURE_VIDEO_OUTPUT";
     field public static final java.lang.String CHANGE_COMPONENT_ENABLED_STATE = "android.permission.CHANGE_COMPONENT_ENABLED_STATE";
     field public static final java.lang.String CHANGE_CONFIGURATION = "android.permission.CHANGE_CONFIGURATION";
     field public static final java.lang.String CHANGE_NETWORK_STATE = "android.permission.CHANGE_NETWORK_STATE";
@@ -103,7 +101,6 @@
     field public static final java.lang.String READ_CALL_LOG = "android.permission.READ_CALL_LOG";
     field public static final java.lang.String READ_CONTACTS = "android.permission.READ_CONTACTS";
     field public static final deprecated java.lang.String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
-    field public static final java.lang.String READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER";
     field public static final deprecated java.lang.String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
     field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS";
     field public static final java.lang.String READ_MEDIA_AUDIO = "android.permission.READ_MEDIA_AUDIO";
@@ -42722,6 +42719,7 @@
     method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
     method public boolean isConcurrentVoiceAndDataSupported();
     method public boolean isDataEnabled();
+    method public boolean isDataRoamingEnabled();
     method public boolean isHearingAidCompatibilitySupported();
     method public boolean isNetworkRoaming();
     method public boolean isSmsCapable();
diff --git a/api/system-current.txt b/api/system-current.txt
index 41175798..04d31bd 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -46,9 +46,7 @@
     field public static final java.lang.String CAMERA_DISABLE_TRANSMIT_LED = "android.permission.CAMERA_DISABLE_TRANSMIT_LED";
     field public static final java.lang.String CAPTURE_AUDIO_HOTWORD = "android.permission.CAPTURE_AUDIO_HOTWORD";
     field public static final java.lang.String CAPTURE_AUDIO_OUTPUT = "android.permission.CAPTURE_AUDIO_OUTPUT";
-    field public static final java.lang.String CAPTURE_SECURE_VIDEO_OUTPUT = "android.permission.CAPTURE_SECURE_VIDEO_OUTPUT";
     field public static final java.lang.String CAPTURE_TV_INPUT = "android.permission.CAPTURE_TV_INPUT";
-    field public static final java.lang.String CAPTURE_VIDEO_OUTPUT = "android.permission.CAPTURE_VIDEO_OUTPUT";
     field public static final java.lang.String CHANGE_APP_IDLE_STATE = "android.permission.CHANGE_APP_IDLE_STATE";
     field public static final java.lang.String CHANGE_COMPONENT_ENABLED_STATE = "android.permission.CHANGE_COMPONENT_ENABLED_STATE";
     field public static final java.lang.String CHANGE_CONFIGURATION = "android.permission.CHANGE_CONFIGURATION";
@@ -134,7 +132,6 @@
     field public static final java.lang.String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES";
     field public static final java.lang.String READ_CONTENT_RATING_SYSTEMS = "android.permission.READ_CONTENT_RATING_SYSTEMS";
     field public static final java.lang.String READ_DREAM_STATE = "android.permission.READ_DREAM_STATE";
-    field public static final java.lang.String READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER";
     field public static final java.lang.String READ_INSTALL_SESSIONS = "android.permission.READ_INSTALL_SESSIONS";
     field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS";
     field public static final java.lang.String READ_NETWORK_USAGE_HISTORY = "android.permission.READ_NETWORK_USAGE_HISTORY";
@@ -5399,6 +5396,7 @@
     method public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
     method public void setDataActivationState(int);
     method public deprecated void setDataEnabled(int, boolean);
+    method public void setDataRoamingEnabled(boolean);
     method public boolean setRadio(boolean);
     method public boolean setRadioPower(boolean);
     method public void setSimPowerState(int);
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 196f89c..65a0a4b 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -1,14 +1,11 @@
-Landroid/accessibilityservice/IAccessibilityServiceConnection$Stub;-><init>()V
 Landroid/accessibilityservice/IAccessibilityServiceConnection$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accessibilityservice/IAccessibilityServiceConnection;
 Landroid/accounts/IAccountAuthenticator$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/accounts/IAccountAuthenticator$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/accounts/IAccountAuthenticator$Stub;-><init>()V
 Landroid/accounts/IAccountAuthenticator$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountAuthenticator;
 Landroid/accounts/IAccountAuthenticator;->addAccount(Landroid/accounts/IAccountAuthenticatorResponse;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Landroid/os/Bundle;)V
-Landroid/accounts/IAccountAuthenticator;->addAccountFromCredentials(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;Landroid/os/Bundle;)V
 Landroid/accounts/IAccountAuthenticator;->confirmCredentials(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;Landroid/os/Bundle;)V
 Landroid/accounts/IAccountAuthenticator;->editProperties(Landroid/accounts/IAccountAuthenticatorResponse;Ljava/lang/String;)V
-Landroid/accounts/IAccountAuthenticator;->getAccountCredentialsForCloning(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;)V
 Landroid/accounts/IAccountAuthenticator;->getAccountRemovalAllowed(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;)V
 Landroid/accounts/IAccountAuthenticator;->getAuthToken(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;Ljava/lang/String;Landroid/os/Bundle;)V
 Landroid/accounts/IAccountAuthenticator;->getAuthTokenLabel(Landroid/accounts/IAccountAuthenticatorResponse;Ljava/lang/String;)V
@@ -51,9 +48,6 @@
 Landroid/app/backup/IFullBackupRestoreObserver$Stub;-><init>()V
 Landroid/app/backup/IRestoreObserver$Stub;-><init>()V
 Landroid/app/DownloadManager;->restartDownload([J)V
-Landroid/app/IActivityController;->activityResuming(Ljava/lang/String;)Z
-Landroid/app/IActivityController;->activityStarting(Landroid/content/Intent;Ljava/lang/String;)Z
-Landroid/app/IActivityController;->appNotResponding(Ljava/lang/String;ILjava/lang/String;)I
 Landroid/app/IActivityManager$Stub$Proxy;->getConfiguration()Landroid/content/res/Configuration;
 Landroid/app/IActivityManager$Stub$Proxy;->getLaunchedFromUid(Landroid/os/IBinder;)I
 Landroid/app/IActivityManager$Stub$Proxy;->getProcessLimit()I
@@ -66,7 +60,6 @@
 Landroid/app/IActivityManager;->bindService(Landroid/app/IApplicationThread;Landroid/os/IBinder;Landroid/content/Intent;Ljava/lang/String;Landroid/app/IServiceConnection;ILjava/lang/String;I)I
 Landroid/app/IActivityManager;->broadcastIntent(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I
 Landroid/app/IActivityManager;->checkPermission(Ljava/lang/String;II)I
-Landroid/app/IActivityManager;->enterSafeMode()V
 Landroid/app/IActivityManager;->finishActivity(Landroid/os/IBinder;ILandroid/content/Intent;I)Z
 Landroid/app/IActivityManager;->finishHeavyWeightApp()V
 Landroid/app/IActivityManager;->finishReceiver(Landroid/os/IBinder;ILjava/lang/String;Landroid/os/Bundle;ZI)V
@@ -92,7 +85,6 @@
 Landroid/app/IActivityManager;->isTopOfTask(Landroid/os/IBinder;)Z
 Landroid/app/IActivityManager;->isUserRunning(II)Z
 Landroid/app/IActivityManager;->killAllBackgroundProcesses()V
-Landroid/app/IActivityManager;->killApplicationProcess(Ljava/lang/String;I)V
 Landroid/app/IActivityManager;->killBackgroundProcesses(Ljava/lang/String;I)V
 Landroid/app/IActivityManager;->moveActivityTaskToBack(Landroid/os/IBinder;Z)Z
 Landroid/app/IActivityManager;->moveTaskToFront(IILandroid/os/Bundle;)V
@@ -135,7 +127,6 @@
 Landroid/app/IActivityManager;->stopUser(IZLandroid/app/IStopUserCallback;)I
 Landroid/app/IActivityManager;->suppressResizeConfigChanges(Z)V
 Landroid/app/IActivityManager;->switchUser(I)Z
-Landroid/app/IActivityManager;->unbindBackupAgent(Landroid/content/pm/ApplicationInfo;)V
 Landroid/app/IActivityManager;->unbindService(Landroid/app/IServiceConnection;)Z
 Landroid/app/IActivityManager;->unhandledBack()V
 Landroid/app/IActivityManager;->unlockUser(I[B[BLandroid/os/IProgressListener;)Z
@@ -145,32 +136,23 @@
 Landroid/app/IActivityManager;->updateConfiguration(Landroid/content/res/Configuration;)Z
 Landroid/app/IActivityManager;->updatePersistentConfiguration(Landroid/content/res/Configuration;)V
 Landroid/app/IAlarmManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/app/IAlarmManager$Stub;-><init>()V
 Landroid/app/IAlarmManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IAlarmManager;
 Landroid/app/IAlarmManager$Stub;->TRANSACTION_remove:I
 Landroid/app/IAlarmManager$Stub;->TRANSACTION_set:I
 Landroid/app/IAlarmManager;->getNextAlarmClock(I)Landroid/app/AlarmManager$AlarmClockInfo;
 Landroid/app/IAlarmManager;->set(Ljava/lang/String;IJJJILandroid/app/PendingIntent;Landroid/app/IAlarmListener;Ljava/lang/String;Landroid/os/WorkSource;Landroid/app/AlarmManager$AlarmClockInfo;)V
-Landroid/app/IApplicationThread;->processInBackground()V
 Landroid/app/IApplicationThread;->scheduleBindService(Landroid/os/IBinder;Landroid/content/Intent;ZI)V
 Landroid/app/IApplicationThread;->scheduleCreateService(Landroid/os/IBinder;Landroid/content/pm/ServiceInfo;Landroid/content/res/CompatibilityInfo;I)V
-Landroid/app/IApplicationThread;->scheduleExit()V
-Landroid/app/IApplicationThread;->scheduleLowMemory()V
 Landroid/app/IApplicationThread;->scheduleStopService(Landroid/os/IBinder;)V
-Landroid/app/IApplicationThread;->scheduleSuicide()V
 Landroid/app/IApplicationThread;->scheduleTrimMemory(I)V
 Landroid/app/IApplicationThread;->scheduleUnbindService(Landroid/os/IBinder;Landroid/content/Intent;)V
-Landroid/app/IApplicationThread;->updateTimeZone()V
 Landroid/app/IAppTask;->getTaskInfo()Landroid/app/ActivityManager$RecentTaskInfo;
-Landroid/app/IBackupAgent$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IBackupAgent;
 Landroid/app/IInputForwarder;->forwardEvent(Landroid/view/InputEvent;)Z
 Landroid/app/IInstrumentationWatcher$Stub;-><init>()V
 Landroid/app/IInstrumentationWatcher$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IInstrumentationWatcher;
-Landroid/app/IInstrumentationWatcher;->instrumentationFinished(Landroid/content/ComponentName;ILandroid/os/Bundle;)V
 Landroid/app/IInstrumentationWatcher;->instrumentationStatus(Landroid/content/ComponentName;ILandroid/os/Bundle;)V
 Landroid/app/INotificationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/app/INotificationManager$Stub$Proxy;->areNotificationsEnabledForPackage(Ljava/lang/String;I)Z
-Landroid/app/INotificationManager$Stub;-><init>()V
 Landroid/app/INotificationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/INotificationManager;
 Landroid/app/INotificationManager$Stub;->TRANSACTION_enqueueNotificationWithTag:I
 Landroid/app/INotificationManager;->areNotificationsEnabledForPackage(Ljava/lang/String;I)Z
@@ -198,13 +180,11 @@
 Landroid/app/IStopUserCallback$Stub;-><init>()V
 Landroid/app/IStopUserCallback;->userStopped(I)V
 Landroid/app/ITransientNotification$Stub;-><init>()V
-Landroid/app/ITransientNotification;->hide()V
 Landroid/app/ITransientNotification;->show(Landroid/os/IBinder;)V
 Landroid/app/IUiModeManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/app/IUiModeManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IUiModeManager;
 Landroid/app/IUiModeManager;->disableCarMode(I)V
 Landroid/app/IUserSwitchObserver$Stub;-><init>()V
-Landroid/app/IWallpaperManager$Stub;-><init>()V
 Landroid/app/IWallpaperManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IWallpaperManager;
 Landroid/app/IWallpaperManager;->getHeightHint()I
 Landroid/app/IWallpaperManager;->getWallpaper(Ljava/lang/String;Landroid/app/IWallpaperManagerCallback;ILandroid/os/Bundle;I)Landroid/os/ParcelFileDescriptor;
@@ -213,7 +193,6 @@
 Landroid/app/IWallpaperManager;->hasNamedWallpaper(Ljava/lang/String;)Z
 Landroid/app/IWallpaperManager;->setWallpaperComponent(Landroid/content/ComponentName;)V
 Landroid/app/IWallpaperManagerCallback$Stub;-><init>()V
-Landroid/app/IWallpaperManagerCallback;->onWallpaperChanged()V
 Landroid/app/job/IJobCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/app/job/IJobCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/app/job/IJobCallback$Stub;-><init>()V
@@ -307,7 +286,6 @@
 Landroid/content/IIntentReceiver$Stub;-><init>()V
 Landroid/content/IIntentReceiver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IIntentReceiver;
 Landroid/content/IIntentReceiver;->performReceive(Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZI)V
-Landroid/content/IIntentSender$Stub;-><init>()V
 Landroid/content/IIntentSender$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IIntentSender;
 Landroid/content/IOnPrimaryClipChangedListener$Stub;-><init>()V
 Landroid/content/IOnPrimaryClipChangedListener$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IOnPrimaryClipChangedListener;
@@ -378,7 +356,6 @@
 Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;II)Landroid/content/pm/PackageInfo;
 Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackagesForUid(I)[Ljava/lang/String;
 Landroid/content/pm/IPackageManager$Stub$Proxy;->getSystemSharedLibraryNames()[Ljava/lang/String;
-Landroid/content/pm/IPackageManager$Stub;-><init>()V
 Landroid/content/pm/IPackageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageManager;
 Landroid/content/pm/IPackageManager$Stub;->TRANSACTION_getApplicationInfo:I
 Landroid/content/pm/IPackageManager;->addPermission(Landroid/content/pm/PermissionInfo;)Z
@@ -386,12 +363,10 @@
 Landroid/content/pm/IPackageManager;->canonicalToCurrentPackageNames([Ljava/lang/String;)[Ljava/lang/String;
 Landroid/content/pm/IPackageManager;->checkPermission(Ljava/lang/String;Ljava/lang/String;I)I
 Landroid/content/pm/IPackageManager;->checkSignatures(Ljava/lang/String;Ljava/lang/String;)I
-Landroid/content/pm/IPackageManager;->checkUidPermission(Ljava/lang/String;I)I
 Landroid/content/pm/IPackageManager;->checkUidSignatures(II)I
 Landroid/content/pm/IPackageManager;->clearPackagePreferredActivities(Ljava/lang/String;)V
 Landroid/content/pm/IPackageManager;->currentToCanonicalPackageNames([Ljava/lang/String;)[Ljava/lang/String;
 Landroid/content/pm/IPackageManager;->deleteApplicationCacheFiles(Ljava/lang/String;Landroid/content/pm/IPackageDataObserver;)V
-Landroid/content/pm/IPackageManager;->enterSafeMode()V
 Landroid/content/pm/IPackageManager;->getApplicationEnabledSetting(Ljava/lang/String;I)I
 Landroid/content/pm/IPackageManager;->getAppOpPermissionPackages(Ljava/lang/String;)[Ljava/lang/String;
 Landroid/content/pm/IPackageManager;->getBlockUninstallForUser(Ljava/lang/String;I)Z
@@ -420,7 +395,6 @@
 Landroid/content/pm/IPackageManager;->grantRuntimePermission(Ljava/lang/String;Ljava/lang/String;I)V
 Landroid/content/pm/IPackageManager;->hasSystemUidErrors()Z
 Landroid/content/pm/IPackageManager;->isPackageAvailable(Ljava/lang/String;I)Z
-Landroid/content/pm/IPackageManager;->isProtectedBroadcast(Ljava/lang/String;)Z
 Landroid/content/pm/IPackageManager;->isSafeMode()Z
 Landroid/content/pm/IPackageManager;->isStorageLow()Z
 Landroid/content/pm/IPackageManager;->isUidPrivileged(I)Z
@@ -436,7 +410,6 @@
 Landroid/content/pm/IPackageManager;->setInstallerPackageName(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/content/pm/IPackageManager;->setLastChosenActivity(Landroid/content/Intent;Ljava/lang/String;ILandroid/content/IntentFilter;ILandroid/content/ComponentName;)V
 Landroid/content/pm/IPackageManager;->setPackageStoppedState(Ljava/lang/String;ZI)V
-Landroid/content/pm/IPackageManager;->systemReady()V
 Landroid/content/pm/IPackageMoveObserver$Stub;-><init>()V
 Landroid/content/pm/IPackageMoveObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageMoveObserver;
 Landroid/content/pm/IPackageStatsObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -513,10 +486,12 @@
 Landroid/location/ILocationListener;->onProviderEnabled(Ljava/lang/String;)V
 Landroid/location/ILocationListener;->onStatusChanged(Ljava/lang/String;ILandroid/os/Bundle;)V
 Landroid/location/ILocationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/location/ILocationManager$Stub;-><init>()V
 Landroid/location/ILocationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ILocationManager;
 Landroid/location/ILocationManager$Stub;->TRANSACTION_getAllProviders:I
 Landroid/location/ILocationManager;->getAllProviders()Ljava/util/List;
+Landroid/Manifest$permission;->CAPTURE_SECURE_VIDEO_OUTPUT:Ljava/lang/String;
+Landroid/Manifest$permission;->CAPTURE_VIDEO_OUTPUT:Ljava/lang/String;
+Landroid/Manifest$permission;->READ_FRAME_BUFFER:Ljava/lang/String;
 Landroid/media/IAudioFocusDispatcher;->dispatchAudioFocusChange(ILjava/lang/String;)V
 Landroid/media/IAudioRoutesObserver$Stub;-><init>()V
 Landroid/media/IAudioService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -546,7 +521,6 @@
 Landroid/net/IConnectivityManager$Stub$Proxy;->getTetherableUsbRegexs()[Ljava/lang/String;
 Landroid/net/IConnectivityManager$Stub$Proxy;->getTetheredIfaces()[Ljava/lang/String;
 Landroid/net/IConnectivityManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/net/IConnectivityManager$Stub;-><init>()V
 Landroid/net/IConnectivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/IConnectivityManager;
 Landroid/net/IConnectivityManager;->getActiveLinkProperties()Landroid/net/LinkProperties;
 Landroid/net/IConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
@@ -586,7 +560,6 @@
 Landroid/net/nsd/INsdManager;->getMessenger()Landroid/os/Messenger;
 Landroid/net/SntpClient;-><init>()V
 Landroid/net/wifi/IWifiManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/net/wifi/IWifiManager$Stub;-><init>()V
 Landroid/net/wifi/IWifiManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiManager;
 Landroid/net/wifi/IWifiManager$Stub;->TRANSACTION_getScanResults:I
 Landroid/net/wifi/IWifiManager;->getCurrentNetwork()Landroid/net/Network;
@@ -816,11 +789,9 @@
 Landroid/os/INetworkManagementService;->tetherInterface(Ljava/lang/String;)V
 Landroid/os/INetworkManagementService;->untetherInterface(Ljava/lang/String;)V
 Landroid/os/IPermissionController$Stub$Proxy;->checkPermission(Ljava/lang/String;II)Z
-Landroid/os/IPermissionController$Stub;-><init>()V
 Landroid/os/IPermissionController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPermissionController;
 Landroid/os/IPowerManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/os/IPowerManager$Stub$Proxy;->isLightDeviceIdleMode()Z
-Landroid/os/IPowerManager$Stub;-><init>()V
 Landroid/os/IPowerManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPowerManager;
 Landroid/os/IPowerManager$Stub;->TRANSACTION_acquireWakeLock:I
 Landroid/os/IPowerManager$Stub;->TRANSACTION_goToSleep:I
@@ -1516,7 +1487,6 @@
 Landroid/service/wallpaper/IWallpaperEngine;->destroy()V
 Landroid/service/wallpaper/IWallpaperEngine;->dispatchPointer(Landroid/view/MotionEvent;)V
 Landroid/service/wallpaper/IWallpaperEngine;->dispatchWallpaperCommand(Ljava/lang/String;IIILandroid/os/Bundle;)V
-Landroid/service/wallpaper/IWallpaperEngine;->setDesiredSize(II)V
 Landroid/service/wallpaper/IWallpaperEngine;->setVisibility(Z)V
 Landroid/service/wallpaper/IWallpaperService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/wallpaper/IWallpaperService;
 Landroid/speech/IRecognitionListener;->onEvent(ILandroid/os/Bundle;)V
@@ -1594,28 +1564,18 @@
 Landroid/view/accessibility/IAccessibilityInteractionConnectionCallback;->setFindAccessibilityNodeInfosResult(Ljava/util/List;I)V
 Landroid/view/accessibility/IAccessibilityInteractionConnectionCallback;->setPerformAccessibilityActionResult(ZI)V
 Landroid/view/accessibility/IAccessibilityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/view/accessibility/IAccessibilityManager$Stub;-><init>()V
 Landroid/view/accessibility/IAccessibilityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/accessibility/IAccessibilityManager;
 Landroid/view/accessibility/IAccessibilityManager;->getEnabledAccessibilityServiceList(II)Ljava/util/List;
 Landroid/view/AccessibilityIterators$AbstractTextSegmentIterator;-><init>()V
 Landroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/view/autofill/IAutoFillManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/autofill/IAutoFillManager;
-Landroid/view/IApplicationToken$Stub;-><init>()V
 Landroid/view/IDockedStackListener$Stub;-><init>()V
 Landroid/view/IGraphicsStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/view/IGraphicsStats$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IGraphicsStats;
-Landroid/view/IOnKeyguardExitResult;->onKeyguardExitResult(Z)V
 Landroid/view/IRecentsAnimationController;->setAnimationTargetsBehindSystemBars(Z)V
 Landroid/view/IRotationWatcher$Stub;-><init>()V
-Landroid/view/IRotationWatcher;->onRotationChanged(I)V
 Landroid/view/IWindow$Stub;-><init>()V
 Landroid/view/IWindow$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IWindow;
-Landroid/view/IWindow;->closeSystemDialogs(Ljava/lang/String;)V
-Landroid/view/IWindow;->dispatchAppVisibility(Z)V
-Landroid/view/IWindow;->dispatchGetNewSurface()V
-Landroid/view/IWindow;->dispatchWallpaperCommand(Ljava/lang/String;IIILandroid/os/Bundle;Z)V
-Landroid/view/IWindow;->dispatchWallpaperOffsets(FFFFZ)V
-Landroid/view/IWindow;->windowFocusChanged(ZZ)V
 Landroid/view/IWindowManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/view/IWindowManager$Stub$Proxy;->getBaseDisplayDensity(I)I
 Landroid/view/IWindowManager$Stub$Proxy;->getDockedStackSide()I
@@ -1634,7 +1594,6 @@
 Landroid/view/IWindowManager;->getInitialDisplaySize(ILandroid/graphics/Point;)V
 Landroid/view/IWindowManager;->getPendingAppTransition()I
 Landroid/view/IWindowManager;->hasNavigationBar()Z
-Landroid/view/IWindowManager;->inputMethodClientHasFocus(Lcom/android/internal/view/IInputMethodClient;)Z
 Landroid/view/IWindowManager;->isKeyguardLocked()Z
 Landroid/view/IWindowManager;->isKeyguardSecure()Z
 Landroid/view/IWindowManager;->isSafeModeEnabled()Z
@@ -1649,7 +1608,6 @@
 Landroid/view/IWindowManager;->showStrictModeViolation(Z)V
 Landroid/view/IWindowManager;->thawRotation()V
 Landroid/view/IWindowSession$Stub$Proxy;->relayout(Landroid/view/IWindow;ILandroid/view/WindowManager$LayoutParams;IIIIJLandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/util/MergedConfiguration;Landroid/view/Surface;)I
-Landroid/view/IWindowSession$Stub;-><init>()V
 Landroid/view/IWindowSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IWindowSession;
 Landroid/view/IWindowSession;->finishDrawing(Landroid/view/IWindow;)V
 Landroid/view/IWindowSession;->getInTouchMode()Z
@@ -1720,32 +1678,15 @@
 Lcom/android/internal/app/IAppOpsService;->resetAllModes(ILjava/lang/String;)V
 Lcom/android/internal/app/IAppOpsService;->setMode(IILjava/lang/String;I)V
 Lcom/android/internal/app/IBatteryStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Lcom/android/internal/app/IBatteryStats$Stub;-><init>()V
 Lcom/android/internal/app/IBatteryStats$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IBatteryStats;
 Lcom/android/internal/app/IBatteryStats;->computeChargeTimeRemaining()J
 Lcom/android/internal/app/IBatteryStats;->getAwakeTimeBattery()J
 Lcom/android/internal/app/IBatteryStats;->getStatistics()[B
 Lcom/android/internal/app/IBatteryStats;->isCharging()Z
-Lcom/android/internal/app/IBatteryStats;->noteFullWifiLockAcquired(I)V
-Lcom/android/internal/app/IBatteryStats;->noteFullWifiLockReleased(I)V
-Lcom/android/internal/app/IBatteryStats;->notePhoneDataConnectionState(IZ)V
-Lcom/android/internal/app/IBatteryStats;->notePhoneOff()V
-Lcom/android/internal/app/IBatteryStats;->notePhoneOn()V
-Lcom/android/internal/app/IBatteryStats;->notePhoneSignalStrength(Landroid/telephony/SignalStrength;)V
-Lcom/android/internal/app/IBatteryStats;->notePhoneState(I)V
-Lcom/android/internal/app/IBatteryStats;->noteScreenBrightness(I)V
-Lcom/android/internal/app/IBatteryStats;->noteStartSensor(II)V
-Lcom/android/internal/app/IBatteryStats;->noteStopSensor(II)V
-Lcom/android/internal/app/IBatteryStats;->noteUserActivity(II)V
-Lcom/android/internal/app/IBatteryStats;->noteWifiMulticastDisabled(I)V
-Lcom/android/internal/app/IBatteryStats;->noteWifiMulticastEnabled(I)V
 Lcom/android/internal/app/IMediaContainerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IMediaContainerService;
 Lcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->showSessionFromSession(Landroid/os/IBinder;Landroid/os/Bundle;I)Z
 Lcom/android/internal/app/IVoiceInteractionManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IVoiceInteractionManagerService;
 Lcom/android/internal/app/IVoiceInteractionManagerService;->getKeyphraseSoundModel(ILjava/lang/String;)Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel;
-Lcom/android/internal/appwidget/IAppWidgetHost;->providerChanged(ILandroid/appwidget/AppWidgetProviderInfo;)V
-Lcom/android/internal/appwidget/IAppWidgetHost;->updateAppWidget(ILandroid/widget/RemoteViews;)V
-Lcom/android/internal/appwidget/IAppWidgetService$Stub;-><init>()V
 Lcom/android/internal/appwidget/IAppWidgetService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/appwidget/IAppWidgetService;
 Lcom/android/internal/appwidget/IAppWidgetService$Stub;->TRANSACTION_bindAppWidgetId:I
 Lcom/android/internal/appwidget/IAppWidgetService;->bindAppWidgetId(Ljava/lang/String;IILandroid/content/ComponentName;Landroid/os/Bundle;)Z
@@ -1753,15 +1694,6 @@
 Lcom/android/internal/appwidget/IAppWidgetService;->getAppWidgetIds(Landroid/content/ComponentName;)[I
 Lcom/android/internal/appwidget/IAppWidgetService;->getAppWidgetViews(Ljava/lang/String;I)Landroid/widget/RemoteViews;
 Lcom/android/internal/backup/IBackupTransport$Stub;-><init>()V
-Lcom/android/internal/backup/IBackupTransport$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/backup/IBackupTransport;
-Lcom/android/internal/backup/IBackupTransport;->clearBackupData(Landroid/content/pm/PackageInfo;)I
-Lcom/android/internal/backup/IBackupTransport;->finishBackup()I
-Lcom/android/internal/backup/IBackupTransport;->finishRestore()V
-Lcom/android/internal/backup/IBackupTransport;->getRestoreData(Landroid/os/ParcelFileDescriptor;)I
-Lcom/android/internal/backup/IBackupTransport;->initializeDevice()I
-Lcom/android/internal/backup/IBackupTransport;->requestBackupTime()J
-Lcom/android/internal/backup/IBackupTransport;->startRestore(J[Landroid/content/pm/PackageInfo;)I
-Lcom/android/internal/backup/IBackupTransport;->transportDirName()Ljava/lang/String;
 Lcom/android/internal/location/ILocationProvider$Stub;-><init>()V
 Lcom/android/internal/logging/MetricsLogger;-><init>()V
 Lcom/android/internal/net/LegacyVpnInfo;-><init>()V
@@ -2033,7 +1965,6 @@
 Lcom/android/internal/R$styleable;->AndroidManifest_sharedUserId:I
 Lcom/android/internal/R$styleable;->AndroidManifest_versionCode:I
 Lcom/android/internal/R$styleable;->AndroidManifest_versionName:I
-Lcom/android/internal/R$styleable;->AppWidgetProviderInfo:[I
 Lcom/android/internal/R$styleable;->AutoCompleteTextView:[I
 Lcom/android/internal/R$styleable;->CheckBoxPreference:[I
 Lcom/android/internal/R$styleable;->CheckBoxPreference_disableDependentsState:I
@@ -2223,7 +2154,6 @@
 Lcom/android/internal/R$styleable;->View_longClickable:I
 Lcom/android/internal/R$styleable;->WallpaperPreviewInfo:[I
 Lcom/android/internal/R$styleable;->Window:[I
-Lcom/android/internal/R$styleable;->WindowAnimation:[I
 Lcom/android/internal/R$styleable;->Window_windowActionBarFullscreenDecorLayout:I
 Lcom/android/internal/R$styleable;->Window_windowBackground:I
 Lcom/android/internal/R$styleable;->Window_windowFullscreen:I
@@ -2286,15 +2216,6 @@
 Lcom/android/internal/telephony/ICarrierConfigLoader;->getConfigForSubId(ILjava/lang/String;)Landroid/os/PersistableBundle;
 Lcom/android/internal/telephony/IMms$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IMms;
 Lcom/android/internal/telephony/IPhoneStateListener$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IPhoneStateListener;
-Lcom/android/internal/telephony/IPhoneStateListener;->onCallForwardingIndicatorChanged(Z)V
-Lcom/android/internal/telephony/IPhoneStateListener;->onCallStateChanged(ILjava/lang/String;)V
-Lcom/android/internal/telephony/IPhoneStateListener;->onCellLocationChanged(Landroid/os/Bundle;)V
-Lcom/android/internal/telephony/IPhoneStateListener;->onDataActivity(I)V
-Lcom/android/internal/telephony/IPhoneStateListener;->onDataConnectionStateChanged(II)V
-Lcom/android/internal/telephony/IPhoneStateListener;->onMessageWaitingIndicatorChanged(Z)V
-Lcom/android/internal/telephony/IPhoneStateListener;->onServiceStateChanged(Landroid/telephony/ServiceState;)V
-Lcom/android/internal/telephony/IPhoneStateListener;->onSignalStrengthChanged(I)V
-Lcom/android/internal/telephony/IPhoneStateListener;->onSignalStrengthsChanged(Landroid/telephony/SignalStrength;)V
 Lcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Lcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;->getDeviceId(Ljava/lang/String;)Ljava/lang/String;
 Lcom/android/internal/telephony/IPhoneSubInfo$Stub;-><init>()V
@@ -2353,7 +2274,6 @@
 Lcom/android/internal/telephony/ITelephony;->toggleRadioOnOff()V
 Lcom/android/internal/telephony/ITelephony;->updateServiceLocation()V
 Lcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Lcom/android/internal/telephony/ITelephonyRegistry$Stub;-><init>()V
 Lcom/android/internal/telephony/ITelephonyRegistry$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephonyRegistry;
 Lcom/android/internal/telephony/ITelephonyRegistry;->listen(Ljava/lang/String;Lcom/android/internal/telephony/IPhoneStateListener;IZ)V
 Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCallForwardingChanged(Z)V
@@ -2426,17 +2346,8 @@
 Lcom/android/internal/textservice/ITextServicesManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Lcom/android/internal/util/HexDump;->toHexString([BZ)Ljava/lang/String;
 Lcom/android/internal/view/BaseIWindow;-><init>()V
-Lcom/android/internal/view/IInputMethod$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethod;
-Lcom/android/internal/view/IInputMethod;->bindInput(Landroid/view/inputmethod/InputBinding;)V
-Lcom/android/internal/view/IInputMethod;->hideSoftInput(ILandroid/os/ResultReceiver;)V
-Lcom/android/internal/view/IInputMethod;->setSessionEnabled(Lcom/android/internal/view/IInputMethodSession;Z)V
-Lcom/android/internal/view/IInputMethod;->showSoftInput(ILandroid/os/ResultReceiver;)V
-Lcom/android/internal/view/IInputMethod;->unbindInput()V
-Lcom/android/internal/view/IInputMethodClient;->onBindMethod(Lcom/android/internal/view/InputBindResult;)V
-Lcom/android/internal/view/IInputMethodClient;->setUsingInputMethod(Z)V
 Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;->getEnabledInputMethodList()Ljava/util/List;
-Lcom/android/internal/view/IInputMethodManager$Stub;-><init>()V
 Lcom/android/internal/view/IInputMethodManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodManager;
 Lcom/android/internal/view/IInputMethodSession$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodSession;
 Lcom/android/internal/widget/ILockSettings$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/ILockSettings;
diff --git a/core/java/android/annotation/OWNERS b/core/java/android/annotation/OWNERS
index d6bb71b..85adfa7 100644
--- a/core/java/android/annotation/OWNERS
+++ b/core/java/android/annotation/OWNERS
@@ -1 +1,2 @@
 tnorbye@google.com
+per-file UnsupportedAppUsage.java = mathewi@google.com
diff --git a/core/java/android/annotation/UnsupportedAppUsage.java b/core/java/android/annotation/UnsupportedAppUsage.java
index fbba6da..28145a0 100644
--- a/core/java/android/annotation/UnsupportedAppUsage.java
+++ b/core/java/android/annotation/UnsupportedAppUsage.java
@@ -27,15 +27,15 @@
  * Indicates that a class member, that is not part of the SDK, is used by apps.
  * Since the member is not part of the SDK, such use is not supported.
  *
- * This annotation acts as a heads up that changing a given method or field
+ * <p>This annotation acts as a heads up that changing a given method or field
  * may affect apps, potentially breaking them when the next Android version is
  * released. In some cases, for members that are heavily used, this annotation
  * may imply restrictions on changes to the member.
  *
- * This annotation also results in access to the member being permitted by the
+ * <p>This annotation also results in access to the member being permitted by the
  * runtime, with a warning being generated in debug builds.
  *
- * For more details, see go/UnsupportedAppUsage.
+ * <p>For more details, see go/UnsupportedAppUsage.
  *
  * {@hide}
  */
@@ -53,15 +53,15 @@
     /**
      * Indicates that usage of this API is limited to apps based on their target SDK version.
      *
-     * Access to the API is allowed if the targetSdkVersion in the apps manifest is no greater than
-     * this value. Access checks are performed at runtime.
+     * <p>Access to the API is allowed if the targetSdkVersion in the apps manifest is no greater
+     * than this value. Access checks are performed at runtime.
      *
-     * This is used to give app developers a grace period to migrate off a non-SDK interface. When
-     * making Android version N, existing APIs can have a maxTargetSdk of N-1 added to them.
+     * <p>This is used to give app developers a grace period to migrate off a non-SDK interface.
+     * When making Android version N, existing APIs can have a maxTargetSdk of N-1 added to them.
      * Developers must then migrate off the API when their app is updated in future, but it will
      * continue working in the meantime.
      *
-     * Possible values are:
+     * <p>Possible values are:
      * <ul>
      *     <li>
      *         {@link android.os.Build.VERSION_CODES#O} or {@link android.os.Build.VERSION_CODES#P},
diff --git a/core/java/android/content/res/ObbInfo.java b/core/java/android/content/res/ObbInfo.java
index 452fdce..1d10b4f 100644
--- a/core/java/android/content/res/ObbInfo.java
+++ b/core/java/android/content/res/ObbInfo.java
@@ -80,6 +80,7 @@
     }
 
     public void writeToParcel(Parcel dest, int parcelableFlags) {
+        // Keep this in sync with writeToParcel() in ObbInfo.cpp
         dest.writeString(filename);
         dest.writeString(packageName);
         dest.writeInt(version);
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 30d2d5f..508626b 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -85,11 +85,47 @@
     /*package*/ XmlBlock.Parser mXml;
     @UnsupportedAppUsage
     /*package*/ Resources.Theme mTheme;
+    /**
+     * mData is used to hold the value/id and other metadata about each attribute.
+     *
+     * [type, data, asset cookie, resource id, changing configuration, density]
+     *
+     * type - type of this attribute, see TypedValue#TYPE_*
+     *
+     * data - can be used in various ways:
+     *     a) actual value of the attribute if type is between #TYPE_FIRST_INT and #TYPE_LAST_INT
+     *        1) color represented by an integer (#TYPE_INT_COLOR_*)
+     *        2) boolean represented by an integer (#TYPE_INT_BOOLEAN)
+     *        3) integer number (#TYPE_TYPE_INT_DEC or #TYPE_INT_HEX)
+     *        4) float number where integer gets interpreted as float (#TYPE_FLOAT, #TYPE_FRACTION
+     *            and #TYPE_DIMENSION)
+     *     b) index into string block inside AssetManager (#TYPE_STRING)
+     *     c) attribute resource id in the current theme/style (#TYPE_ATTRIBUTE)
+     *
+     * asset cookie - used in two ways:
+     *     a) for strings, drawables, and fonts it specifies the set of apk assets to look at
+     *     (multi-apk case)
+     *     b) cookie + asset as a unique identifier for drawable caches
+     *
+     * resource id - id that was finally used to resolve this attribute
+     *
+     * changing configuration - a mask of the configuration parameters for which the values in this
+     * attribute may change
+     *
+     * density - density of drawable pointed to by this attribute
+     */
     @UnsupportedAppUsage
     /*package*/ int[] mData;
+    /**
+     * Pointer to the start of the memory address of mData. It is passed via JNI and used to write
+     * to mData array directly from native code (AttributeResolution.cpp).
+     */
     /*package*/ long mDataAddress;
     @UnsupportedAppUsage
     /*package*/ int[] mIndices;
+    /**
+     * Similar to mDataAddress, but instead it is a pointer to mIndices address.
+     */
     /*package*/ long mIndicesAddress;
     @UnsupportedAppUsage
     /*package*/ int mLength;
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index d51e896..e8fb287 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -167,8 +167,7 @@
      * reasonable measures, such as over-the-air encryption, to prevent the contents
      * of the display from being intercepted or recorded on a persistent medium.
      * </p><p>
-     * Creating a secure virtual display requires the
-     * {@link android.Manifest.permission#CAPTURE_SECURE_VIDEO_OUTPUT} permission.
+     * Creating a secure virtual display requires the CAPTURE_SECURE_VIDEO_OUTPUT permission.
      * This permission is reserved for use by system components and is not available to
      * third-party applications.
      * </p>
@@ -228,9 +227,8 @@
      * </p>
      *
      * <p>
-     * Creating an auto-mirroing virtual display requires the
-     * {@link android.Manifest.permission#CAPTURE_VIDEO_OUTPUT}
-     * or {@link android.Manifest.permission#CAPTURE_SECURE_VIDEO_OUTPUT} permission.
+     * Creating an auto-mirroing virtual display requires the CAPTURE_VIDEO_OUTPUT
+     * or CAPTURE_SECURE_VIDEO_OUTPUT permission.
      * These permissions are reserved for use by system components and are not available to
      * third-party applications.
      *
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 5c2d41e..33b2676 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -17,6 +17,7 @@
 package android.os.storage;
 
 import android.content.pm.IPackageMoveObserver;
+import android.content.res.ObbInfo;
 import android.os.IVoldTaskListener;
 import android.os.ParcelFileDescriptor;
 import android.os.storage.DiskInfo;
@@ -57,7 +58,7 @@
      * it of the terminal state of the call.
      */
     void mountObb(in String rawPath, in String canonicalPath, in String key,
-            IObbActionListener token, int nonce) = 21;
+            IObbActionListener token, int nonce, in ObbInfo obbInfo) = 21;
     /**
      * Unmounts an Opaque Binary Blob (OBB). When the force flag is specified,
      * any program using it will be forcibly killed to unmount the image.
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 5a1ea68..e69acae 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -34,6 +34,8 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageMoveObserver;
 import android.content.pm.PackageManager;
+import android.content.res.ObbInfo;
+import android.content.res.ObbScanner;
 import android.os.Binder;
 import android.os.Environment;
 import android.os.FileUtils;
@@ -580,7 +582,8 @@
         try {
             final String canonicalPath = new File(rawPath).getCanonicalPath();
             final int nonce = mObbActionListener.addListener(listener);
-            mStorageManager.mountObb(rawPath, canonicalPath, key, mObbActionListener, nonce);
+            mStorageManager.mountObb(rawPath, canonicalPath, key, mObbActionListener, nonce,
+                    getObbInfo(canonicalPath));
             return true;
         } catch (IOException e) {
             throw new IllegalArgumentException("Failed to resolve path: " + rawPath, e);
@@ -589,6 +592,15 @@
         }
     }
 
+    private ObbInfo getObbInfo(String canonicalPath) {
+        try {
+            final ObbInfo obbInfo = ObbScanner.getObbInfo(canonicalPath);
+            return obbInfo;
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Couldn't get OBB info for " + canonicalPath, e);
+        }
+    }
+
     /**
      * Unmount an Opaque Binary Blob (OBB) file asynchronously. If the
      * <code>force</code> flag is true, it will kill any application needed to
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8f176e8..67bdbf6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3238,11 +3238,13 @@
     <permission android:name="android.permission.ACCESS_SURFACE_FLINGER"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi Allows an application to take screen shots and more generally
+    <!-- Allows an application to take screen shots and more generally
          get access to the frame buffer data.
-         <p>Not for use by third-party applications. -->
+         <p>Not for use by third-party applications.
+          @hide
+          @removed -->
     <permission android:name="android.permission.READ_FRAME_BUFFER"
-        android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to use InputFlinger's low level features.
          @hide -->
@@ -3338,15 +3340,19 @@
     <permission android:name="android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows an application to capture video output.
-         <p>Not for use by third-party applications.</p> -->
+    <!-- Allows an application to capture video output.
+         <p>Not for use by third-party applications.</p>
+          @hide
+          @removed -->
     <permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"
-        android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature" />
 
-    <!-- @SystemApi Allows an application to capture secure video output.
-         <p>Not for use by third-party applications.</p> -->
+    <!-- Allows an application to capture secure video output.
+         <p>Not for use by third-party applications.</p>
+          @hide
+          @removed -->
     <permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"
-        android:protectionLevel="signature|privileged" />
+        android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to know what content is playing and control its playback.
          <p>Not for use by third-party applications due to privacy of media consumption</p>  -->
diff --git a/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java b/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java
index 56629d4..16dcff5 100644
--- a/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java
+++ b/core/tests/coretests/src/android/os/storage/StorageManagerBaseTest.java
@@ -65,95 +65,6 @@
         + "to ourselves and our posterity, do ordain and establish this Constitution\n"
         + "for the United States of America.\n\n";
 
-    class MountingObbThread extends Thread {
-        boolean mStop = false;
-        volatile boolean mFileOpenOnObb = false;
-        private String mObbFilePath = null;
-        private String mPathToContentsFile = null;
-        private String mOfficialObbFilePath = null;
-
-        /**
-         * Constructor
-         *
-         * @param obbFilePath path to the OBB image file
-         * @param pathToContentsFile path to a file on the mounted OBB volume to open after the OBB
-         *      has been mounted
-         */
-        public MountingObbThread (String obbFilePath, String pathToContentsFile) {
-            assertTrue("obbFilePath cannot be null!", obbFilePath != null);
-            mObbFilePath = obbFilePath;
-            assertTrue("path to contents file cannot be null!", pathToContentsFile != null);
-            mPathToContentsFile = pathToContentsFile;
-        }
-
-        /**
-         * Runs the thread
-         *
-         * Mounts OBB_FILE_1, and tries to open a file on the mounted OBB (specified in the
-         * constructor). Once it's open, it waits until someone calls its doStop(), after which it
-         * closes the opened file.
-         */
-        public void run() {
-            // the official OBB file path and the mount-request file path should be the same, but
-            // let's distinguish the two as they may make for some interesting tests later
-            mOfficialObbFilePath = mountObb(mObbFilePath);
-            assertEquals("Expected and actual OBB file paths differ!", mObbFilePath,
-                    mOfficialObbFilePath);
-
-            // open a file on OBB 1...
-            DataInputStream inputFile = openFileOnMountedObb(mOfficialObbFilePath,
-                    mPathToContentsFile);
-            assertTrue("Failed to open file!", inputFile != null);
-
-            synchronized (this) {
-                mFileOpenOnObb = true;
-                notifyAll();
-            }
-
-            while (!mStop) {
-                try {
-                    Thread.sleep(WAIT_TIME_INCR);
-                } catch (InterruptedException e) {
-                    // nothing special to be done for interruptions
-                }
-            }
-            try {
-                inputFile.close();
-            } catch (IOException e) {
-                fail("Failed to close file on OBB due to error: " + e.toString());
-            }
-        }
-
-        /**
-         * Tells whether a file has yet been successfully opened on the OBB or not
-         *
-         * @return true if the specified file on the OBB was opened; false otherwise
-         */
-        public boolean isFileOpenOnObb() {
-            return mFileOpenOnObb;
-        }
-
-        /**
-         * Returns the official path of the OBB file that was mounted
-         *
-         * This is not the mount path, but the normalized path to the actual OBB file
-         *
-         * @return a {@link String} representation of the path to the OBB file that was mounted
-         */
-        public String officialObbFilePath() {
-            return mOfficialObbFilePath;
-        }
-
-        /**
-         * Requests the thread to stop running
-         *
-         * Closes the opened file and returns
-         */
-        public void doStop() {
-            mStop = true;
-        }
-    }
-
     public class ObbListener extends OnObbStateChangeListener {
         private String LOG_TAG = "StorageManagerBaseTest.ObbListener";
 
@@ -362,7 +273,8 @@
         assertTrue("mountObb call failed", mSm.mountObb(obbFilePath, key, obbListener));
         assertTrue("Failed to get OBB mount status change for file: " + obbFilePath,
                 doWaitForObbStateChange(obbListener));
-        assertEquals("OBB mount state not what was expected!", expectedState, obbListener.state());
+        assertEquals("OBB mount state not what was expected!", expectedState,
+                obbListener.state());
 
         if (OnObbStateChangeListener.MOUNTED == expectedState) {
             assertEquals(obbFilePath, obbListener.officialPath());
@@ -373,7 +285,8 @@
                     mSm.isObbMounted(obbListener.officialPath()));
         }
 
-        assertEquals("Mount state is not what was expected!", expectedState, obbListener.state());
+        assertEquals("Mount state is not what was expected!", expectedState,
+                obbListener.state());
         return obbListener.officialPath();
     }
 
diff --git a/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java b/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
index 5f8bd03..3ec297c 100644
--- a/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
+++ b/core/tests/coretests/src/android/os/storage/StorageManagerIntegrationTest.java
@@ -20,7 +20,6 @@
 import android.os.ProxyFileDescriptorCallback;
 import android.system.ErrnoException;
 import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
 
 import com.android.frameworks.coretests.R;
 
@@ -135,57 +134,18 @@
     }
 
     /**
-     * Tests that we can not force unmount when a file is currently open on the OBB.
-     */
-    @LargeTest
-    public void testUnmount_DontForce() throws Exception {
-        final File file = createObbFile(OBB_FILE_1, R.raw.obb_file1);
-        String obbFilePath = file.getAbsolutePath();
-
-        MountingObbThread mountingThread = new MountingObbThread(obbFilePath,
-                OBB_FILE_1_CONTENTS_1);
-
-        try {
-            mountingThread.start();
-
-            long waitTime = 0;
-            while (!mountingThread.isFileOpenOnObb()) {
-                synchronized (mountingThread) {
-                    Log.i(LOG_TAG, "Waiting for file to be opened on OBB...");
-                    mountingThread.wait(WAIT_TIME_INCR);
-                    waitTime += WAIT_TIME_INCR;
-                    if (waitTime > MAX_WAIT_TIME) {
-                        fail("Timed out waiting for file file to be opened on OBB!");
-                    }
-                }
-            }
-
-            unmountObb(obbFilePath, DONT_FORCE);
-
-            // verify still mounted
-            assertTrue("mounted path should not be null!", obbFilePath != null);
-            assertTrue("mounted path should still be mounted!", mSm.isObbMounted(obbFilePath));
-
-            // close the opened file
-            mountingThread.doStop();
-
-            // try unmounting again (should succeed this time)
-            unmountObb(obbFilePath, DONT_FORCE);
-            assertFalse("mounted path should no longer be mounted!",
-                    mSm.isObbMounted(obbFilePath));
-        } catch (InterruptedException e) {
-            fail("Timed out waiting for file on OBB to be opened...");
-        }
-    }
-
-    /**
      * Tests mounting a single OBB that isn't signed.
      */
     @LargeTest
     public void testMountUnsignedObb() throws Exception {
         final File file = createObbFile(OBB_FILE_2_UNSIGNED, R.raw.obb_file2_nosign);
         String filePath = file.getAbsolutePath();
-        mountObb(filePath, OBB_FILE_2_UNSIGNED, OnObbStateChangeListener.ERROR_INTERNAL);
+        try {
+            mountObb(filePath, OBB_FILE_2_UNSIGNED, OnObbStateChangeListener.ERROR_INTERNAL);
+            fail("mountObb should've failed with an exception");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
     }
 
     /**
diff --git a/libs/storage/Android.bp b/libs/storage/Android.bp
index 911bd1d..c19933e 100644
--- a/libs/storage/Android.bp
+++ b/libs/storage/Android.bp
@@ -6,6 +6,7 @@
         "IMountShutdownObserver.cpp",
         "IObbActionListener.cpp",
         "IMountService.cpp",
+        "ObbInfo.cpp",
     ],
 
     export_include_dirs: ["include"],
diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp
index fa3d8bd..fd6e6e9 100644
--- a/libs/storage/IMountService.cpp
+++ b/libs/storage/IMountService.cpp
@@ -443,7 +443,7 @@
     }
 
     void mountObb(const String16& rawPath, const String16& canonicalPath, const String16& key,
-            const sp<IObbActionListener>& token, int32_t nonce)
+            const sp<IObbActionListener>& token, int32_t nonce, const sp<ObbInfo>& obbInfo)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
@@ -452,6 +452,7 @@
         data.writeString16(key);
         data.writeStrongBinder(IInterface::asBinder(token));
         data.writeInt32(nonce);
+        obbInfo->writeToParcel(&data);
         if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) {
             ALOGD("mountObb could not contact remote\n");
             return;
diff --git a/libs/storage/ObbInfo.cpp b/libs/storage/ObbInfo.cpp
new file mode 100644
index 0000000..1bb6b3a
--- /dev/null
+++ b/libs/storage/ObbInfo.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <storage/ObbInfo.h>
+
+#include <binder/Parcel.h>
+#include <utils/String16.h>
+#include <sys/types.h>
+
+namespace android {
+
+ObbInfo::ObbInfo(const String16 fileName, const String16 packageName, int32_t version,
+        int32_t flags, size_t saltSize, const uint8_t* salt) : mFileName(fileName),
+        mPackageName(packageName), mVersion(version), mFlags(flags), mSaltSize(saltSize),
+        mSalt(salt) {}
+
+ObbInfo::~ObbInfo() {}
+
+status_t ObbInfo::readFromParcel(const Parcel*) {
+    return INVALID_OPERATION;
+}
+
+status_t ObbInfo::writeToParcel(Parcel* p) const {
+    // Parcel write code must be kept in sync with
+    // frameworks/base/core/java/android/content/res/ObbInfo.java
+    p->writeString16(mFileName);
+    p->writeString16(mPackageName);
+    p->writeInt32(mVersion);
+    p->writeInt32(mFlags);
+    p->writeByteArray(mSaltSize, mSalt);
+    return OK;
+}
+
+}; // namespace android
\ No newline at end of file
diff --git a/libs/storage/include/storage/IMountService.h b/libs/storage/include/storage/IMountService.h
index c3d34d8..2463e02 100644
--- a/libs/storage/include/storage/IMountService.h
+++ b/libs/storage/include/storage/IMountService.h
@@ -20,6 +20,7 @@
 #include <storage/IMountServiceListener.h>
 #include <storage/IMountShutdownObserver.h>
 #include <storage/IObbActionListener.h>
+#include <storage/ObbInfo.h>
 
 #include <utils/String8.h>
 
@@ -64,7 +65,7 @@
     virtual void finishMediaUpdate() = 0;
     virtual void mountObb(const String16& rawPath, const String16& canonicalPath,
             const String16& key, const sp<IObbActionListener>& token,
-            const int32_t nonce) = 0;
+            const int32_t nonce, const sp<ObbInfo>& obbInfo) = 0;
     virtual void unmountObb(const String16& filename, const bool force,
             const sp<IObbActionListener>& token, const int32_t nonce) = 0;
     virtual bool isObbMounted(const String16& filename) = 0;
diff --git a/libs/storage/include/storage/ObbInfo.h b/libs/storage/include/storage/ObbInfo.h
new file mode 100644
index 0000000..e4cc353
--- /dev/null
+++ b/libs/storage/include/storage/ObbInfo.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_OBBINFO_H
+#define ANDROID_OBBINFO_H
+
+#include <binder/Parcelable.h>
+#include <utils/RefBase.h>
+#include <utils/String16.h>
+#include <sys/types.h>
+
+namespace android {
+
+class ObbInfo : public Parcelable, public virtual RefBase {
+
+public:
+    ObbInfo(const String16 fileName, const String16 packageName, int32_t version,
+            int32_t flags, size_t saltSize, const uint8_t* salt);
+    ~ObbInfo();
+
+    status_t writeToParcel(Parcel* parcel) const override;
+    status_t readFromParcel(const Parcel* parcel) override;
+
+private:
+    const String16 mFileName;
+    const String16 mPackageName;
+    int32_t mVersion;
+    int32_t mFlags;
+    size_t mSaltSize;
+    const uint8_t* mSalt;
+};
+
+}; // namespace android
+
+#endif // ANDROID_OBBINFO_H
\ No newline at end of file
diff --git a/media/java/android/mtp/OWNERS b/media/java/android/mtp/OWNERS
index 7a14b37..1928ba8 100644
--- a/media/java/android/mtp/OWNERS
+++ b/media/java/android/mtp/OWNERS
@@ -1,5 +1,7 @@
+set noparent
+
 marcone@google.com
-jsharkey@google.com
+jsharkey@android.com
 jameswei@google.com
 rmojumder@google.com
 
diff --git a/native/android/storage_manager.cpp b/native/android/storage_manager.cpp
index bf15b8d..2272525 100644
--- a/native/android/storage_manager.cpp
+++ b/native/android/storage_manager.cpp
@@ -18,7 +18,9 @@
 
 #include <android/storage_manager.h>
 #include <storage/IMountService.h>
+#include <storage/ObbInfo.h>
 
+#include <androidfw/ObbFile.h>
 #include <binder/Binder.h>
 #include <binder/IServiceManager.h>
 #include <cutils/atomic.h>
@@ -29,7 +31,6 @@
 #include <utils/Vector.h>
 #include <utils/threads.h>
 
-
 using namespace android;
 
 struct ObbActionListener : public BnObbActionListener {
@@ -79,6 +80,20 @@
         return cb;
     }
 
+    ObbInfo* getObbInfo(char* canonicalPath) {
+        sp<ObbFile> obbFile = new ObbFile();
+        if (!obbFile->readFrom(canonicalPath)) {
+            return nullptr;
+        }
+
+        String16 fileName(obbFile->getFileName());
+        String16 packageName(obbFile->getPackageName());
+        size_t length;
+        const unsigned char* salt = obbFile->getSalt(&length);
+        return new ObbInfo(fileName, packageName,
+                obbFile->getVersion(), obbFile->getFlags(), length, salt);
+    }
+
 public:
     AStorageManager()
     {
@@ -134,11 +149,18 @@
             return;
         }
 
+        sp<ObbInfo> obbInfo = getObbInfo(canonicalPath);
+        if (obbInfo == nullptr) {
+            ALOGE("Couldn't get obb info for %s: %s", canonicalPath, strerror(errno));
+            return;
+        }
+
         ObbCallback* cb = registerObbCallback(func, data);
         String16 rawPath16(rawPath);
         String16 canonicalPath16(canonicalPath);
         String16 key16(key);
-        mMountService->mountObb(rawPath16, canonicalPath16, key16, mObbActionListener, cb->nonce);
+        mMountService->mountObb(rawPath16, canonicalPath16, key16, mObbActionListener,
+                cb->nonce, obbInfo);
     }
 
     void unmountObb(const char* filename, const bool force, AStorageManager_obbCallbackFunc func, void* data) {
diff --git a/packages/SettingsLib/res/layout/restricted_switch_preference.xml b/packages/SettingsLib/res/layout/restricted_switch_preference.xml
index 64b47b6..d9f91de 100644
--- a/packages/SettingsLib/res/layout/restricted_switch_preference.xml
+++ b/packages/SettingsLib/res/layout/restricted_switch_preference.xml
@@ -24,7 +24,7 @@
     android:clipToPadding="false">
 
     <LinearLayout
-        android:id="@+id/icon_container"
+        android:id="@+id/icon_frame"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:minWidth="56dp"
@@ -83,4 +83,4 @@
         android:paddingStart="16dp"
         android:orientation="vertical" />
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index c789c5d..6abe76a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -23,6 +23,7 @@
 import android.os.UserManager;
 import android.print.PrintManager;
 import android.provider.Settings;
+import android.telephony.ServiceState;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.UserIcons;
@@ -391,4 +392,52 @@
                 || audioMode == AudioManager.MODE_IN_CALL
                 || audioMode == AudioManager.MODE_IN_COMMUNICATION;
     }
+
+    /**
+     * Return the service state is in-service or not.
+     * To make behavior consistent with SystemUI and Settings/AboutPhone/SIM status UI
+     *
+     * @param serviceState Service state. {@link ServiceState}
+     */
+    public static boolean isInService(ServiceState serviceState) {
+        if (serviceState == null) {
+            return false;
+        }
+        int state = getCombinedServiceState(serviceState);
+        if (state == ServiceState.STATE_POWER_OFF
+                || state == ServiceState.STATE_OUT_OF_SERVICE
+                || state == ServiceState.STATE_EMERGENCY_ONLY) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Return the combined service state.
+     * To make behavior consistent with SystemUI and Settings/AboutPhone/SIM status UI
+     *
+     * @param serviceState Service state. {@link ServiceState}
+     */
+    public static int getCombinedServiceState(ServiceState serviceState) {
+        if (serviceState == null) {
+            return ServiceState.STATE_OUT_OF_SERVICE;
+        }
+
+        // Consider the device to be in service if either voice or data
+        // service is available. Some SIM cards are marketed as data-only
+        // and do not support voice service, and on these SIM cards, we
+        // want to show signal bars for data service as well as the "no
+        // service" or "emergency calls only" text that indicates that voice
+        // is not available.
+        int state = serviceState.getState();
+        int dataState = serviceState.getDataRegState();
+        if (state == ServiceState.STATE_OUT_OF_SERVICE
+                || state == ServiceState.STATE_EMERGENCY_ONLY) {
+            if (dataState == ServiceState.STATE_IN_SERVICE) {
+                return ServiceState.STATE_IN_SERVICE;
+            }
+        }
+        return state;
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 25e6831..10fd683 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -282,6 +282,9 @@
                 cachedDevice = mDeviceManager.addDevice(device);
                 Log.d(TAG, "DeviceFoundHandler created new CachedBluetoothDevice: "
                         + cachedDevice);
+            } else if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
+                // Dispatch device add callback to show bonded BT device in discovery mode
+                dispatchDeviceAdded(cachedDevice);
             }
             cachedDevice.setRssi(rssi);
             cachedDevice.setJustDiscovered(true);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
index 09a2bd2..babe82e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
@@ -39,6 +39,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
+import android.telephony.ServiceState;
 import android.text.TextUtils;
 
 import org.junit.Before;
@@ -74,6 +75,8 @@
     private Context mContext;
     @Mock
     private LocationManager mLocationManager;
+    @Mock
+    private ServiceState mServiceState;
 
     @Before
     public void setUp() {
@@ -226,4 +229,71 @@
 
         assertThat(Utils.isAudioModeOngoingCall(mContext)).isFalse();
     }
+
+    @Test
+    public void isInService_servicestateNull_returnFalse() {
+        assertThat(Utils.isInService(null)).isFalse();
+    }
+
+    @Test
+    public void isInService_voiceInService_returnTrue() {
+        when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);
+        assertThat(Utils.isInService(mServiceState)).isTrue();
+    }
+
+    @Test
+    public void isInService_voiceOutOfServiceDataInService_returnTrue() {
+        when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
+        when(mServiceState.getDataRegState()).thenReturn(ServiceState.STATE_IN_SERVICE);
+        assertThat(Utils.isInService(mServiceState)).isTrue();
+    }
+
+    @Test
+    public void isInService_voiceOutOfServiceDataOutOfService_returnFalse() {
+        when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
+        when(mServiceState.getDataRegState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
+        assertThat(Utils.isInService(mServiceState)).isFalse();
+    }
+
+    @Test
+    public void isInService_ServiceStatePowerOff_returnFalse() {
+        when(mServiceState.getState()).thenReturn(ServiceState.STATE_POWER_OFF);
+        assertThat(Utils.isInService(mServiceState)).isFalse();
+    }
+
+    @Test
+    public void getCombinedServiceState_servicestateNull_returnOutOfService() {
+        assertThat(Utils.getCombinedServiceState(null)).isEqualTo(
+                ServiceState.STATE_OUT_OF_SERVICE);
+    }
+
+    @Test
+    public void getCombinedServiceState_ServiceStatePowerOff_returnPowerOff() {
+        when(mServiceState.getState()).thenReturn(ServiceState.STATE_POWER_OFF);
+        assertThat(Utils.getCombinedServiceState(mServiceState)).isEqualTo(
+                ServiceState.STATE_POWER_OFF);
+    }
+
+    @Test
+    public void getCombinedServiceState_voiceInService_returnInService() {
+        when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);
+        assertThat(Utils.getCombinedServiceState(mServiceState)).isEqualTo(
+                ServiceState.STATE_IN_SERVICE);
+    }
+
+    @Test
+    public void getCombinedServiceState_voiceOutOfServiceDataInService_returnInService() {
+        when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
+        when(mServiceState.getDataRegState()).thenReturn(ServiceState.STATE_IN_SERVICE);
+        assertThat(Utils.getCombinedServiceState(mServiceState)).isEqualTo(
+                ServiceState.STATE_IN_SERVICE);
+    }
+
+    @Test
+    public void getCombinedServiceState_voiceOutOfServiceDataOutOfService_returnOutOfService() {
+        when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
+        when(mServiceState.getDataRegState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE);
+        assertThat(Utils.getCombinedServiceState(mServiceState)).isEqualTo(
+                ServiceState.STATE_OUT_OF_SERVICE);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index a195fc9..06d4434 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -100,7 +100,7 @@
  * is provisioned.
  */
 class GlobalActionsDialog implements DialogInterface.OnDismissListener,
-        DialogInterface.OnClickListener {
+        DialogInterface.OnClickListener, DialogInterface.OnShowListener {
 
     static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
     static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
@@ -397,6 +397,7 @@
         dialog.setKeyguardShowing(mKeyguardShowing);
 
         dialog.setOnDismissListener(this);
+        dialog.setOnShowListener(this);
 
         return dialog;
     }
@@ -458,6 +459,7 @@
 
         @Override
         public void onPress() {
+            MetricsLogger.action(mContext, MetricsEvent.ACTION_EMERGENCY_DIALER_FROM_POWER_MENU);
             Intent intent = new Intent(ACTION_EMERGENCY_DIALER_DIAL);
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
             mContext.startActivityAsUser(intent, UserHandle.CURRENT);
@@ -862,6 +864,11 @@
         item.onPress();
     }
 
+    /** {@inheritDoc} */
+    public void onShow(DialogInterface dialog) {
+        MetricsLogger.visible(mContext, MetricsEvent.POWER_MENU);
+    }
+
     /**
      * The adapter used for the list within the global actions dialog, taking
      * into account whether the keyguard is showing via
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index a046675..8ca1415 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -36,6 +36,7 @@
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.cdma.EriInfo;
 import com.android.settingslib.graph.SignalDrawable;
+import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
@@ -319,28 +320,6 @@
         return new MobileState();
     }
 
-    private boolean hasService() {
-        if (mServiceState != null) {
-            // Consider the device to be in service if either voice or data
-            // service is available. Some SIM cards are marketed as data-only
-            // and do not support voice service, and on these SIM cards, we
-            // want to show signal bars for data service as well as the "no
-            // service" or "emergency calls only" text that indicates that voice
-            // is not available.
-            switch (mServiceState.getVoiceRegState()) {
-                case ServiceState.STATE_POWER_OFF:
-                    return false;
-                case ServiceState.STATE_OUT_OF_SERVICE:
-                case ServiceState.STATE_EMERGENCY_ONLY:
-                    return mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
-                default:
-                    return true;
-            }
-        } else {
-            return false;
-        }
-    }
-
     private boolean isCdma() {
         return (mSignalStrength != null) && !mSignalStrength.isGsm();
     }
@@ -446,10 +425,11 @@
      */
     private final void updateTelephony() {
         if (DEBUG) {
-            Log.d(mTag, "updateTelephonySignalStrength: hasService=" + hasService()
-                    + " ss=" + mSignalStrength);
+            Log.d(mTag, "updateTelephonySignalStrength: hasService=" +
+                    Utils.isInService(mServiceState) + " ss=" + mSignalStrength);
         }
-        mCurrentState.connected = hasService() && mSignalStrength != null;
+        mCurrentState.connected = Utils.isInService(mServiceState)
+                && mSignalStrength != null;
         if (mCurrentState.connected) {
             if (!mSignalStrength.isGsm() && mConfig.alwaysShowCdmaRssi) {
                 mCurrentState.level = mSignalStrength.getCdmaLevel();
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 2e53a5f..b668623 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -6498,6 +6498,16 @@
     // OS: Q
     FIELD_EMERGENCY_DIALER_SHORTCUT_TAPS_INTERVAL = 1567;
 
+    // OPEN: Power menu is opened
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: Q
+    POWER_MENU = 1568;
+
+    // ACTION: User tapped emergency dialer icon in the power menu.
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: Q
+    ACTION_EMERGENCY_DIALER_FROM_POWER_MENU = 1569;
+
     // ---- End Q Constants, all Q constants go above this line ----
 
     // Add new aosp constants above this line.
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 1746b85..d505a77 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -44,11 +44,9 @@
 import android.app.admin.SecurityLog;
 import android.app.usage.StorageStatsManager;
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.ServiceConnection;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageMoveObserver;
 import android.content.pm.PackageManager;
@@ -115,7 +113,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.IMediaContainerService;
 import com.android.internal.os.AppFuseMount;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.FuseUnavailableMountException;
@@ -544,37 +541,7 @@
 
     // OBB action handler messages
     private static final int OBB_RUN_ACTION = 1;
-    private static final int OBB_MCS_BOUND = 2;
-    private static final int OBB_MCS_UNBIND = 3;
-    private static final int OBB_MCS_RECONNECT = 4;
-    private static final int OBB_FLUSH_MOUNT_STATE = 5;
-
-    /*
-     * Default Container Service information
-     */
-    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
-            "com.android.defcontainer", "com.android.defcontainer.DefaultContainerService");
-
-    final private DefaultContainerConnection mDefContainerConn = new DefaultContainerConnection();
-
-    class DefaultContainerConnection implements ServiceConnection {
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            if (DEBUG_OBB)
-                Slog.i(TAG, "onServiceConnected");
-            IMediaContainerService imcs = IMediaContainerService.Stub.asInterface(service);
-            mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_MCS_BOUND, imcs));
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            if (DEBUG_OBB)
-                Slog.i(TAG, "onServiceDisconnected");
-        }
-    }
-
-    // Used in the ObbActionHandler
-    private IMediaContainerService mContainerService = null;
+    private static final int OBB_FLUSH_MOUNT_STATE = 2;
 
     // Last fstrim operation tracking
     private static final String LAST_FSTRIM_FILE = "last-fstrim";
@@ -2305,16 +2272,17 @@
     }
 
     @Override
-    public void mountObb(
-            String rawPath, String canonicalPath, String key, IObbActionListener token, int nonce) {
+    public void mountObb(String rawPath, String canonicalPath, String key,
+            IObbActionListener token, int nonce, ObbInfo obbInfo) {
         Preconditions.checkNotNull(rawPath, "rawPath cannot be null");
         Preconditions.checkNotNull(canonicalPath, "canonicalPath cannot be null");
         Preconditions.checkNotNull(token, "token cannot be null");
+        Preconditions.checkNotNull(obbInfo, "obbIfno cannot be null");
 
         final int callingUid = Binder.getCallingUid();
         final ObbState obbState = new ObbState(rawPath, canonicalPath,
                 callingUid, token, nonce, null);
-        final ObbAction action = new MountObbAction(obbState, key, callingUid);
+        final ObbAction action = new MountObbAction(obbState, key, callingUid, obbInfo);
         mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_RUN_ACTION, action));
 
         if (DEBUG_OBB)
@@ -3217,8 +3185,6 @@
     }
 
     private class ObbActionHandler extends Handler {
-        private boolean mBound = false;
-        private final List<ObbAction> mActions = new LinkedList<ObbAction>();
 
         ObbActionHandler(Looper l) {
             super(l);
@@ -3233,83 +3199,7 @@
                     if (DEBUG_OBB)
                         Slog.i(TAG, "OBB_RUN_ACTION: " + action.toString());
 
-                    // If a bind was already initiated we don't really
-                    // need to do anything. The pending install
-                    // will be processed later on.
-                    if (!mBound) {
-                        // If this is the only one pending we might
-                        // have to bind to the service again.
-                        if (!connectToService()) {
-                            action.notifyObbStateChange(new ObbException(ERROR_INTERNAL,
-                                    "Failed to bind to media container service"));
-                            return;
-                        }
-                    }
-
-                    mActions.add(action);
-                    break;
-                }
-                case OBB_MCS_BOUND: {
-                    if (DEBUG_OBB)
-                        Slog.i(TAG, "OBB_MCS_BOUND");
-                    if (msg.obj != null) {
-                        mContainerService = (IMediaContainerService) msg.obj;
-                    }
-                    if (mContainerService == null) {
-                        // Something seriously wrong. Bail out
-                        for (ObbAction action : mActions) {
-                            // Indicate service bind error
-                            action.notifyObbStateChange(new ObbException(ERROR_INTERNAL,
-                                    "Failed to bind to media container service"));
-                        }
-                        mActions.clear();
-                    } else if (mActions.size() > 0) {
-                        final ObbAction action = mActions.get(0);
-                        if (action != null) {
-                            action.execute(this);
-                        }
-                    } else {
-                        // Should never happen ideally.
-                        Slog.w(TAG, "Empty queue");
-                    }
-                    break;
-                }
-                case OBB_MCS_RECONNECT: {
-                    if (DEBUG_OBB)
-                        Slog.i(TAG, "OBB_MCS_RECONNECT");
-                    if (mActions.size() > 0) {
-                        if (mBound) {
-                            disconnectService();
-                        }
-                        if (!connectToService()) {
-                            for (ObbAction action : mActions) {
-                                // Indicate service bind error
-                                action.notifyObbStateChange(new ObbException(ERROR_INTERNAL,
-                                        "Failed to bind to media container service"));
-                            }
-                            mActions.clear();
-                        }
-                    }
-                    break;
-                }
-                case OBB_MCS_UNBIND: {
-                    if (DEBUG_OBB)
-                        Slog.i(TAG, "OBB_MCS_UNBIND");
-
-                    // Delete pending install
-                    if (mActions.size() > 0) {
-                        mActions.remove(0);
-                    }
-                    if (mActions.size() == 0) {
-                        if (mBound) {
-                            disconnectService();
-                        }
-                    } else {
-                        // There are more pending requests in queue.
-                        // Just post MCS_BOUND message to trigger processing
-                        // of next pending install.
-                        mObbActionHandler.sendEmptyMessage(OBB_MCS_BOUND);
-                    }
+                    action.execute(this);
                     break;
                 }
                 case OBB_FLUSH_MOUNT_STATE: {
@@ -3354,25 +3244,6 @@
                 }
             }
         }
-
-        private boolean connectToService() {
-            if (DEBUG_OBB)
-                Slog.i(TAG, "Trying to bind to DefaultContainerService");
-
-            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
-            if (mContext.bindServiceAsUser(service, mDefContainerConn, Context.BIND_AUTO_CREATE,
-                    UserHandle.SYSTEM)) {
-                mBound = true;
-                return true;
-            }
-            return false;
-        }
-
-        private void disconnectService() {
-            mContainerService = null;
-            mBound = false;
-            mContext.unbindService(mDefContainerConn);
-        }
     }
 
     private static class ObbException extends Exception {
@@ -3390,8 +3261,6 @@
     }
 
     abstract class ObbAction {
-        private static final int MAX_RETRIES = 3;
-        private int mRetries;
 
         ObbState mObbState;
 
@@ -3403,40 +3272,14 @@
             try {
                 if (DEBUG_OBB)
                     Slog.i(TAG, "Starting to execute action: " + toString());
-                mRetries++;
-                if (mRetries > MAX_RETRIES) {
-                    mObbActionHandler.sendEmptyMessage(OBB_MCS_UNBIND);
-                    notifyObbStateChange(new ObbException(ERROR_INTERNAL,
-                            "Failed to bind to media container service"));
-                } else {
-                    handleExecute();
-                    if (DEBUG_OBB)
-                        Slog.i(TAG, "Posting install MCS_UNBIND");
-                    mObbActionHandler.sendEmptyMessage(OBB_MCS_UNBIND);
-                }
+                handleExecute();
             } catch (ObbException e) {
                 notifyObbStateChange(e);
-                mObbActionHandler.sendEmptyMessage(OBB_MCS_UNBIND);
             }
         }
 
         abstract void handleExecute() throws ObbException;
 
-        protected ObbInfo getObbInfo() throws ObbException {
-            final ObbInfo obbInfo;
-            try {
-                obbInfo = mContainerService.getObbInfo(mObbState.canonicalPath);
-            } catch (Exception e) {
-                throw new ObbException(ERROR_PERMISSION_DENIED, e);
-            }
-            if (obbInfo != null) {
-                return obbInfo;
-            } else {
-                throw new ObbException(ERROR_INTERNAL,
-                        "Missing OBB info for: " + mObbState.canonicalPath);
-            }
-        }
-
         protected void notifyObbStateChange(ObbException e) {
             Slog.w(TAG, e);
             notifyObbStateChange(e.status);
@@ -3458,22 +3301,22 @@
     class MountObbAction extends ObbAction {
         private final String mKey;
         private final int mCallingUid;
+        private ObbInfo mObbInfo;
 
-        MountObbAction(ObbState obbState, String key, int callingUid) {
+        MountObbAction(ObbState obbState, String key, int callingUid, ObbInfo obbInfo) {
             super(obbState);
             mKey = key;
             mCallingUid = callingUid;
+            mObbInfo = obbInfo;
         }
 
         @Override
         public void handleExecute() throws ObbException {
             warnOnNotMounted();
 
-            final ObbInfo obbInfo = getObbInfo();
-
-            if (!isUidOwnerOfPackageOrSystem(obbInfo.packageName, mCallingUid)) {
+            if (!isUidOwnerOfPackageOrSystem(mObbInfo.packageName, mCallingUid)) {
                 throw new ObbException(ERROR_PERMISSION_DENIED, "Denied attempt to mount OBB "
-                        + obbInfo.filename + " which is owned by " + obbInfo.packageName);
+                        + mObbInfo.filename + " which is owned by " + mObbInfo.packageName);
             }
 
             final boolean isMounted;
@@ -3482,7 +3325,7 @@
             }
             if (isMounted) {
                 throw new ObbException(ERROR_ALREADY_MOUNTED,
-                        "Attempt to mount OBB which is already mounted: " + obbInfo.filename);
+                        "Attempt to mount OBB which is already mounted: " + mObbInfo.filename);
             }
 
             final String hashedKey;
@@ -3494,7 +3337,7 @@
                 try {
                     SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
 
-                    KeySpec ks = new PBEKeySpec(mKey.toCharArray(), obbInfo.salt,
+                    KeySpec ks = new PBEKeySpec(mKey.toCharArray(), mObbInfo.salt,
                             PBKDF2_HASH_ROUNDS, CRYPTO_ALGORITHM_KEY_SIZE);
                     SecretKey key = factory.generateSecret(ks);
                     BigInteger bi = new BigInteger(key.getEncoded());
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index b36b5d3..bc23316 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -16,15 +16,7 @@
 
 package com.android.server.am;
 
-import android.content.pm.IPackageManager;
-import android.content.pm.PermissionInfo;
-import android.os.Trace;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Set;
+import static com.android.server.am.ActivityManagerDebugConfig.*;
 
 import android.app.ActivityManager;
 import android.app.AppGlobals;
@@ -37,7 +29,9 @@
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.pm.ActivityInfo;
+import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
 import android.content.pm.ResolveInfo;
 import android.os.Bundle;
 import android.os.Handler;
@@ -47,13 +41,19 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.util.EventLog;
 import android.util.Slog;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 
-import static com.android.server.am.ActivityManagerDebugConfig.*;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Set;
 
 /**
  * BROADCASTS
@@ -409,10 +409,12 @@
             String resultData, Bundle resultExtras, boolean resultAbort, boolean waitForServices) {
         final int state = r.state;
         final ActivityInfo receiver = r.curReceiver;
+        final long finishTime = SystemClock.uptimeMillis();
         r.state = BroadcastRecord.IDLE;
         if (state == BroadcastRecord.IDLE) {
             Slog.w(TAG, "finishReceiver [" + mQueueName + "] called but state is IDLE");
         }
+        r.duration[r.nextReceiver - 1] = finishTime - r.receiverTime;
         r.receiver = null;
         r.intent.setComponent(null);
         if (r.curApp != null && r.curApp.curReceivers.contains(r)) {
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 7e15947..9b7dc44 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -18,8 +18,8 @@
 
 import android.app.AppOpsManager;
 import android.app.BroadcastOptions;
-import android.content.IIntentReceiver;
 import android.content.ComponentName;
+import android.content.IIntentReceiver;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ResolveInfo;
@@ -62,6 +62,7 @@
     final BroadcastOptions options; // BroadcastOptions supplied by caller
     final List receivers;   // contains BroadcastFilter and ResolveInfo
     final int[] delivery;   // delivery state of each receiver
+    final long[] duration;   // duration a receiver took to process broadcast
     IIntentReceiver resultTo; // who receives final result if non-null
     long enqueueClockTime;  // the clock time the broadcast was enqueued
     long dispatchTime;      // when dispatch started on this set of receivers
@@ -203,6 +204,7 @@
                 case DELIVERY_TIMEOUT:   pw.print("Timeout"); break;
                 default:                 pw.print("???????"); break;
             }
+            pw.print(" "); TimeUtils.formatDuration(duration[i], pw);
             pw.print(" #"); pw.print(i); pw.print(": ");
             if (o instanceof BroadcastFilter) {
                 pw.println(o);
@@ -239,6 +241,7 @@
         options = _options;
         receivers = _receivers;
         delivery = new int[_receivers != null ? _receivers.size() : 0];
+        duration = new long[delivery.length];
         resultTo = _resultTo;
         resultCode = _resultCode;
         resultData = _resultData;
@@ -274,6 +277,7 @@
         options = from.options;
         receivers = from.receivers;
         delivery = from.delivery;
+        duration = from.duration;
         resultTo = from.resultTo;
         enqueueClockTime = from.enqueueClockTime;
         dispatchTime = from.dispatchTime;
diff --git a/services/net/java/android/net/dhcp/DhcpServingParams.java b/services/net/java/android/net/dhcp/DhcpServingParams.java
index ba9d116..6d58bc6 100644
--- a/services/net/java/android/net/dhcp/DhcpServingParams.java
+++ b/services/net/java/android/net/dhcp/DhcpServingParams.java
@@ -28,6 +28,8 @@
 import android.net.LinkAddress;
 import android.net.NetworkUtils;
 
+import com.google.android.collect.Sets;
+
 import java.net.Inet4Address;
 import java.util.Collections;
 import java.util.HashSet;
@@ -155,6 +157,25 @@
         }
 
         /**
+         * Set the default routers to be advertised to DHCP clients.
+         *
+         * <p>Each router must be inside the served prefix. This may be an empty list of routers,
+         * but it must always be set explicitly before building the {@link DhcpServingParams}.
+         */
+        public Builder setDefaultRouters(@NonNull Inet4Address... defaultRouters) {
+            return setDefaultRouters(Sets.newArraySet(defaultRouters));
+        }
+
+        /**
+         * Convenience method to build the parameters with no default router.
+         *
+         * <p>Equivalent to calling {@link #setDefaultRouters(Inet4Address...)} with no address.
+         */
+        public Builder withNoDefaultRouter() {
+            return setDefaultRouters();
+        }
+
+        /**
          * Set the DNS servers to be advertised to DHCP clients.
          *
          * <p>This may be an empty set, but it must always be set explicitly before building the
@@ -166,6 +187,25 @@
         }
 
         /**
+         * Set the DNS servers to be advertised to DHCP clients.
+         *
+         * <p>This may be an empty list of servers, but it must always be set explicitly before
+         * building the {@link DhcpServingParams}.
+         */
+        public Builder setDnsServers(@NonNull Inet4Address... dnsServers) {
+            return setDnsServers(Sets.newArraySet(dnsServers));
+        }
+
+        /**
+         * Convenience method to build the parameters with no DNS server.
+         *
+         * <p>Equivalent to calling {@link #setDnsServers(Inet4Address...)} with no address.
+         */
+        public Builder withNoDnsServer() {
+            return setDnsServers();
+        }
+
+        /**
          * Set excluded addresses that the DHCP server is not allowed to assign to clients.
          *
          * <p>This parameter is optional. DNS servers and default routers are always excluded
@@ -177,6 +217,16 @@
         }
 
         /**
+         * Set excluded addresses that the DHCP server is not allowed to assign to clients.
+         *
+         * <p>This parameter is optional. DNS servers and default routers are always excluded
+         * and do not need to be set here.
+         */
+        public Builder setExcludedAddrs(@NonNull Inet4Address... excludedAddrs) {
+            return setExcludedAddrs(Sets.newArraySet(excludedAddrs));
+        }
+
+        /**
          * Set the lease time for leases assigned by the DHCP server.
          *
          * <p>This parameter is required.
diff --git a/services/tests/servicestests/src/com/android/server/MountServiceTests.java b/services/tests/servicestests/src/com/android/server/MountServiceTests.java
index ecfe0db..b1b3174 100644
--- a/services/tests/servicestests/src/com/android/server/MountServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/MountServiceTests.java
@@ -220,7 +220,12 @@
 
         final File outFile = getFilePath("test1_nosig.obb");
 
-        mountObb(sm, R.raw.test1_nosig, outFile, OnObbStateChangeListener.ERROR_INTERNAL);
+        try {
+            mountObb(sm, R.raw.test1_nosig, outFile, OnObbStateChangeListener.ERROR_INTERNAL);
+            fail("mountObb should've failed with an exception");
+        } catch (IllegalArgumentException e) {
+            // Expected
+        }
 
         assertFalse("OBB should not be mounted",
                 sm.isObbMounted(outFile.getPath()));
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index d25e59f..9a4ea9e7 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -28,6 +28,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Represents a distinct method to place or receive a phone call. Apps which can place calls and
@@ -360,6 +361,33 @@
     private boolean mIsEnabled;
     private String mGroupId;
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PhoneAccount that = (PhoneAccount) o;
+        return mCapabilities == that.mCapabilities &&
+                mHighlightColor == that.mHighlightColor &&
+                mSupportedAudioRoutes == that.mSupportedAudioRoutes &&
+                mIsEnabled == that.mIsEnabled &&
+                Objects.equals(mAccountHandle, that.mAccountHandle) &&
+                Objects.equals(mAddress, that.mAddress) &&
+                Objects.equals(mSubscriptionAddress, that.mSubscriptionAddress) &&
+                Objects.equals(mLabel, that.mLabel) &&
+                Objects.equals(mShortDescription, that.mShortDescription) &&
+                Objects.equals(mSupportedUriSchemes, that.mSupportedUriSchemes) &&
+                areBundlesEqual(mExtras, that.mExtras) &&
+                Objects.equals(mGroupId, that.mGroupId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mAccountHandle, mAddress, mSubscriptionAddress, mCapabilities,
+                mHighlightColor, mLabel, mShortDescription, mSupportedUriSchemes,
+                mSupportedAudioRoutes,
+                mExtras, mIsEnabled, mGroupId);
+    }
+
     /**
      * Helper class for creating a {@link PhoneAccount}.
      */
@@ -1022,4 +1050,31 @@
 
         return sb.toString();
     }
+
+    /**
+     * Determines if two {@link Bundle}s are equal.
+     * @param extras First {@link Bundle} to check.
+     * @param newExtras {@link Bundle} to compare against.
+     * @return {@code true} if the {@link Bundle}s are equal, {@code false} otherwise.
+     */
+    private static boolean areBundlesEqual(Bundle extras, Bundle newExtras) {
+        if (extras == null || newExtras == null) {
+            return extras == newExtras;
+        }
+
+        if (extras.size() != newExtras.size()) {
+            return false;
+        }
+
+        for(String key : extras.keySet()) {
+            if (key != null) {
+                final Object value = extras.get(key);
+                final Object newValue = newExtras.get(key);
+                if (!Objects.equals(value, newValue)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
 }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 26bf7f8..82e3a9d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -6617,9 +6617,9 @@
      * subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
      *
      * <p>Requires one of the following permissions:
-     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE ACCESS_NETWORK_STATE},
-     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}, or that the
-     * calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE}, or that the calling app has carrier
+     * privileges (see {@link #hasCarrierPrivileges}).
      *
      * <p>Note that this does not take into account any data restrictions that may be present on the
      * calling app. Such restrictions may be inspected with
@@ -6627,11 +6627,69 @@
      *
      * @return true if mobile data is enabled.
      */
+    @RequiresPermission(anyOf = {android.Manifest.permission.ACCESS_NETWORK_STATE,
+            android.Manifest.permission.MODIFY_PHONE_STATE})
     public boolean isDataEnabled() {
         return getDataEnabled(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
     }
 
     /**
+     * Returns whether mobile data roaming is enabled on the subscription.
+     *
+     * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     *
+     * <p>Requires one of the following permissions:
+     * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
+     * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app
+     * has carrier privileges (see {@link #hasCarrierPrivileges}).
+     *
+     * @return {@code true} if the data roaming is enabled on the subscription, otherwise return
+     * {@code false}.
+     */
+    @RequiresPermission(anyOf = {android.Manifest.permission.ACCESS_NETWORK_STATE,
+            android.Manifest.permission.READ_PHONE_STATE})
+    public boolean isDataRoamingEnabled() {
+        boolean isDataRoamingEnabled = false;
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                isDataRoamingEnabled = telephony.isDataRoamingEnabled(getSubId());
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelephony#isDataRoamingEnabled", e);
+        }
+        return isDataRoamingEnabled;
+    }
+
+    /**
+     * Enables/Disables the data roaming on the subscription.
+     *
+     * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     *
+     * <p> Requires permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
+     * privileges (see {@link #hasCarrierPrivileges}).
+     *
+     * @param isEnabled {@code true} to enable mobile data roaming, otherwise disable it.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public void setDataRoamingEnabled(boolean isEnabled) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                telephony.setDataRoamingEnabled(getSubId(), isEnabled);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelephony#setDataRoamingEnabled", e);
+        }
+    }
+
+    /**
      * @deprecated use {@link #isDataEnabled()} instead.
      * @hide
      */
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index c59a739..a7e5581 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1514,6 +1514,22 @@
     void setRadioIndicationUpdateMode(int subId, int filters, int mode);
 
     /**
+     * Returns whether mobile data roaming is enabled on the subscription with id {@code subId}.
+     *
+     * @param subId the subscription id
+     * @return {@code true} if the data roaming is enabled on this subscription.
+     */
+    boolean isDataRoamingEnabled(int subId);
+
+    /**
+     * Enables/Disables the data roaming on the subscription with id {@code subId}.
+     *
+     * @param subId the subscription id
+     * @param isEnabled {@code true} to enable mobile data roaming, otherwise disable it.
+     */
+    void setDataRoamingEnabled(int subId, boolean isEnabled);
+
+    /**
      * A test API to override carrier information including mccmnc, imsi, iccid, gid1, gid2,
      * plmn and spn. This would be handy for, eg, forcing a particular carrier id, carrier's config
      * (also any country or carrier overlays) to be loaded when using a test SIM with a call box.
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index bbe38b7..06378ba 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -20,7 +20,6 @@
 import android.Manifest;
 import android.app.AppOpsManager;
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.os.Binder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -250,6 +249,26 @@
     }
 
     /**
+     * Ensure the caller (or self, if not processing an IPC) has
+     * {@link android.Manifest.permission#READ_PHONE_STATE} or carrier privileges.
+     *
+     * @throws SecurityException if the caller does not have the required permission/privileges
+     */
+    public static void enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
+            Context context, int subId, String message) {
+        if (context.checkCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE)
+                == PERMISSION_GRANTED) {
+            return;
+        }
+
+        if (DBG) {
+            Rlog.d(LOG_TAG, "No READ_PHONE_STATE permission, check carrier privilege next.");
+        }
+
+        enforceCallingOrSelfCarrierPrivilege(subId, message);
+    }
+
+    /**
      * Make sure the caller (or self, if not processing an IPC) has carrier privileges.
      *
      * @throws SecurityException if the caller does not have the required privileges
diff --git a/tests/net/java/android/net/dhcp/DhcpServingParamsTest.java b/tests/net/java/android/net/dhcp/DhcpServingParamsTest.java
index dfa09a9..b6a4073 100644
--- a/tests/net/java/android/net/dhcp/DhcpServingParamsTest.java
+++ b/tests/net/java/android/net/dhcp/DhcpServingParamsTest.java
@@ -37,7 +37,6 @@
 
 import java.net.Inet4Address;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -150,14 +149,14 @@
 
     @Test(expected = InvalidParameterException.class)
     public void testBuild_PrefixTooSmall() throws InvalidParameterException {
-        mBuilder.setDefaultRouters(Collections.singleton(parseAddr("192.168.0.254")))
+        mBuilder.setDefaultRouters(parseAddr("192.168.0.254"))
                 .setServerAddr(new LinkAddress(TEST_SERVER_ADDR, 31))
                 .build();
     }
 
     @Test(expected = InvalidParameterException.class)
     public void testBuild_RouterNotInPrefix() throws InvalidParameterException {
-        mBuilder.setDefaultRouters(Collections.singleton(parseAddr("192.168.254.254"))).build();
+        mBuilder.setDefaultRouters(parseAddr("192.168.254.254")).build();
     }
 
     private static <T> void assertContains(@NonNull Set<T> set, @NonNull Set<T> subset) {
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 58b5e8f..23322ab 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -51,7 +51,7 @@
 
 template <typename T>
 static bool less_than_struct_with_name_and_id(const std::unique_ptr<T>& lhs,
-                                              const std::pair<StringPiece, Maybe<uint8_t>>& rhs) {
+                                              const std::pair<StringPiece, Maybe<uint16_t>>& rhs) {
   int name_cmp = lhs->name.compare(0, lhs->name.size(), rhs.first.data(), rhs.first.size());
   return name_cmp < 0 || (name_cmp == 0 && rhs.second && lhs->id < rhs.second);
 }
@@ -141,7 +141,7 @@
   return types.emplace(iter, std::move(new_type))->get();
 }
 
-ResourceEntry* ResourceTableType::FindEntry(const StringPiece& name, const Maybe<uint8_t> id) {
+ResourceEntry* ResourceTableType::FindEntry(const StringPiece& name, const Maybe<uint16_t> id) {
   const auto last = entries.end();
   auto iter = std::lower_bound(entries.begin(), last, std::make_pair(name, id),
       less_than_struct_with_name_and_id<ResourceEntry>);
@@ -152,7 +152,7 @@
 }
 
 ResourceEntry* ResourceTableType::FindOrCreateEntry(const StringPiece& name,
-                                                    const Maybe<uint8_t> id) {
+                                                    const Maybe<uint16_t > id) {
   auto last = entries.end();
   auto iter = std::lower_bound(entries.begin(), last, std::make_pair(name, id),
                                less_than_struct_with_name_and_id<ResourceEntry>);
@@ -450,7 +450,7 @@
   }
 
   ResourceEntry* entry = type->FindOrCreateEntry(name.entry, use_id ? res_id.entry_id()
-                                                                    : Maybe<uint8_t>());
+                                                                    : Maybe<uint16_t>());
 
   // Check for entries appearing twice with two different entry ids
   if (check_id && entry->id && entry->id.value() != res_id.entry_id()) {
@@ -561,7 +561,7 @@
   }
 
   ResourceEntry* entry = type->FindOrCreateEntry(name.entry, use_id ? res_id.entry_id()
-                                                                    : Maybe<uint8_t>());
+                                                                    : Maybe<uint16_t>());
 
   // Check for entries appearing twice with two different entry ids
   if (check_id && entry->id && entry->id.value() != res_id.entry_id()) {
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index c40323c..5a43a2d 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -146,9 +146,10 @@
 
   explicit ResourceTableType(const ResourceType type) : type(type) {}
 
-  ResourceEntry* FindEntry(const android::StringPiece& name, Maybe<uint8_t> id = Maybe<uint8_t>());
+  ResourceEntry* FindEntry(const android::StringPiece& name,
+                           Maybe<uint16_t> id = Maybe<uint16_t>());
   ResourceEntry* FindOrCreateEntry(const android::StringPiece& name,
-                                   Maybe<uint8_t> id = Maybe<uint8_t>());
+                                   Maybe<uint16_t> id = Maybe<uint16_t>());
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ResourceTableType);
diff --git a/tools/aapt2/ResourceTable_test.cpp b/tools/aapt2/ResourceTable_test.cpp
index 7fa8ea2..1aa9751 100644
--- a/tools/aapt2/ResourceTable_test.cpp
+++ b/tools/aapt2/ResourceTable_test.cpp
@@ -258,4 +258,44 @@
   ASSERT_FALSE(table.SetOverlayable(name, overlayable, test::GetDiagnostics()));
 }
 
+TEST(ResourceTableTest, AllowDuplictaeResourcesNames) {
+  ResourceTable table(/* validate_resources */ false);
+
+  const ResourceName foo_name = test::ParseNameOrDie("android:bool/foo");
+  ASSERT_TRUE(table.AddResourceWithId(foo_name, ResourceId(0x7f0100ff), ConfigDescription{} , "",
+                                      test::BuildPrimitive(android::Res_value::TYPE_INT_BOOLEAN, 0),
+                                      test::GetDiagnostics()));
+  ASSERT_TRUE(table.AddResourceWithId(foo_name, ResourceId(0x7f010100), ConfigDescription{} , "",
+                                      test::BuildPrimitive(android::Res_value::TYPE_INT_BOOLEAN, 1),
+                                      test::GetDiagnostics()));
+
+  ASSERT_TRUE(table.SetVisibilityWithId(foo_name, Visibility{Visibility::Level::kPublic},
+                                        ResourceId(0x7f0100ff), test::GetDiagnostics()));
+  ASSERT_TRUE(table.SetVisibilityWithId(foo_name, Visibility{Visibility::Level::kPrivate},
+                                        ResourceId(0x7f010100), test::GetDiagnostics()));
+
+  auto package = table.FindPackageById(0x7f);
+  ASSERT_THAT(package, NotNull());
+  auto type = package->FindType(ResourceType::kBool);
+  ASSERT_THAT(type, NotNull());
+
+  auto entry1 = type->FindEntry("foo", 0x00ff);
+  ASSERT_THAT(entry1, NotNull());
+  ASSERT_THAT(entry1->id, Eq(0x00ff));
+  ASSERT_THAT(entry1->values[0], NotNull());
+  ASSERT_THAT(entry1->values[0]->value, NotNull());
+  ASSERT_THAT(ValueCast<BinaryPrimitive>(entry1->values[0]->value.get()), NotNull());
+  ASSERT_THAT(ValueCast<BinaryPrimitive>(entry1->values[0]->value.get())->value.data, Eq(0u));
+  ASSERT_THAT(entry1->visibility.level, Visibility::Level::kPublic);
+
+  auto entry2 = type->FindEntry("foo", 0x0100);
+  ASSERT_THAT(entry2, NotNull());
+  ASSERT_THAT(entry2->id, Eq(0x0100));
+  ASSERT_THAT(entry2->values[0], NotNull());
+  ASSERT_THAT(entry1->values[0]->value, NotNull());
+  ASSERT_THAT(ValueCast<BinaryPrimitive>(entry2->values[0]->value.get()), NotNull());
+  ASSERT_THAT(ValueCast<BinaryPrimitive>(entry2->values[0]->value.get())->value.data, Eq(1u));
+  ASSERT_THAT(entry2->visibility.level, Visibility::Level::kPrivate);
+}
+
 }  // namespace aapt