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