diff options
58 files changed, 1121 insertions, 365 deletions
diff --git a/StubLibraries.bp b/StubLibraries.bp index fe84a7ac7715..97fa28fc9e97 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -118,7 +118,6 @@ stubs_defaults { droidstubs { name: "api-stubs-docs", defaults: ["metalava-full-api-stubs-default"], - removed_dex_api_filename: "removed-dex.txt", arg_files: [ "core/res/AndroidManifest.xml", ], @@ -179,7 +178,6 @@ module_libs = " " + droidstubs { name: "system-api-stubs-docs", defaults: ["metalava-full-api-stubs-default"], - removed_dex_api_filename: "system-removed-dex.txt", arg_files: [ "core/res/AndroidManifest.xml", ], @@ -231,7 +229,11 @@ droidstubs { arg_files: [ "core/res/AndroidManifest.xml", ], - args: metalava_framework_docs_args + " --show-annotation android.annotation.TestApi", + args: metalava_framework_docs_args + + " --show-annotation android.annotation.TestApi" + + " --show-for-stub-purposes-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" + + "\\)", check_api: { current: { api_file: "api/test-current.txt", diff --git a/api/current.txt b/api/current.txt index 66f2340b1ca1..3e64cf3f6bba 100644 --- a/api/current.txt +++ b/api/current.txt @@ -48255,6 +48255,7 @@ package android.telephony { method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getDeviceSoftwareVersion(); method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getEmergencyNumberList(); method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getEmergencyNumberList(int); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<java.lang.String> getEquivalentHomePlmns(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String[] getForbiddenPlmns(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getGroupIdLevel1(); method public String getIccAuthentication(int, int, String); @@ -49108,6 +49109,7 @@ package android.telephony.ims.feature { } public static class MmTelFeature.MmTelCapabilities { + method public final boolean isCapable(int); field public static final int CAPABILITY_TYPE_SMS = 8; // 0x8 field public static final int CAPABILITY_TYPE_UT = 4; // 0x4 field public static final int CAPABILITY_TYPE_VIDEO = 2; // 0x2 diff --git a/api/system-current.txt b/api/system-current.txt index e163e7d79255..8db99aa097a7 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -11187,7 +11187,6 @@ package android.telephony { method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion(); - method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<java.lang.String> getEquivalentHomePlmns(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst(); method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping(); @@ -12249,7 +12248,6 @@ package android.telephony.ims.feature { ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities); ctor public MmTelFeature.MmTelCapabilities(int); method public final void addCapabilities(int); - method public final boolean isCapable(int); method public final void removeCapabilities(int); } diff --git a/api/test-current.txt b/api/test-current.txt index 5793b60735ee..fe437dccd9d3 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -85,7 +85,7 @@ package android.app { method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener); method public static void resumeAppSwitches() throws android.os.RemoteException; method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public void scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int); - method @RequiresPermission("android.permission.MANAGE_USERS") public boolean switchUser(@NonNull android.os.UserHandle); + method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean switchUser(@NonNull android.os.UserHandle); field public static final int PROCESS_CAPABILITY_ALL = 7; // 0x7 field public static final int PROCESS_CAPABILITY_ALL_EXPLICIT = 1; // 0x1 field public static final int PROCESS_CAPABILITY_ALL_IMPLICIT = 6; // 0x6 @@ -185,12 +185,12 @@ package android.app { public class AppOpsManager { method @RequiresPermission("android.permission.MANAGE_APPOPS") public void addHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOps); method @RequiresPermission("android.permission.MANAGE_APPOPS") public void clearHistory(); - method @Nullable @RequiresPermission("android.permission.GET_APP_OPS_STATS") public android.app.RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage(); - method @RequiresPermission("android.permission.GET_APP_OPS_STATS") public void getHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>); + method @Nullable @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public android.app.RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage(); + method @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public void getHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>); method @RequiresPermission("android.permission.MANAGE_APPOPS") public void getHistoricalOpsFromDiskRaw(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @Nullable java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>); method public static int getNumOps(); method public static String[] getOpStrs(); - method @NonNull @RequiresPermission("android.permission.GET_APP_OPS_STATS") public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...); + method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...); method public boolean isOperationActive(int, int, String); method @RequiresPermission("android.permission.MANAGE_APPOPS") public void offsetHistory(long); method public static int opToDefaultMode(@NonNull String); @@ -435,10 +435,10 @@ package android.app { } public class DreamManager { - method @RequiresPermission("android.permission.READ_DREAM_STATE") public boolean isDreaming(); - method @RequiresPermission("android.permission.WRITE_DREAM_STATE") public void setActiveDream(@NonNull android.content.ComponentName); - method @RequiresPermission("android.permission.WRITE_DREAM_STATE") public void startDream(@NonNull android.content.ComponentName); - method @RequiresPermission("android.permission.WRITE_DREAM_STATE") public void stopDream(); + method @RequiresPermission(android.Manifest.permission.READ_DREAM_STATE) public boolean isDreaming(); + method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void setActiveDream(@NonNull android.content.ComponentName); + method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void startDream(@NonNull android.content.ComponentName); + method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void stopDream(); } public final class NotificationChannel implements android.os.Parcelable { @@ -528,14 +528,14 @@ package android.app { } public class UiModeManager { - method @RequiresPermission("android.permission.ENTER_CAR_MODE_PRIORITIZED") public void enableCarMode(@IntRange(from=0) int, int); + method @RequiresPermission(android.Manifest.permission.ENTER_CAR_MODE_PRIORITIZED) public void enableCarMode(@IntRange(from=0) int, int); method public boolean isNightModeLocked(); method public boolean isUiModeLocked(); } public class WallpaperManager { method @Nullable public android.graphics.Bitmap getBitmap(); - method @RequiresPermission("android.permission.SET_WALLPAPER_COMPONENT") public boolean setWallpaperComponent(android.content.ComponentName); + method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT) public boolean setWallpaperComponent(android.content.ComponentName); method public boolean shouldEnableWideColorGamut(); method @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) public boolean wallpaperSupportsWcg(int); } @@ -609,11 +609,11 @@ package android.app.assist { package android.app.backup { public class BackupManager { - method @RequiresPermission("android.permission.BACKUP") public android.content.Intent getConfigurationIntent(String); - method @RequiresPermission("android.permission.BACKUP") public android.content.Intent getDataManagementIntent(String); - method @Nullable @RequiresPermission("android.permission.BACKUP") public CharSequence getDataManagementIntentLabel(@NonNull String); - method @Deprecated @Nullable @RequiresPermission("android.permission.BACKUP") public String getDataManagementLabel(@NonNull String); - method @RequiresPermission("android.permission.BACKUP") public String getDestinationString(String); + method @RequiresPermission(android.Manifest.permission.BACKUP) public android.content.Intent getConfigurationIntent(String); + method @RequiresPermission(android.Manifest.permission.BACKUP) public android.content.Intent getDataManagementIntent(String); + method @Nullable @RequiresPermission(android.Manifest.permission.BACKUP) public CharSequence getDataManagementIntentLabel(@NonNull String); + method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.BACKUP) public String getDataManagementLabel(@NonNull String); + method @RequiresPermission(android.Manifest.permission.BACKUP) public String getDestinationString(String); } } @@ -738,20 +738,20 @@ package android.app.role { } public class RoleControllerManager { - method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void isApplicationVisibleForRole(@NonNull String, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); - method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void isRoleVisible(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); + method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void isApplicationVisibleForRole(@NonNull String, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); + method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void isRoleVisible(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); } public final class RoleManager { - method @RequiresPermission("android.permission.OBSERVE_ROLE_HOLDERS") public void addOnRoleHoldersChangedListenerAsUser(@NonNull java.util.concurrent.Executor, @NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle); - method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void addRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); + method @RequiresPermission(android.Manifest.permission.OBSERVE_ROLE_HOLDERS) public void addOnRoleHoldersChangedListenerAsUser(@NonNull java.util.concurrent.Executor, @NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle); + method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void addRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public boolean addRoleHolderFromController(@NonNull String, @NonNull String); - method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void clearRoleHoldersAsUser(@NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); + method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void clearRoleHoldersAsUser(@NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @NonNull @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public java.util.List<java.lang.String> getHeldRolesFromController(@NonNull String); - method @NonNull @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public java.util.List<java.lang.String> getRoleHolders(@NonNull String); - method @NonNull @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public java.util.List<java.lang.String> getRoleHoldersAsUser(@NonNull String, @NonNull android.os.UserHandle); - method @RequiresPermission("android.permission.OBSERVE_ROLE_HOLDERS") public void removeOnRoleHoldersChangedListenerAsUser(@NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle); - method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void removeRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); + method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public java.util.List<java.lang.String> getRoleHolders(@NonNull String); + method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public java.util.List<java.lang.String> getRoleHoldersAsUser(@NonNull String, @NonNull android.os.UserHandle); + method @RequiresPermission(android.Manifest.permission.OBSERVE_ROLE_HOLDERS) public void removeOnRoleHoldersChangedListenerAsUser(@NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle); + method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void removeRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public boolean removeRoleHolderFromController(@NonNull String, @NonNull String); method @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public void setRoleNamesFromController(@NonNull java.util.List<java.lang.String>); field public static final int MANAGE_HOLDERS_FLAG_DONT_KILL_APP = 1; // 0x1 @@ -858,7 +858,7 @@ package android.content { method public int getUserId(); method public void setAutofillOptions(@Nullable android.content.AutofillOptions); method public void setContentCaptureOptions(@Nullable android.content.ContentCaptureOptions); - method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public void startActivityAsUser(@NonNull @RequiresPermission android.content.Intent, @NonNull android.os.UserHandle); + method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public void startActivityAsUser(@NonNull @RequiresPermission android.content.Intent, @NonNull android.os.UserHandle); field public static final String APP_INTEGRITY_SERVICE = "app_integrity"; field public static final String BUGREPORT_SERVICE = "bugreport"; field public static final String CONTENT_CAPTURE_MANAGER_SERVICE = "content_capture"; @@ -877,7 +877,7 @@ package android.content { } public class Intent implements java.lang.Cloneable android.os.Parcelable { - field @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public static final String ACTION_MANAGE_DEFAULT_APP = "android.intent.action.MANAGE_DEFAULT_APP"; + field @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public static final String ACTION_MANAGE_DEFAULT_APP = "android.intent.action.MANAGE_DEFAULT_APP"; field public static final String ACTION_ROLLBACK_COMMITTED = "android.intent.action.ROLLBACK_COMMITTED"; field public static final String EXTRA_ORIGINATING_UID = "android.intent.extra.ORIGINATING_UID"; field public static final String EXTRA_ROLE_NAME = "android.intent.extra.ROLE_NAME"; @@ -976,7 +976,7 @@ package android.content.pm { public static class PackageInstaller.SessionParams implements android.os.Parcelable { method public void setEnableRollback(boolean); method public void setEnableRollback(boolean, int); - method @RequiresPermission("android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS") public void setGrantedRuntimePermissions(String[]); + method @RequiresPermission(android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS) public void setGrantedRuntimePermissions(String[]); method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setInstallAsApex(); method public void setInstallerPackageName(@Nullable String); method public void setRequestDowngrade(boolean); @@ -987,24 +987,24 @@ package android.content.pm { method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void addOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener); method public abstract boolean arePermissionsIndividuallyControlled(); method @Nullable public String getContentCaptureServicePackageName(); - method @Nullable @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract String getDefaultBrowserPackageNameAsUser(int); + method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract String getDefaultBrowserPackageNameAsUser(int); method @Nullable public String getDefaultTextClassifierPackageName(); method @Nullable public String getIncidentReportApproverPackageName(); method public abstract int getInstallReason(@NonNull String, @NonNull android.os.UserHandle); method @NonNull public abstract java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(int, int); - method @NonNull @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int); + method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public abstract java.util.List<android.content.pm.PackageInfo> getInstalledPackagesAsUser(int, int); method @Nullable public abstract String[] getNamesForUids(int[]); method @NonNull public abstract String getPermissionControllerPackageName(); - method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS", "android.permission.GET_RUNTIME_PERMISSIONS"}) public abstract int getPermissionFlags(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); + method @android.content.pm.PackageManager.PermissionFlags @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, android.Manifest.permission.GET_RUNTIME_PERMISSIONS}) public abstract int getPermissionFlags(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); method @NonNull public abstract String getServicesSystemSharedLibraryPackageName(); method @NonNull public abstract String getSharedSystemSharedLibraryPackageName(); method @Nullable public String getSystemTextClassifierPackageName(); method @Nullable public String getWellbeingPackageName(); - method @RequiresPermission("android.permission.GRANT_RUNTIME_PERMISSIONS") public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); + method @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public abstract void grantRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void removeOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener); - method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public abstract void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); - method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle, @NonNull String); - method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.REVOKE_RUNTIME_PERMISSIONS"}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, int, int, @NonNull android.os.UserHandle); + method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public abstract void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); + method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle, @NonNull String); + method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS}) public abstract void updatePermissionFlags(@NonNull String, @NonNull String, @android.content.pm.PackageManager.PermissionFlags int, @android.content.pm.PackageManager.PermissionFlags int, @NonNull android.os.UserHandle); field public static final String FEATURE_ADOPTABLE_STORAGE = "android.software.adoptable_storage"; field public static final String FEATURE_FILE_BASED_ENCRYPTION = "android.software.file_based_encryption"; field public static final int FLAG_PERMISSION_APPLY_RESTRICTION = 16384; // 0x4000 @@ -1291,7 +1291,7 @@ package android.hardware.display { } public final class DisplayManager { - method @RequiresPermission("android.permission.ACCESS_AMBIENT_LIGHT_STATS") public java.util.List<android.hardware.display.AmbientBrightnessDayStats> getAmbientBrightnessStats(); + method @RequiresPermission(android.Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS) public java.util.List<android.hardware.display.AmbientBrightnessDayStats> getAmbientBrightnessStats(); method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getBrightnessConfiguration(); method @RequiresPermission(android.Manifest.permission.BRIGHTNESS_SLIDER_USAGE) public java.util.List<android.hardware.display.BrightnessChangeEvent> getBrightnessEvents(); method @Nullable @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public android.hardware.display.BrightnessConfiguration getDefaultBrightnessConfiguration(); @@ -1306,7 +1306,7 @@ package android.hardware.hdmi { public final class HdmiControlManager { method @Nullable public android.hardware.hdmi.HdmiSwitchClient getSwitchClient(); - method @RequiresPermission("android.permission.HDMI_CEC") public void setStandbyMode(boolean); + method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setStandbyMode(boolean); field public static final String ACTION_OSD_MESSAGE = "android.hardware.hdmi.action.OSD_MESSAGE"; field public static final int AVR_VOLUME_MUTED = 101; // 0x65 field public static final int CLEAR_TIMER_STATUS_CEC_DISABLE = 162; // 0xa2 @@ -1417,11 +1417,9 @@ package android.hardware.hdmi { field public static final int PORT_OUTPUT = 1; // 0x1 } - public class HdmiSwitchClient { + public class HdmiSwitchClient extends android.hardware.hdmi.HdmiClient { method public int getDeviceType(); method @NonNull public java.util.List<android.hardware.hdmi.HdmiPortInfo> getPortInfo(); - method public void sendKeyEvent(int, boolean); - method public void sendVendorCommand(int, byte[], boolean); } } @@ -1680,7 +1678,7 @@ package android.location { method @NonNull public String[] getBackgroundThrottlingWhitelist(); method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void getCurrentLocation(@NonNull android.location.LocationRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.location.Location>); method @NonNull public String[] getIgnoreSettingsWhitelist(); - method @Nullable @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public java.util.List<java.lang.String> getProviderPackages(@NonNull String); + method @Nullable @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public java.util.List<java.lang.String> getProviderPackages(@NonNull String); method @NonNull public java.util.List<android.location.LocationRequest> getTestProviderCurrentRequests(String); method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper); method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.location.LocationListener); @@ -1748,12 +1746,12 @@ package android.media { } public class AudioManager { - method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy); method public boolean hasRegisteredDynamicPolicy(); - method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy); - method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy); - method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public void unregisterAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy); - method @RequiresPermission("android.permission.MODIFY_AUDIO_ROUTING") public void unregisterAudioPolicyAsync(@NonNull android.media.audiopolicy.AudioPolicy); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicyAsync(@NonNull android.media.audiopolicy.AudioPolicy); field public static final int SUCCESS = 0; // 0x0 } @@ -2130,15 +2128,15 @@ package android.net { method @NonNull public android.net.NetworkCapabilities build(); method @NonNull public android.net.NetworkCapabilities.Builder removeCapability(int); method @NonNull public android.net.NetworkCapabilities.Builder removeTransportType(int); - method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setAdministratorUids(@NonNull int[]); + method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setAdministratorUids(@NonNull int[]); method @NonNull public android.net.NetworkCapabilities.Builder setLinkDownstreamBandwidthKbps(int); method @NonNull public android.net.NetworkCapabilities.Builder setLinkUpstreamBandwidthKbps(int); method @NonNull public android.net.NetworkCapabilities.Builder setNetworkSpecifier(@Nullable android.net.NetworkSpecifier); - method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setOwnerUid(int); - method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setRequestorPackageName(@Nullable String); - method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setRequestorUid(int); - method @NonNull @RequiresPermission("android.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP") public android.net.NetworkCapabilities.Builder setSignalStrength(int); - method @NonNull @RequiresPermission("android.permission.NETWORK_FACTORY") public android.net.NetworkCapabilities.Builder setSsid(@Nullable String); + method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setOwnerUid(int); + method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorPackageName(@Nullable String); + method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorUid(int); + method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkCapabilities.Builder setSignalStrength(int); + method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setSsid(@Nullable String); method @NonNull public android.net.NetworkCapabilities.Builder setTransportInfo(@Nullable android.net.TransportInfo); } @@ -2216,11 +2214,11 @@ package android.net { public class TetheringManager { method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheringEventCallback); - method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener); - method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback); - method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering(); - method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int); - method @RequiresPermission(anyOf={"android.permission.TETHER_PRIVILEGED", android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback); + method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void requestLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.OnTetheringEntitlementResultListener); + method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(@NonNull android.net.TetheringManager.TetheringRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback); + method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopAllTethering(); + method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void stopTethering(int); + method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.ACCESS_NETWORK_STATE}) public void unregisterTetheringEventCallback(@NonNull android.net.TetheringManager.TetheringEventCallback); field public static final String ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED"; field public static final String EXTRA_ACTIVE_LOCAL_ONLY = "android.net.extra.ACTIVE_LOCAL_ONLY"; field public static final String EXTRA_ACTIVE_TETHER = "tetherArray"; @@ -2285,9 +2283,9 @@ package android.net { public static class TetheringManager.TetheringRequest.Builder { ctor public TetheringManager.TetheringRequest.Builder(int); method @NonNull public android.net.TetheringManager.TetheringRequest build(); - method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean); - method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean); - method @NonNull @RequiresPermission("android.permission.TETHER_PRIVILEGED") public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress); + method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setExemptFromEntitlementCheck(boolean); + method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setShouldShowEntitlementUi(boolean); + method @NonNull @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public android.net.TetheringManager.TetheringRequest.Builder setStaticIpv4Addresses(@NonNull android.net.LinkAddress, @NonNull android.net.LinkAddress); } public class TrafficStats { @@ -2489,7 +2487,7 @@ package android.net.util { package android.os { public class BatteryManager { - method @RequiresPermission("android.permission.POWER_SAVER") public boolean setChargingStateUpdateDelayMillis(int); + method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public boolean setChargingStateUpdateDelayMillis(int); } public final class BugreportManager { @@ -2785,18 +2783,18 @@ package android.os { } public final class PowerManager { - method @RequiresPermission("android.permission.POWER_SAVER") public int getPowerSaveModeTrigger(); - method @RequiresPermission("android.permission.POWER_SAVER") public boolean setDynamicPowerSaveHint(boolean, int); - method @RequiresPermission(anyOf={"android.permission.DEVICE_POWER", "android.permission.POWER_SAVER"}) public boolean setPowerSaveModeEnabled(boolean); + method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public int getPowerSaveModeTrigger(); + method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public boolean setDynamicPowerSaveHint(boolean, int); + method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setPowerSaveModeEnabled(boolean); field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1 field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0 } public class PowerWhitelistManager { - method @RequiresPermission("android.permission.DEVICE_POWER") public void addToWhitelist(@NonNull String); - method @RequiresPermission("android.permission.DEVICE_POWER") public void addToWhitelist(@NonNull java.util.List<java.lang.String>); - method @RequiresPermission("android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST") public void whitelistAppTemporarily(@NonNull String, long); - method @RequiresPermission("android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST") public long whitelistAppTemporarilyForEvent(@NonNull String, int, @NonNull String); + method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void addToWhitelist(@NonNull String); + method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void addToWhitelist(@NonNull java.util.List<java.lang.String>); + method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public void whitelistAppTemporarily(@NonNull String, long); + method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public long whitelistAppTemporarilyForEvent(@NonNull String, int, @NonNull String); field public static final int EVENT_MMS = 2; // 0x2 field public static final int EVENT_SMS = 1; // 0x1 field public static final int EVENT_UNSPECIFIED = 0; // 0x0 @@ -2862,8 +2860,8 @@ package android.os { } public class SystemConfigManager { - method @NonNull @RequiresPermission("android.permission.READ_CARRIER_APP_INFO") public java.util.Set<java.lang.String> getDisabledUntilUsedPreinstalledCarrierApps(); - method @NonNull @RequiresPermission("android.permission.READ_CARRIER_APP_INFO") public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getDisabledUntilUsedPreinstalledCarrierAssociatedApps(); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_CARRIER_APP_INFO) public java.util.Set<java.lang.String> getDisabledUntilUsedPreinstalledCarrierApps(); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_CARRIER_APP_INFO) public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getDisabledUntilUsedPreinstalledCarrierAssociatedApps(); } public class SystemProperties { @@ -2892,7 +2890,7 @@ package android.os { } public class UserManager { - method @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", "android.permission.CREATE_USERS"}) public boolean hasBaseUserRestriction(@NonNull String, @NonNull android.os.UserHandle); + method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean hasBaseUserRestriction(@NonNull String, @NonNull android.os.UserHandle); method public static boolean isSplitSystemUser(); field public static final String ACTION_USER_RESTRICTIONS_CHANGED = "android.os.action.USER_RESTRICTIONS_CHANGED"; } @@ -2958,10 +2956,10 @@ package android.os { } public abstract class Vibrator { - method @RequiresPermission("android.permission.ACCESS_VIBRATOR_STATE") public void addVibratorStateListener(@NonNull android.os.Vibrator.OnVibratorStateChangedListener); - method @RequiresPermission("android.permission.ACCESS_VIBRATOR_STATE") public void addVibratorStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.Vibrator.OnVibratorStateChangedListener); - method @RequiresPermission("android.permission.ACCESS_VIBRATOR_STATE") public boolean isVibrating(); - method @RequiresPermission("android.permission.ACCESS_VIBRATOR_STATE") public void removeVibratorStateListener(@NonNull android.os.Vibrator.OnVibratorStateChangedListener); + method @RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE) public void addVibratorStateListener(@NonNull android.os.Vibrator.OnVibratorStateChangedListener); + method @RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE) public void addVibratorStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.Vibrator.OnVibratorStateChangedListener); + method @RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE) public boolean isVibrating(); + method @RequiresPermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE) public void removeVibratorStateListener(@NonNull android.os.Vibrator.OnVibratorStateChangedListener); } public static interface Vibrator.OnVibratorStateChangedListener { @@ -3060,12 +3058,12 @@ package android.os.image { public class DynamicSystemClient { ctor public DynamicSystemClient(@NonNull android.content.Context); - method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void bind(); + method @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM) public void bind(); method public void setOnStatusChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener); method public void setOnStatusChangedListener(@NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener); - method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void start(@NonNull android.net.Uri, long); - method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void start(@NonNull android.net.Uri, long, long); - method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void unbind(); + method @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM) public void start(@NonNull android.net.Uri, long); + method @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM) public void start(@NonNull android.net.Uri, long, long); + method @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM) public void unbind(); field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6 field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4 field public static final int CAUSE_ERROR_IO = 3; // 0x3 @@ -3119,13 +3117,13 @@ package android.os.strictmode { package android.permission { public final class PermissionControllerManager { - method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.RESTORE_RUNTIME_PERMISSIONS"}) public void applyStagedRuntimePermissionBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); - method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void countPermissionApps(@NonNull java.util.List<java.lang.String>, int, @NonNull android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, @Nullable android.os.Handler); - method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void getAppPermissions(@NonNull String, @NonNull android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, @Nullable android.os.Handler); - method @RequiresPermission("android.permission.GET_RUNTIME_PERMISSIONS") public void getRuntimePermissionBackup(@NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<byte[]>); - method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermission(@NonNull String, @NonNull String); - method @RequiresPermission("android.permission.REVOKE_RUNTIME_PERMISSIONS") public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback); - method @RequiresPermission(anyOf={"android.permission.GRANT_RUNTIME_PERMISSIONS", "android.permission.RESTORE_RUNTIME_PERMISSIONS"}) public void stageAndApplyRuntimePermissionsBackup(@NonNull byte[], @NonNull android.os.UserHandle); + method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.RESTORE_RUNTIME_PERMISSIONS}) public void applyStagedRuntimePermissionBackup(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); + method @RequiresPermission(android.Manifest.permission.GET_RUNTIME_PERMISSIONS) public void countPermissionApps(@NonNull java.util.List<java.lang.String>, int, @NonNull android.permission.PermissionControllerManager.OnCountPermissionAppsResultCallback, @Nullable android.os.Handler); + method @RequiresPermission(android.Manifest.permission.GET_RUNTIME_PERMISSIONS) public void getAppPermissions(@NonNull String, @NonNull android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, @Nullable android.os.Handler); + method @RequiresPermission(android.Manifest.permission.GET_RUNTIME_PERMISSIONS) public void getRuntimePermissionBackup(@NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<byte[]>); + method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public void revokeRuntimePermission(@NonNull String, @NonNull String); + method @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public void revokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, @NonNull java.util.concurrent.Executor, @NonNull android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback); + method @RequiresPermission(anyOf={android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, android.Manifest.permission.RESTORE_RUNTIME_PERMISSIONS}) public void stageAndApplyRuntimePermissionsBackup(@NonNull byte[], @NonNull android.os.UserHandle); field public static final int COUNT_ONLY_WHEN_GRANTED = 1; // 0x1 field public static final int COUNT_WHEN_SYSTEM = 2; // 0x2 field public static final int REASON_INSTALLER_POLICY_VIOLATION = 2; // 0x2 @@ -3146,9 +3144,9 @@ package android.permission { } public final class PermissionManager { - method @IntRange(from=0) @RequiresPermission(anyOf={"android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY", android.Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS}) public int getRuntimePermissionsVersion(); + method @IntRange(from=0) @RequiresPermission(anyOf={android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, android.Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS}) public int getRuntimePermissionsVersion(); method @NonNull public java.util.List<android.permission.PermissionManager.SplitPermissionInfo> getSplitPermissions(); - method @RequiresPermission(anyOf={"android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY", android.Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS}) public void setRuntimePermissionsVersion(@IntRange(from=0) int); + method @RequiresPermission(anyOf={android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, android.Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS}) public void setRuntimePermissionsVersion(@IntRange(from=0) int); } public static final class PermissionManager.SplitPermissionInfo { @@ -3214,14 +3212,14 @@ package android.provider { } public final class DeviceConfig { - method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static void addOnPropertiesChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertiesChangedListener); - method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static boolean getBoolean(@NonNull String, @NonNull String, boolean); - method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static float getFloat(@NonNull String, @NonNull String, float); - method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static int getInt(@NonNull String, @NonNull String, int); - method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static long getLong(@NonNull String, @NonNull String, long); - method @NonNull @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static android.provider.DeviceConfig.Properties getProperties(@NonNull String, @NonNull java.lang.String...); - method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getProperty(@NonNull String, @NonNull String); - method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static String getString(@NonNull String, @NonNull String, @Nullable String); + method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static void addOnPropertiesChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertiesChangedListener); + method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static boolean getBoolean(@NonNull String, @NonNull String, boolean); + method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static float getFloat(@NonNull String, @NonNull String, float); + method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static int getInt(@NonNull String, @NonNull String, int); + method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static long getLong(@NonNull String, @NonNull String, long); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static android.provider.DeviceConfig.Properties getProperties(@NonNull String, @NonNull java.lang.String...); + method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getProperty(@NonNull String, @NonNull String); + method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getString(@NonNull String, @NonNull String, @Nullable String); method public static void removeOnPropertiesChangedListener(@NonNull android.provider.DeviceConfig.OnPropertiesChangedListener); method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static void resetToDefaults(int, @Nullable String); method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperties(@NonNull android.provider.DeviceConfig.Properties) throws android.provider.DeviceConfig.BadConfigException; @@ -4067,8 +4065,8 @@ package android.telephony { public class PhoneStateListener { method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber); method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber); - field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000 - field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000 + field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000 + field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000 } public final class PreciseDataConnectionState implements android.os.Parcelable { @@ -4109,22 +4107,22 @@ package android.telephony { public class TelephonyManager { method public int addDevicePolicyOverrideApn(@NonNull android.content.Context, @NonNull android.telephony.data.ApnSetting); method public int checkCarrierPrivilegesForPackage(String); - method @Nullable @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication(); + method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication(); method public int getCarrierIdListVersion(); method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent); - method @Nullable @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public android.content.ComponentName getDefaultRespondViaMessageApplication(); + method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getDefaultRespondViaMessageApplication(); method @NonNull public java.util.List<android.telephony.data.ApnSetting> getDevicePolicyOverrideApns(@NonNull android.content.Context); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getLine1AlphaTag(); method public android.util.Pair<java.lang.Integer,java.lang.Integer> getRadioHalVersion(); method public boolean modifyDevicePolicyOverrideApn(@NonNull android.content.Context, int, @NonNull android.telephony.data.ApnSetting); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void refreshUiccProfile(); - method @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public void resetOtaEmergencyNumberDbFilePath(); + method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void resetOtaEmergencyNumberDbFilePath(); method @Deprecated public void setCarrierTestOverride(String, String, String, String, String, String, String); method public void setCarrierTestOverride(String, String, String, String, String, String, String, String, String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setSystemSelectionChannels(@NonNull java.util.List<android.telephony.RadioAccessSpecifier>); - method @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor); + method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void updateOtaEmergencyNumberDbFilePath(@NonNull android.os.ParcelFileDescriptor); field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1 field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0 @@ -4707,7 +4705,6 @@ package android.telephony.ims.feature { ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities); ctor public MmTelFeature.MmTelCapabilities(int); method public final void addCapabilities(int); - method public final boolean isCapable(int); method public final void removeCapabilities(int); } @@ -5227,11 +5224,11 @@ package android.view.accessibility { public final class AccessibilityManager { method public void addAccessibilityServicesStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener, @Nullable android.os.Handler); - method @NonNull @RequiresPermission("android.permission.MANAGE_ACCESSIBILITY") public java.util.List<java.lang.String> getAccessibilityShortcutTargets(int); - method @RequiresPermission("android.permission.MANAGE_ACCESSIBILITY") public void performAccessibilityShortcut(); - method @RequiresPermission("android.permission.MANAGE_ACCESSIBILITY") public void registerSystemAction(@NonNull android.app.RemoteAction, int); + method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public java.util.List<java.lang.String> getAccessibilityShortcutTargets(int); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void performAccessibilityShortcut(); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void registerSystemAction(@NonNull android.app.RemoteAction, int); method public void removeAccessibilityServicesStateChangeListener(@NonNull android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener); - method @RequiresPermission("android.permission.MANAGE_ACCESSIBILITY") public void unregisterSystemAction(int); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public void unregisterSystemAction(int); } public static interface AccessibilityManager.AccessibilityServicesStateChangeListener { diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index e9683a4fdd77..97ef62bf457d 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -1386,6 +1386,7 @@ public final class SystemServiceRegistry { case Context.CONTENT_CAPTURE_MANAGER_SERVICE: case Context.APP_PREDICTION_SERVICE: case Context.INCREMENTAL_SERVICE: + case Context.ETHERNET_SERVICE: return null; } Slog.wtf(TAG, "Manager wrapper not available: " + name); diff --git a/core/java/android/net/NetworkProvider.java b/core/java/android/net/NetworkProvider.java index 75086cf82b57..d31218d9b67b 100644 --- a/core/java/android/net/NetworkProvider.java +++ b/core/java/android/net/NetworkProvider.java @@ -30,7 +30,7 @@ import android.util.Log; /** * Base class for network providers such as telephony or Wi-Fi. NetworkProviders connect the device - * to networks and makes them available to to the core network stack by creating + * to networks and makes them available to the core network stack by creating * {@link NetworkAgent}s. The networks can then provide connectivity to apps and can be interacted * with via networking APIs such as {@link ConnectivityManager}. * diff --git a/core/java/android/permission/Permissions.md b/core/java/android/permission/Permissions.md index 1ef3ad211cee..2da1193c02ed 100644 --- a/core/java/android/permission/Permissions.md +++ b/core/java/android/permission/Permissions.md @@ -847,7 +847,7 @@ private val whitelistedPkgs = listOf("my.whitelisted.package") @Test fun onlySomeAppsAreAllowedToHavePermissionGranted() { - assertThat(whitelistedPkgs).containsAllIn( + assertThat(whitelistedPkgs).containsAtLeastElementsIn( context.packageManager.getInstalledPackages(MATCH_ALL) .filter { pkg -> context.checkPermission(android.Manifest.permission.MY_PRIVILEGED_PERMISSION, -1, diff --git a/core/tests/coretests/src/android/app/NotificationHistoryTest.java b/core/tests/coretests/src/android/app/NotificationHistoryTest.java index c9510918e555..20ac83173ff2 100644 --- a/core/tests/coretests/src/android/app/NotificationHistoryTest.java +++ b/core/tests/coretests/src/android/app/NotificationHistoryTest.java @@ -117,8 +117,8 @@ public class NotificationHistoryTest { history.addNotificationToWrite(n); assertThat(history.getNotificationsToWrite().size()).isEqualTo(2); - assertThat(history.getNotificationsToWrite().get(0)).isSameAs(n2); - assertThat(history.getNotificationsToWrite().get(1)).isSameAs(n); + assertThat(history.getNotificationsToWrite().get(0)).isSameInstanceAs(n2); + assertThat(history.getNotificationsToWrite().get(1)).isSameInstanceAs(n); assertThat(history.getHistoryCount()).isEqualTo(2); } @@ -141,11 +141,11 @@ public class NotificationHistoryTest { history.addNotificationsToWrite(secondHistory); assertThat(history.getNotificationsToWrite().size()).isEqualTo(5); - assertThat(history.getNotificationsToWrite().get(0)).isSameAs(n3); - assertThat(history.getNotificationsToWrite().get(1)).isSameAs(n); - assertThat(history.getNotificationsToWrite().get(2)).isSameAs(n4); - assertThat(history.getNotificationsToWrite().get(3)).isSameAs(n2); - assertThat(history.getNotificationsToWrite().get(4)).isSameAs(n5); + assertThat(history.getNotificationsToWrite().get(0)).isSameInstanceAs(n3); + assertThat(history.getNotificationsToWrite().get(1)).isSameInstanceAs(n); + assertThat(history.getNotificationsToWrite().get(2)).isSameInstanceAs(n4); + assertThat(history.getNotificationsToWrite().get(3)).isSameInstanceAs(n2); + assertThat(history.getNotificationsToWrite().get(4)).isSameInstanceAs(n5); assertThat(history.getHistoryCount()).isEqualTo(5); assertThat(history.getPooledStringsToWrite()).asList().contains(n2.getChannelName()); diff --git a/core/tests/coretests/src/android/content/integrity/CompoundFormulaTest.java b/core/tests/coretests/src/android/content/integrity/CompoundFormulaTest.java index ba060fa630c5..593e70e6b257 100644 --- a/core/tests/coretests/src/android/content/integrity/CompoundFormulaTest.java +++ b/core/tests/coretests/src/android/content/integrity/CompoundFormulaTest.java @@ -45,7 +45,8 @@ public class CompoundFormulaTest { CompoundFormula.AND, Arrays.asList(ATOMIC_FORMULA_1, ATOMIC_FORMULA_2)); assertThat(compoundFormula.getConnector()).isEqualTo(CompoundFormula.AND); - assertThat(compoundFormula.getFormulas()).containsAllOf(ATOMIC_FORMULA_1, ATOMIC_FORMULA_2); + assertThat(compoundFormula.getFormulas()) + .containsAtLeast(ATOMIC_FORMULA_1, ATOMIC_FORMULA_2); } @Test diff --git a/core/tests/coretests/src/android/content/pm/parsing/result/ParseInputAndResultTest.kt b/core/tests/coretests/src/android/content/pm/parsing/result/ParseInputAndResultTest.kt index d45fee97950f..9ad63adda6b7 100644 --- a/core/tests/coretests/src/android/content/pm/parsing/result/ParseInputAndResultTest.kt +++ b/core/tests/coretests/src/android/content/pm/parsing/result/ParseInputAndResultTest.kt @@ -113,7 +113,7 @@ class ParseInputAndResultTest { assertError(result) assertThat(result.errorCode).isEqualTo(errorCode) assertThat(result.errorMessage).isEqualTo(errorMessage) - assertThat(result.exception).isSameAs(exception) + assertThat(result.exception).isSameInstanceAs(exception) } @Test @@ -125,13 +125,13 @@ class ParseInputAndResultTest { assertError(result) assertThat(result.errorCode).isEqualTo(errorCode) assertThat(result.errorMessage).isEqualTo(errorMessage) - assertThat(result.exception).isSameAs(exception) + assertThat(result.exception).isSameInstanceAs(exception) val carriedResult = input.error<Int>(result) assertError(carriedResult) assertThat(carriedResult.errorCode).isEqualTo(errorCode) assertThat(carriedResult.errorMessage).isEqualTo(errorMessage) - assertThat(carriedResult.exception).isSameAs(exception) + assertThat(carriedResult.exception).isSameInstanceAs(exception) } @Test @@ -259,7 +259,7 @@ class ParseInputAndResultTest { private fun assertSuccess(expected: Any? = null, result: ParseResult<*>) { assertThat(result.isError).isFalse() assertThat(result.isSuccess).isTrue() - assertThat(result.result).isSameAs(expected) + assertThat(result.result).isSameInstanceAs(expected) assertThat(result.errorCode).isEqualTo(PackageManager.INSTALL_SUCCEEDED) assertThat(result.errorMessage).isNull() assertThat(result.exception).isNull() diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java index 628252d8ca6c..402b92a3f2a2 100644 --- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java @@ -52,7 +52,8 @@ public class TextClassificationManagerTest { @Test public void testGetLocalTextClassifier() { - assertThat(mTcm.getTextClassifier(TextClassifier.LOCAL)).isSameAs(TextClassifier.NO_OP); + assertThat(mTcm.getTextClassifier(TextClassifier.LOCAL)) + .isSameInstanceAs(TextClassifier.NO_OP); } @Test diff --git a/core/tests/coretests/src/com/android/internal/infra/AndroidFutureTest.java b/core/tests/coretests/src/com/android/internal/infra/AndroidFutureTest.java index f108eb8aeb0b..a2bc77a71c90 100644 --- a/core/tests/coretests/src/com/android/internal/infra/AndroidFutureTest.java +++ b/core/tests/coretests/src/com/android/internal/infra/AndroidFutureTest.java @@ -81,7 +81,7 @@ public class AndroidFutureTest { future.completeExceptionally(origException); ExecutionException executionException = expectThrows(ExecutionException.class, future::get); - assertThat(executionException.getCause()).isSameAs(origException); + assertThat(executionException.getCause()).isSameInstanceAs(origException); } @Test @@ -92,7 +92,7 @@ public class AndroidFutureTest { CountDownLatch latch = new CountDownLatch(1); future.whenComplete((obj, err) -> { assertThat(obj).isNull(); - assertThat(err).isSameAs(origException); + assertThat(err).isSameInstanceAs(origException); latch.countDown(); }); latch.await(); diff --git a/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java index 59148870fa3c..942045c8bf35 100644 --- a/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java @@ -107,7 +107,7 @@ public class BinderDeathDispatcherTest { if (!isAlive) { return false; } - assertThat(mRecipient).isSameAs(recipient); + assertThat(mRecipient).isSameInstanceAs(recipient); mRecipient = null; return true; } diff --git a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java index 9f68ef31c166..7eca320d4aeb 100644 --- a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java +++ b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java @@ -74,7 +74,7 @@ public class RegisterStatusBarResultTest { assertThat(copy.mImeBackDisposition).isEqualTo(original.mImeBackDisposition); assertThat(copy.mShowImeSwitcher).isEqualTo(original.mShowImeSwitcher); assertThat(copy.mDisabledFlags2).isEqualTo(original.mDisabledFlags2); - assertThat(copy.mImeToken).isSameAs(original.mImeToken); + assertThat(copy.mImeToken).isSameInstanceAs(original.mImeToken); assertThat(copy.mNavbarColorManagedByIme).isEqualTo(original.mNavbarColorManagedByIme); assertThat(copy.mAppFullscreen).isEqualTo(original.mAppFullscreen); assertThat(copy.mAppImmersive).isEqualTo(original.mAppImmersive); diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java index 67a040dba3e7..139474c1c01d 100644 --- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java +++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java @@ -28,7 +28,6 @@ import android.location.LocationManager; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; -import android.telephony.PhoneNumberUtils; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log; @@ -161,7 +160,7 @@ public class GpsNetInitiatedHandler { be set to true when the phone is having emergency call, and then will be set to false by mPhoneStateListener when the emergency call ends. */ - mIsInEmergencyCall = PhoneNumberUtils.isEmergencyNumber(phoneNumber); + mIsInEmergencyCall = mTelephonyManager.isEmergencyNumber(phoneNumber); if (DEBUG) Log.v(TAG, "ACTION_NEW_OUTGOING_CALL - " + getInEmergency()); } else if (action.equals(LocationManager.MODE_CHANGED_ACTION)) { updateLocationMode(); diff --git a/media/OWNERS b/media/OWNERS index 36df3a05e0ee..0fc781c848f7 100644 --- a/media/OWNERS +++ b/media/OWNERS @@ -15,6 +15,8 @@ jsharkey@android.com klhyun@google.com lajos@google.com marcone@google.com +nchalko@google.com philburk@google.com +quxiangfang@google.com sungsoo@google.com wonsik@google.com diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt index afecd9a0f137..f82aefa6d472 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -46423,6 +46423,7 @@ package android.telephony { method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getDeviceSoftwareVersion(); method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getEmergencyNumberList(); method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getEmergencyNumberList(int); + method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<java.lang.String> getEquivalentHomePlmns(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String[] getForbiddenPlmns(); method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getGroupIdLevel1(); method public String getIccAuthentication(int, int, String); @@ -47276,6 +47277,7 @@ package android.telephony.ims.feature { } public static class MmTelFeature.MmTelCapabilities { + method public final boolean isCapable(int); field public static final int CAPABILITY_TYPE_SMS = 8; // 0x8 field public static final int CAPABILITY_TYPE_UT = 4; // 0x4 field public static final int CAPABILITY_TYPE_VIDEO = 2; // 0x2 diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index 2b3e7815d060..6a217b2ce847 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -10069,7 +10069,6 @@ package android.telephony { method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion(); - method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<java.lang.String> getEquivalentHomePlmns(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst(); method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping(); @@ -11131,7 +11130,6 @@ package android.telephony.ims.feature { ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities); ctor public MmTelFeature.MmTelCapabilities(int); method public final void addCapabilities(int); - method public final boolean isCapable(int); method public final void removeCapabilities(int); } diff --git a/packages/InputDevices/res/raw/keyboard_layout_turkish_f.kcm b/packages/InputDevices/res/raw/keyboard_layout_turkish_f.kcm new file mode 100644 index 000000000000..5b96da027be7 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_turkish_f.kcm @@ -0,0 +1,366 @@ +# Copyright (C) 2020 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. + +# +# Turkish F keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 13 MINUS +map key 43 COMMA +map key 51 EQUALS +map key 52 BACKSLASH +map key 53 PERIOD +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '+' + base: '+' + shift: '*' + ralt: '\u00ac' +} + +key 1 { + label: '1' + base: '1' + shift: '!' + ralt: '\u00b9' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '\u00b2' +} + +key 3 { + label: '3' + base: '3' + shift: '^' + ralt: '#' +} + +key 4 { + label: '4' + base: '4' + shift: '$' + ralt: '\u00bc' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '\u00bd' +} + +key 6 { + label: '6' + base: '6' + shift: '&' + ralt: '\u00be' +} + +key 7 { + label: '7' + base: '7' + shift: '\'' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key SLASH { + label: '/' + base: '/' + shift: '?' + ralt: '\\' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' + ralt: '|' +} + +### ROW 2 + +key Q { + label: 'F' + base: 'f' + shift, capslock: 'F' + ralt: '@' +} + +key W { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key E { + label: '\u011f' + base: '\u011f' + shift, capslock: '\u011e' +} + +key R { + label: '\u0131' + base: '\u0131' + shift, capslock: 'I' + ralt: '\u00b6' + ralt+shift, ralt+capslock: '\u00ae' +} + +key T { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key Y { + label: 'D' + base: 'd' + shift, capslock: 'D' + ralt: '\u00a5' +} + +key U { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key I { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key O { + label: 'H' + base: 'h' + shift, capslock: 'H' + ralt: '\u00f8' + ralt+shift, ralt+capslock: '\u00d8' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' + ralt: '\u00a3' +} + +key LEFT_BRACKET { + label: 'Q' + base: 'q' + shift, capslock: 'Q' + ralt: '"' +} + +key RIGHT_BRACKET { + label: 'W' + base: 'w' + shift, capslock: 'W' + ralt: '~' +} + +### ROW 3 + +key A { + label: '\u0075' + base: '\u0075' + shift, capslock: '\u0055' + ralt: '\u00e6' + ralt+shift, ralt+capslock: '\u00c6' +} + +key S { + label: 'i' + base: 'i' + shift, capslock: '\u0130' + ralt: '\u00df' + ralt+shift, ralt+capslock: '\u00a7' +} + +key D { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key F { + label: 'A' + base: 'a' + shift, capslock: 'A' + ralt: '\u00aa' +} + +key G { + label: '\u00fc' + base: '\u00fc' + shift, capslock: '\u00dc' +} + +key H { + label: 'T' + base: 't' + shift, capslock: 'T' + ralt: '\u20ba' +} + +key J { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key K { + label: 'M' + base: 'm' + shift, capslock: 'M' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: 'Y' + base: 'y' + shift, capslock: 'Y' + ralt: '\u00b4' +} + +key APOSTROPHE { + label: '\u015f' + base: '\u015f' + shift, capslock: '\u015e' +} + +key COMMA { + label: 'X' + base: 'x' + shift: 'X' + ralt: '\u0060' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '|' + ralt+shift, ralt+capslock: '\u00a6' +} + +key Z { + label: 'J' + base: 'j' + shift, capslock: 'J' + ralt: '\u00ab' + ralt+shift, ralt+capslock: '<' +} + +key X { + label: '\u00f6' + base: '\u00f6' + shift, capslock: '\u00d6' + ralt: '\u00bb' + ralt+shift, ralt+capslock: '>' +} + +key C { + label: 'V' + base: 'v' + shift, capslock: 'V' + ralt: '\u00a2' + ralt+shift, ralt+capslock: '\u00a9' +} + +key V { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key B { + label: '\u00e7' + base: '\u00e7' + shift, capslock: '\u00c7' +} + +key N { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key M { + label: 'S' + base: 's' + shift, capslock: 'S' + ralt: '\u00b5' + ralt+shift, ralt+capslock: '\u00ba' +} + +key EQUALS { + label: 'B' + base: 'b' + shift, capslock: 'B' + ralt: '\u00d7' +} + +key BACKSLASH { + label: '.' + base: '.' + shift, capslock: ':' + ralt: '\u00f7' +} + +key PERIOD { + label: ',' + base: ',' + shift: ';' +} diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml index e95a15912397..c2585ff49a11 100644 --- a/packages/InputDevices/res/values/strings.xml +++ b/packages/InputDevices/res/values/strings.xml @@ -102,6 +102,9 @@ <!-- Turkish keyboard layout label. [CHAR LIMIT=35] --> <string name="keyboard_layout_turkish">Turkish</string> + <!-- Turkish keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_turkish_f">Turkish F</string> + <!-- Ukrainian keyboard layout label. [CHAR LIMIT=35] --> <string name="keyboard_layout_ukrainian">Ukrainian</string> diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml index aa599ae7f2d0..d3c421da9055 100644 --- a/packages/InputDevices/res/xml/keyboard_layouts.xml +++ b/packages/InputDevices/res/xml/keyboard_layouts.xml @@ -128,6 +128,10 @@ android:label="@string/keyboard_layout_turkish" android:keyboardLayout="@raw/keyboard_layout_turkish" /> + <keyboard-layout android:name="keyboard_layout_turkish_f" + android:label="@string/keyboard_layout_turkish_f" + android:keyboardLayout="@raw/keyboard_layout_turkish_f" /> + <keyboard-layout android:name="keyboard_layout_ukrainian" android:label="@string/keyboard_layout_ukrainian" android:keyboardLayout="@raw/keyboard_layout_ukrainian" /> diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java index 81cf118031bf..b0a913617ba0 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java @@ -1090,7 +1090,7 @@ public class WifiTrackerTest { // Verify second update AP is the same object as the first update AP assertThat(passpointAccessPointsFirstUpdate.get(0)) - .isSameAs(passpointAccessPointsSecondUpdate.get(0)); + .isSameInstanceAs(passpointAccessPointsSecondUpdate.get(0)); // Verify second update AP has the average of the first and second update RSSIs assertThat(passpointAccessPointsSecondUpdate.get(0).getRssi()) .isEqualTo((prevRssi + newRssi) / 2); @@ -1210,7 +1210,8 @@ public class WifiTrackerTest { providersAndScans, cachedAccessPoints); // Verify second update AP is the same object as the first update AP - assertThat(osuAccessPointsFirstUpdate.get(0)).isSameAs(osuAccessPointsSecondUpdate.get(0)); + assertThat(osuAccessPointsFirstUpdate.get(0)) + .isSameInstanceAs(osuAccessPointsSecondUpdate.get(0)); // Verify second update AP has the average of the first and second update RSSIs assertThat(osuAccessPointsSecondUpdate.get(0).getRssi()) .isEqualTo((prevRssi + newRssi) / 2); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java index a83d7e099e51..b392c5e5d772 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/IpAddressPreferenceControllerTest.java @@ -69,7 +69,7 @@ public class IpAddressPreferenceControllerTest { assertWithMessage("Intent filter should contain expected intents") .that(ipAddressPreferenceController.getConnectivityIntents()) - .asList().containsAllIn(expectedIntents); + .asList().containsAtLeastElementsIn(expectedIntents); } private static class ConcreteIpAddressPreferenceController extends diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java index 40b9b13ef55f..37052673eb4d 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java @@ -90,7 +90,7 @@ public class WifiMacAddressPreferenceControllerTest { assertWithMessage("Intent filter should contain expected intents") .that(mController.getConnectivityIntents()) - .asList().containsAllIn(expectedIntents); + .asList().containsAtLeastElementsIn(expectedIntents); } @Test diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java index 9b4b97e7f55d..f334cd332ad9 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java @@ -281,7 +281,7 @@ public class TileUtilsTest { assertThat(outTiles).hasSize(1); final Bundle newMetaData = outTiles.get(0).getMetaData(); - assertThat(newMetaData).isNotSameAs(oldMetadata); + assertThat(newMetaData).isNotSameInstanceAs(oldMetadata); } @Test diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java index 353fe625b8ea..35fe1ba8f805 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java @@ -168,7 +168,7 @@ public final class ClockManagerTest extends SysuiTestCase { verify(mMockListener2).onClockChanged(captor2.capture()); assertThat(captor1.getValue()).isInstanceOf(BUBBLE_CLOCK_CLASS); assertThat(captor2.getValue()).isInstanceOf(BUBBLE_CLOCK_CLASS); - assertThat(captor1.getValue()).isNotSameAs(captor2.getValue()); + assertThat(captor1.getValue()).isNotSameInstanceAs(captor2.getValue()); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java index 315caeebe0e9..12221bcc3310 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java @@ -19,6 +19,7 @@ package com.android.systemui.bubbles; import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; @@ -793,47 +794,48 @@ public class BubbleDataTest extends SysuiTestCase { private void assertBubbleAdded(Bubble expected) { BubbleData.Update update = mUpdateCaptor.getValue(); - assertThat(update.addedBubble).named("addedBubble").isEqualTo(expected); + assertWithMessage("addedBubble").that(update.addedBubble).isEqualTo(expected); } private void assertBubbleRemoved(Bubble expected, @BubbleController.DismissReason int reason) { BubbleData.Update update = mUpdateCaptor.getValue(); - assertThat(update.removedBubbles).named("removedBubbles") + assertWithMessage("removedBubbles").that(update.removedBubbles) .isEqualTo(ImmutableList.of(Pair.create(expected, reason))); } private void assertOrderNotChanged() { BubbleData.Update update = mUpdateCaptor.getValue(); - assertThat(update.orderChanged).named("orderChanged").isFalse(); + assertWithMessage("orderChanged").that(update.orderChanged).isFalse(); } private void assertOrderChangedTo(Bubble... order) { BubbleData.Update update = mUpdateCaptor.getValue(); - assertThat(update.orderChanged).named("orderChanged").isTrue(); - assertThat(update.bubbles).named("bubble order").isEqualTo(ImmutableList.copyOf(order)); + assertWithMessage("orderChanged").that(update.orderChanged).isTrue(); + assertWithMessage("bubble order").that(update.bubbles) + .isEqualTo(ImmutableList.copyOf(order)); } private void assertSelectionNotChanged() { BubbleData.Update update = mUpdateCaptor.getValue(); - assertThat(update.selectionChanged).named("selectionChanged").isFalse(); + assertWithMessage("selectionChanged").that(update.selectionChanged).isFalse(); } private void assertSelectionChangedTo(Bubble bubble) { BubbleData.Update update = mUpdateCaptor.getValue(); - assertThat(update.selectionChanged).named("selectionChanged").isTrue(); - assertThat(update.selectedBubble).named("selectedBubble").isEqualTo(bubble); + assertWithMessage("selectionChanged").that(update.selectionChanged).isTrue(); + assertWithMessage("selectedBubble").that(update.selectedBubble).isEqualTo(bubble); } private void assertSelectionCleared() { BubbleData.Update update = mUpdateCaptor.getValue(); - assertThat(update.selectionChanged).named("selectionChanged").isTrue(); - assertThat(update.selectedBubble).named("selectedBubble").isNull(); + assertWithMessage("selectionChanged").that(update.selectionChanged).isTrue(); + assertWithMessage("selectedBubble").that(update.selectedBubble).isNull(); } private void assertExpandedChangedTo(boolean expected) { BubbleData.Update update = mUpdateCaptor.getValue(); - assertThat(update.expandedChanged).named("expandedChanged").isTrue(); - assertThat(update.expanded).named("expanded").isEqualTo(expected); + assertWithMessage("expandedChanged").that(update.expandedChanged).isTrue(); + assertWithMessage("expanded").that(update.expanded).isEqualTo(expected); } private void assertOverflowChangedTo(ImmutableList<Bubble> bubbles) { @@ -895,4 +897,4 @@ public class BubbleDataTest extends SysuiTestCase { setCurrentTime(time); mBubbleData.setExpanded(shouldBeExpanded); } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/MediaArtworkProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/MediaArtworkProcessorTest.kt index 72e6df27a254..724ea023f2bd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/MediaArtworkProcessorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/MediaArtworkProcessorTest.kt @@ -80,7 +80,7 @@ class MediaArtworkProcessorTest : SysuiTestCase() { val background2 = processor.processArtwork(context, artwork)!! // THEN the two bitmaps are the same // Note: This is currently broken and trying to use caching causes issues - assertThat(background1).isNotSameAs(background2) + assertThat(background1).isNotSameInstanceAs(background2) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/people/PeopleHubViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/people/PeopleHubViewControllerTest.kt index 79fa43604c38..5898664dea8e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/people/PeopleHubViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/people/PeopleHubViewControllerTest.kt @@ -118,7 +118,7 @@ class PeopleHubViewControllerTest : SysuiTestCase() { val people = viewModel.people.toList() assertThat(people.size).isEqualTo(1) assertThat(people[0].name).isEqualTo("name") - assertThat(people[0].icon).isSameAs(fakePerson.avatar) + assertThat(people[0].icon).isSameInstanceAs(fakePerson.avatar) people[0].onClick() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index b0b66b87d421..00332cc9cd92 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -326,7 +326,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mAccessibiltyDelegate.onInitializeAccessibilityNodeInfo(mView, nodeInfo); List<AccessibilityNodeInfo.AccessibilityAction> actionList = nodeInfo.getActionList(); - assertThat(actionList).containsAllIn( + assertThat(actionList).containsAtLeastElementsIn( new AccessibilityNodeInfo.AccessibilityAction[] { AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD, AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_UP} diff --git a/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java b/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java index 6276c4e2aa7d..0cf14e3f868c 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java @@ -20,6 +20,10 @@ import static android.net.TetheringManager.TETHERING_BLUETOOTH; import static android.net.TetheringManager.TETHERING_WIFI_P2P; import static android.net.util.PrefixUtils.asIpPrefix; +import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH; +import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH; +import static com.android.net.module.util.Inet4AddressUtils.prefixLengthToV4NetmaskIntHTH; + import static java.util.Arrays.asList; import android.content.Context; @@ -37,9 +41,10 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.IndentingPrintWriter; +import java.net.Inet4Address; import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Random; @@ -58,10 +63,6 @@ import java.util.Set; public class PrivateAddressCoordinator { public static final int PREFIX_LENGTH = 24; - private static final int MAX_UBYTE = 256; - private static final int BYTE_MASK = 0xff; - private static final byte DEFAULT_ID = (byte) 42; - // Upstream monitor would be stopped when tethering is down. When tethering restart, downstream // address may be requested before coordinator get current upstream notification. To ensure // coordinator do not select conflict downstream prefix, mUpstreamPrefixMap would not be cleared @@ -69,22 +70,22 @@ public class PrivateAddressCoordinator { // mUpstreamPrefixMap when tethering is starting. See #maybeRemoveDeprecatedUpstreams(). private final ArrayMap<Network, List<IpPrefix>> mUpstreamPrefixMap; private final ArraySet<IpServer> mDownstreams; - // IANA has reserved the following three blocks of the IP address space for private intranets: - // 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 - // Tethering use 192.168.0.0/16 that has 256 contiguous class C network numbers. - private static final String DEFAULT_TETHERING_PREFIX = "192.168.0.0/16"; private static final String LEGACY_WIFI_P2P_IFACE_ADDRESS = "192.168.49.1/24"; private static final String LEGACY_BLUETOOTH_IFACE_ADDRESS = "192.168.44.1/24"; - private final IpPrefix mTetheringPrefix; + private final List<IpPrefix> mTetheringPrefixes; private final ConnectivityManager mConnectivityMgr; private final TetheringConfiguration mConfig; // keyed by downstream type(TetheringManager.TETHERING_*). private final SparseArray<LinkAddress> mCachedAddresses; public PrivateAddressCoordinator(Context context, TetheringConfiguration config) { + this(context, config, new ArrayList<>(Arrays.asList(new IpPrefix("192.168.0.0/16")))); + } + + public PrivateAddressCoordinator(Context context, TetheringConfiguration config, + List<IpPrefix> prefixPools) { mDownstreams = new ArraySet<>(); mUpstreamPrefixMap = new ArrayMap<>(); - mTetheringPrefix = new IpPrefix(DEFAULT_TETHERING_PREFIX); mConnectivityMgr = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE); mConfig = config; @@ -92,6 +93,8 @@ public class PrivateAddressCoordinator { // Reserved static addresses for bluetooth and wifi p2p. mCachedAddresses.put(TETHERING_BLUETOOTH, new LinkAddress(LEGACY_BLUETOOTH_IFACE_ADDRESS)); mCachedAddresses.put(TETHERING_WIFI_P2P, new LinkAddress(LEGACY_WIFI_P2P_IFACE_ADDRESS)); + + mTetheringPrefixes = prefixPools; } /** @@ -179,52 +182,148 @@ public class PrivateAddressCoordinator { return cachedAddress; } - // Address would be 192.168.[subAddress]/24. - final byte[] bytes = mTetheringPrefix.getRawAddress(); - final int subAddress = getRandomSubAddr(); - final int subNet = (subAddress >> 8) & BYTE_MASK; - bytes[3] = getSanitizedAddressSuffix(subAddress, (byte) 0, (byte) 1, (byte) 0xff); - for (int i = 0; i < MAX_UBYTE; i++) { - final int newSubNet = (subNet + i) & BYTE_MASK; - bytes[2] = (byte) newSubNet; - - final InetAddress addr; - try { - addr = InetAddress.getByAddress(bytes); - } catch (UnknownHostException e) { - throw new IllegalStateException("Invalid address, shouldn't happen.", e); + for (IpPrefix prefixRange : mTetheringPrefixes) { + final LinkAddress newAddress = chooseDownstreamAddress(prefixRange); + if (newAddress != null) { + mDownstreams.add(ipServer); + mCachedAddresses.put(ipServer.interfaceType(), newAddress); + return newAddress; } - - if (isConflict(new IpPrefix(addr, PREFIX_LENGTH))) continue; - - mDownstreams.add(ipServer); - final LinkAddress newAddress = new LinkAddress(addr, PREFIX_LENGTH); - mCachedAddresses.put(ipServer.interfaceType(), newAddress); - return newAddress; } // No available address. return null; } - private boolean isConflict(final IpPrefix prefix) { - // Check whether this prefix is in use or conflict with any current upstream network. - return isDownstreamPrefixInUse(prefix) || isConflictWithUpstream(prefix); + private int getPrefixBaseAddress(final IpPrefix prefix) { + return inet4AddressToIntHTH((Inet4Address) prefix.getAddress()); + } + + /** + * Check whether input prefix conflict with upstream prefixes or in-use downstream prefixes. + * If yes, return one of them. + */ + private IpPrefix getConflictPrefix(final IpPrefix prefix) { + final IpPrefix upstream = getConflictWithUpstream(prefix); + if (upstream != null) return upstream; + + return getInUseDownstreamPrefix(prefix); + } + + // Get the next non-conflict sub prefix. E.g: To get next sub prefix from 10.0.0.0/8, if the + // previously selected prefix is 10.20.42.0/24(subPrefix: 0.20.42.0) and the conflicting prefix + // is 10.16.0.0/20 (10.16.0.0 ~ 10.16.15.255), then the max address under subPrefix is + // 0.16.15.255 and the next subPrefix is 0.16.16.255/24 (0.16.15.255 + 0.0.1.0). + // Note: the sub address 0.0.0.255 here is fine to be any value that it will be replaced as + // selected random sub address later. + private int getNextSubPrefix(final IpPrefix conflictPrefix, final int prefixRangeMask) { + final int suffixMask = ~prefixLengthToV4NetmaskIntHTH(conflictPrefix.getPrefixLength()); + // The largest offset within the prefix assignment block that still conflicts with + // conflictPrefix. + final int maxConflict = + (getPrefixBaseAddress(conflictPrefix) | suffixMask) & ~prefixRangeMask; + + final int prefixMask = prefixLengthToV4NetmaskIntHTH(PREFIX_LENGTH); + // Pick a sub prefix a full prefix (1 << (32 - PREFIX_LENGTH) addresses) greater than + // maxConflict. This ensures that the selected prefix never overlaps with conflictPrefix. + // There is no need to mask the result with PREFIX_LENGTH bits because this is done by + // findAvailablePrefixFromRange when it constructs the prefix. + return maxConflict + (1 << (32 - PREFIX_LENGTH)); } - /** Get random sub address value. Return value is in 0 ~ 0xffff. */ + private LinkAddress chooseDownstreamAddress(final IpPrefix prefixRange) { + // The netmask of the prefix assignment block (e.g., 0xfff00000 for 172.16.0.0/12). + final int prefixRangeMask = prefixLengthToV4NetmaskIntHTH(prefixRange.getPrefixLength()); + + // The zero address in the block (e.g., 0xac100000 for 172.16.0.0/12). + final int baseAddress = getPrefixBaseAddress(prefixRange); + + // The subnet mask corresponding to PREFIX_LENGTH. + final int prefixMask = prefixLengthToV4NetmaskIntHTH(PREFIX_LENGTH); + + // The offset within prefixRange of a randomly-selected prefix of length PREFIX_LENGTH. + // This may not be the prefix of the address returned by this method: + // - If it is already in use, the method will return an address in another prefix. + // - If all prefixes within prefixRange are in use, the method will return null. For + // example, for a /24 prefix within 172.26.0.0/12, this will be a multiple of 256 in + // [0, 1048576). In other words, a random 32-bit number with mask 0x000fff00. + // + // prefixRangeMask is required to ensure no wrapping. For example, consider: + // - prefixRange 127.0.0.0/8 + // - randomPrefixStart 127.255.255.0 + // - A conflicting prefix of 127.255.254.0/23 + // In this case without prefixRangeMask, getNextSubPrefix would return 128.0.0.0, which + // means the "start < end" check in findAvailablePrefixFromRange would not reject the prefix + // because Java doesn't have unsigned integers, so 128.0.0.0 = 0x80000000 = -2147483648 + // is less than 127.0.0.0 = 0x7f000000 = 2130706432. + // + // Additionally, it makes debug output easier to read by making the numbers smaller. + final int randomPrefixStart = getRandomInt() & ~prefixRangeMask & prefixMask; + + // A random offset within the prefix. Used to determine the local address once the prefix + // is selected. It does not result in an IPv4 address ending in .0, .1, or .255 + // For a PREFIX_LENGTH of 255, this is a number between 2 and 254. + final int subAddress = getSanitizedSubAddr(~prefixMask); + + // Find a prefix length PREFIX_LENGTH between randomPrefixStart and the end of the block, + // such that the prefix does not conflict with any upstream. + IpPrefix downstreamPrefix = findAvailablePrefixFromRange( + randomPrefixStart, (~prefixRangeMask) + 1, baseAddress, prefixRangeMask); + if (downstreamPrefix != null) return getLinkAddress(downstreamPrefix, subAddress); + + // If that failed, do the same, but between 0 and randomPrefixStart. + downstreamPrefix = findAvailablePrefixFromRange( + 0, randomPrefixStart, baseAddress, prefixRangeMask); + + return getLinkAddress(downstreamPrefix, subAddress); + } + + private LinkAddress getLinkAddress(final IpPrefix prefix, final int subAddress) { + if (prefix == null) return null; + + final InetAddress address = intToInet4AddressHTH(getPrefixBaseAddress(prefix) | subAddress); + return new LinkAddress(address, PREFIX_LENGTH); + } + + private IpPrefix findAvailablePrefixFromRange(final int start, final int end, + final int baseAddress, final int prefixRangeMask) { + int newSubPrefix = start; + while (newSubPrefix < end) { + final InetAddress address = intToInet4AddressHTH(baseAddress | newSubPrefix); + final IpPrefix prefix = new IpPrefix(address, PREFIX_LENGTH); + + final IpPrefix conflictPrefix = getConflictPrefix(prefix); + + if (conflictPrefix == null) return prefix; + + newSubPrefix = getNextSubPrefix(conflictPrefix, prefixRangeMask); + } + + return null; + } + + /** Get random int which could be used to generate random address. */ @VisibleForTesting - public int getRandomSubAddr() { - return ((new Random()).nextInt()) & 0xffff; // subNet is in 0 ~ 0xffff. + public int getRandomInt() { + return (new Random()).nextInt(); } - private byte getSanitizedAddressSuffix(final int source, byte... excluded) { - final byte subId = (byte) (source & BYTE_MASK); - for (byte value : excluded) { - if (subId == value) return DEFAULT_ID; + /** Get random subAddress and avoid selecting x.x.x.0, x.x.x.1 and x.x.x.255 address. */ + private int getSanitizedSubAddr(final int subAddrMask) { + final int randomSubAddr = getRandomInt() & subAddrMask; + // If prefix length > 30, the selecting speace would be less than 4 which may be hard to + // avoid 3 consecutive address. + if (PREFIX_LENGTH > 30) return randomSubAddr; + + // TODO: maybe it is not necessary to avoid .0, .1 and .255 address because tethering + // address would not be conflicted. This code only works because PREFIX_LENGTH is not longer + // than 24 + final int candidate = randomSubAddr & 0xff; + if (candidate == 0 || candidate == 1 || candidate == 255) { + return (randomSubAddr & 0xfffffffc) + 2; } - return subId; + return randomSubAddr; } /** Release downstream record for IpServer. */ @@ -237,14 +336,18 @@ public class PrivateAddressCoordinator { mUpstreamPrefixMap.clear(); } - private boolean isConflictWithUpstream(final IpPrefix source) { + private IpPrefix getConflictWithUpstream(final IpPrefix prefix) { for (int i = 0; i < mUpstreamPrefixMap.size(); i++) { final List<IpPrefix> list = mUpstreamPrefixMap.valueAt(i); - for (IpPrefix target : list) { - if (isConflictPrefix(source, target)) return true; + for (IpPrefix upstream : list) { + if (isConflictPrefix(prefix, upstream)) return upstream; } } - return false; + return null; + } + + private boolean isConflictWithUpstream(final IpPrefix prefix) { + return getConflictWithUpstream(prefix) != null; } private boolean isConflictPrefix(final IpPrefix prefix1, final IpPrefix prefix2) { @@ -257,11 +360,10 @@ public class PrivateAddressCoordinator { // InUse Prefixes are prefixes of mCachedAddresses which are active downstream addresses, last // downstream addresses(reserved for next time) and static addresses(e.g. bluetooth, wifi p2p). - private boolean isDownstreamPrefixInUse(final IpPrefix prefix) { - // This class always generates downstream prefixes with the same prefix length, so - // prefixes cannot be contained in each other. They can only be equal to each other. + private IpPrefix getInUseDownstreamPrefix(final IpPrefix prefix) { for (int i = 0; i < mCachedAddresses.size(); i++) { - if (prefix.equals(asIpPrefix(mCachedAddresses.valueAt(i)))) return true; + final IpPrefix downstream = asIpPrefix(mCachedAddresses.valueAt(i)); + if (isConflictPrefix(prefix, downstream)) return downstream; } // IpServer may use manually-defined address (mStaticIpv4ServerAddr) which does not include @@ -270,10 +372,10 @@ public class PrivateAddressCoordinator { final IpPrefix target = getDownstreamPrefix(downstream); if (target == null) continue; - if (isConflictPrefix(prefix, target)) return true; + if (isConflictPrefix(prefix, target)) return target; } - return false; + return null; } private IpPrefix getDownstreamPrefix(final IpServer downstream) { @@ -284,6 +386,13 @@ public class PrivateAddressCoordinator { } void dump(final IndentingPrintWriter pw) { + pw.println("mTetheringPrefixes:"); + pw.increaseIndent(); + for (IpPrefix prefix : mTetheringPrefixes) { + pw.println(prefix); + } + pw.decreaseIndent(); + pw.println("mUpstreamPrefixMap:"); pw.increaseIndent(); for (int i = 0; i < mUpstreamPrefixMap.size(); i++) { diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java index 474f4e8b603a..5a0c5b0cff5f 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java @@ -326,7 +326,7 @@ public class Tethering { // It is OK for the configuration to be passed to the PrivateAddressCoordinator at // construction time because the only part of the configuration it uses is // shouldEnableWifiP2pDedicatedIp(), and currently do not support changing that. - mPrivateAddressCoordinator = new PrivateAddressCoordinator(mContext, mConfig); + mPrivateAddressCoordinator = mDeps.getPrivateAddressCoordinator(mContext, mConfig); // Must be initialized after tethering configuration is loaded because BpfCoordinator // constructor needs to use the configuration. diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java index 131a5fbf2abe..45b914178e97 100644 --- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java +++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringDependencies.java @@ -156,4 +156,12 @@ public abstract class TetheringDependencies { public boolean isTetheringDenied() { return TextUtils.equals(SystemProperties.get("ro.tether.denied"), "true"); } + + /** + * Get a reference to PrivateAddressCoordinator to be used by Tethering. + */ + public PrivateAddressCoordinator getPrivateAddressCoordinator(Context ctx, + TetheringConfiguration cfg) { + return new PrivateAddressCoordinator(ctx, cfg); + } } diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java index 191eb6e71149..da13e341fb54 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/PrivateAddressCoordinatorTest.java @@ -51,6 +51,9 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.ArrayList; +import java.util.Arrays; + @RunWith(AndroidJUnit4.class) @SmallTest public final class PrivateAddressCoordinatorTest { @@ -70,7 +73,17 @@ public final class PrivateAddressCoordinatorTest { private final Network mWifiNetwork = new Network(1); private final Network mMobileNetwork = new Network(2); private final Network mVpnNetwork = new Network(3); - private final Network[] mAllNetworks = {mMobileNetwork, mWifiNetwork, mVpnNetwork}; + private final Network mMobileNetwork2 = new Network(4); + private final Network mMobileNetwork3 = new Network(5); + private final Network mMobileNetwork4 = new Network(6); + private final Network mMobileNetwork5 = new Network(7); + private final Network mMobileNetwork6 = new Network(8); + private final Network[] mAllNetworks = {mMobileNetwork, mWifiNetwork, mVpnNetwork, + mMobileNetwork2, mMobileNetwork3, mMobileNetwork4, mMobileNetwork5, mMobileNetwork6}; + private final ArrayList<IpPrefix> mTetheringPrefixes = new ArrayList<>(Arrays.asList( + new IpPrefix("192.168.0.0/16"), + new IpPrefix("172.16.0.0/12"), + new IpPrefix("10.0.0.0/8"))); private void setUpIpServers() throws Exception { when(mUsbIpServer.interfaceType()).thenReturn(TETHERING_USB); @@ -87,7 +100,8 @@ public final class PrivateAddressCoordinatorTest { when(mConnectivityMgr.getAllNetworks()).thenReturn(mAllNetworks); when(mConfig.shouldEnableWifiP2pDedicatedIp()).thenReturn(false); setUpIpServers(); - mPrivateAddressCoordinator = spy(new PrivateAddressCoordinator(mContext, mConfig)); + mPrivateAddressCoordinator = spy(new PrivateAddressCoordinator(mContext, mConfig, + mTetheringPrefixes)); } @Test @@ -117,28 +131,28 @@ public final class PrivateAddressCoordinatorTest { @Test public void testSanitizedAddress() throws Exception { int fakeSubAddr = 0x2b00; // 43.0. - when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeSubAddr); + when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(fakeSubAddr); LinkAddress actualAddress = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer, false /* useLastAddress */); - assertEquals(new LinkAddress("192.168.43.42/24"), actualAddress); + assertEquals(new LinkAddress("192.168.43.2/24"), actualAddress); mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); fakeSubAddr = 0x2d01; // 45.1. - when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeSubAddr); + when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(fakeSubAddr); actualAddress = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer, false /* useLastAddress */); - assertEquals(new LinkAddress("192.168.45.42/24"), actualAddress); + assertEquals(new LinkAddress("192.168.45.2/24"), actualAddress); mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); fakeSubAddr = 0x2eff; // 46.255. - when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeSubAddr); + when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(fakeSubAddr); actualAddress = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer, false /* useLastAddress */); - assertEquals(new LinkAddress("192.168.46.42/24"), actualAddress); + assertEquals(new LinkAddress("192.168.46.254/24"), actualAddress); mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); fakeSubAddr = 0x2f05; // 47.5. - when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeSubAddr); + when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(fakeSubAddr); actualAddress = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer, false /* useLastAddress */); assertEquals(new LinkAddress("192.168.47.5/24"), actualAddress); @@ -148,7 +162,7 @@ public final class PrivateAddressCoordinatorTest { @Test public void testReservedPrefix() throws Exception { // - Test bluetooth prefix is reserved. - when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn( + when(mPrivateAddressCoordinator.getRandomInt()).thenReturn( getSubAddress(mBluetoothAddress.getAddress().getAddress())); final LinkAddress hotspotAddress = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer, false /* useLastAddress */); @@ -157,7 +171,7 @@ public final class PrivateAddressCoordinatorTest { mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); // - Test previous enabled hotspot prefix(cached prefix) is reserved. - when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn( + when(mPrivateAddressCoordinator.getRandomInt()).thenReturn( getSubAddress(hotspotAddress.getAddress().getAddress())); final LinkAddress usbAddress = mPrivateAddressCoordinator.requestDownstreamAddress( mUsbIpServer, false /* useLastAddress */); @@ -167,7 +181,7 @@ public final class PrivateAddressCoordinatorTest { mPrivateAddressCoordinator.releaseDownstream(mUsbIpServer); // - Test wifi p2p prefix is reserved. - when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn( + when(mPrivateAddressCoordinator.getRandomInt()).thenReturn( getSubAddress(mLegacyWifiP2pAddress.getAddress().getAddress())); final LinkAddress etherAddress = mPrivateAddressCoordinator.requestDownstreamAddress( mEthernetIpServer, false /* useLastAddress */); @@ -180,23 +194,22 @@ public final class PrivateAddressCoordinatorTest { @Test public void testRequestLastDownstreamAddress() throws Exception { - final int fakeHotspotSubAddr = 0x2b05; - final IpPrefix predefinedPrefix = new IpPrefix("192.168.43.0/24"); - when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeHotspotSubAddr); + final int fakeHotspotSubAddr = 0x2b05; // 43.5 + when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(fakeHotspotSubAddr); final LinkAddress hotspotAddress = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer, true /* useLastAddress */); - assertEquals("Wrong wifi prefix: ", predefinedPrefix, asIpPrefix(hotspotAddress)); + assertEquals("Wrong wifi prefix: ", new LinkAddress("192.168.43.5/24"), hotspotAddress); when(mHotspotIpServer.getAddress()).thenReturn(hotspotAddress); final LinkAddress usbAddress = mPrivateAddressCoordinator.requestDownstreamAddress( mUsbIpServer, true /* useLastAddress */); - assertNotEquals(predefinedPrefix, asIpPrefix(usbAddress)); + assertEquals("Wrong wifi prefix: ", new LinkAddress("192.168.45.5/24"), usbAddress); mPrivateAddressCoordinator.releaseDownstream(mHotspotIpServer); mPrivateAddressCoordinator.releaseDownstream(mUsbIpServer); final int newFakeSubAddr = 0x3c05; - when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeHotspotSubAddr); + when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(fakeHotspotSubAddr); final LinkAddress newHotspotAddress = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer, true /* useLastAddress */); @@ -204,6 +217,18 @@ public final class PrivateAddressCoordinatorTest { final LinkAddress newUsbAddress = mPrivateAddressCoordinator.requestDownstreamAddress( mUsbIpServer, true /* useLastAddress */); assertEquals(usbAddress, newUsbAddress); + + // BUG: the code should detect a conflict, but it doesn't. + // Regression introduced in r.android.com/168169687. + // Ensure conflict notification works when using cached address. + when(mHotspotIpServer.getAddress()).thenReturn(newHotspotAddress); + when(mUsbIpServer.getAddress()).thenReturn(usbAddress); + final UpstreamNetworkState wifiUpstream = buildUpstreamNetworkState(mWifiNetwork, + new LinkAddress("192.168.88.23/16"), null, + makeNetworkCapabilities(TRANSPORT_WIFI)); + mPrivateAddressCoordinator.updateUpstreamPrefix(wifiUpstream); + verify(mHotspotIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); + verify(mUsbIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); } private UpstreamNetworkState buildUpstreamNetworkState(final Network network, @@ -229,11 +254,10 @@ public final class PrivateAddressCoordinatorTest { @Test public void testNoConflictUpstreamPrefix() throws Exception { - final int fakeHotspotSubId = 43; - final int fakeHotspotSubAddr = 0x2b05; + final int fakeHotspotSubAddr = 0x2b05; // 43.5 final IpPrefix predefinedPrefix = new IpPrefix("192.168.43.0/24"); // Force always get subAddress "43.5" for conflict testing. - when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn(fakeHotspotSubAddr); + when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(fakeHotspotSubAddr); // - Enable hotspot with prefix 192.168.43.0/24 final LinkAddress hotspotAddr = mPrivateAddressCoordinator.requestDownstreamAddress( mHotspotIpServer, true /* useLastAddress */); @@ -312,6 +336,209 @@ public final class PrivateAddressCoordinatorTest { assertEquals(predefinedPrefix, ethPrefix); } + @Test + public void testChooseAvailablePrefix() throws Exception { + final int randomAddress = 0x8605; // 134.5 + when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(randomAddress); + final LinkAddress addr0 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + // Check whether return address is prefix 192.168.0.0/16 + subAddress 0.0.134.5. + assertEquals("Wrong prefix: ", new LinkAddress("192.168.134.5/24"), addr0); + when(mHotspotIpServer.getAddress()).thenReturn(addr0); + final UpstreamNetworkState wifiUpstream = buildUpstreamNetworkState(mWifiNetwork, + new LinkAddress("192.168.134.13/26"), null, + makeNetworkCapabilities(TRANSPORT_WIFI)); + mPrivateAddressCoordinator.updateUpstreamPrefix(wifiUpstream); + + // Check whether return address is next prefix of 192.168.134.0/24. + final LinkAddress addr1 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("192.168.135.5/24"), addr1); + when(mHotspotIpServer.getAddress()).thenReturn(addr1); + final UpstreamNetworkState wifiUpstream2 = buildUpstreamNetworkState(mWifiNetwork, + new LinkAddress("192.168.149.16/19"), null, + makeNetworkCapabilities(TRANSPORT_WIFI)); + mPrivateAddressCoordinator.updateUpstreamPrefix(wifiUpstream2); + + + // The conflict range is 128 ~ 159, so the address is 192.168.160.5/24. + final LinkAddress addr2 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("192.168.160.5/24"), addr2); + when(mHotspotIpServer.getAddress()).thenReturn(addr2); + final UpstreamNetworkState mobileUpstream = buildUpstreamNetworkState(mMobileNetwork, + new LinkAddress("192.168.129.53/18"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + // Update another conflict upstream which is covered by the previous one (but not the first + // one) and verify whether this would affect the result. + final UpstreamNetworkState mobileUpstream2 = buildUpstreamNetworkState(mMobileNetwork2, + new LinkAddress("192.168.170.7/19"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(mobileUpstream); + mPrivateAddressCoordinator.updateUpstreamPrefix(mobileUpstream2); + + // The conflict range are 128 ~ 159 and 159 ~ 191, so the address is 192.168.192.5/24. + final LinkAddress addr3 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("192.168.192.5/24"), addr3); + when(mHotspotIpServer.getAddress()).thenReturn(addr3); + final UpstreamNetworkState mobileUpstream3 = buildUpstreamNetworkState(mMobileNetwork3, + new LinkAddress("192.168.188.133/17"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(mobileUpstream3); + + // Conflict range: 128 ~ 255. The next available address is 192.168.0.5 because + // 192.168.134/24 ~ 192.168.255.255/24 is not available. + final LinkAddress addr4 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("192.168.0.5/24"), addr4); + when(mHotspotIpServer.getAddress()).thenReturn(addr4); + final UpstreamNetworkState mobileUpstream4 = buildUpstreamNetworkState(mMobileNetwork4, + new LinkAddress("192.168.3.59/21"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(mobileUpstream4); + + // Conflict ranges: 128 ~ 255 and 0 ~ 7, so the address is 192.168.8.5/24. + final LinkAddress addr5 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("192.168.8.5/24"), addr5); + when(mHotspotIpServer.getAddress()).thenReturn(addr5); + final UpstreamNetworkState mobileUpstream5 = buildUpstreamNetworkState(mMobileNetwork5, + new LinkAddress("192.168.68.43/21"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(mobileUpstream5); + + // Update an upstream that does *not* conflict, check whether return the same address + // 192.168.5/24. + final LinkAddress addr6 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("192.168.8.5/24"), addr6); + when(mHotspotIpServer.getAddress()).thenReturn(addr6); + final UpstreamNetworkState mobileUpstream6 = buildUpstreamNetworkState(mMobileNetwork6, + new LinkAddress("192.168.10.97/21"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(mobileUpstream6); + + // Conflict ranges: 0 ~ 15 and 128 ~ 255, so the address is 192.168.16.5/24. + final LinkAddress addr7 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("192.168.16.5/24"), addr7); + when(mHotspotIpServer.getAddress()).thenReturn(addr7); + final UpstreamNetworkState mobileUpstream7 = buildUpstreamNetworkState(mMobileNetwork6, + new LinkAddress("192.168.0.0/17"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(mobileUpstream7); + + // Choose prefix from next range(172.16.0.0/12) when no available prefix in 192.168.0.0/16. + final LinkAddress addr8 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("172.16.134.5/24"), addr8); + when(mHotspotIpServer.getAddress()).thenReturn(addr6); + } + + @Test + public void testChoosePrefixFromDifferentRanges() throws Exception { + final int randomAddress = 0x1f2b2a; // 31.43.42 + when(mPrivateAddressCoordinator.getRandomInt()).thenReturn(randomAddress); + final LinkAddress classC1 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + // Check whether return address is prefix 192.168.0.0/16 + subAddress 0.0.43.42. + assertEquals("Wrong prefix: ", new LinkAddress("192.168.43.42/24"), classC1); + when(mHotspotIpServer.getAddress()).thenReturn(classC1); + final UpstreamNetworkState wifiUpstream = buildUpstreamNetworkState(mWifiNetwork, + new LinkAddress("192.168.88.23/17"), null, + makeNetworkCapabilities(TRANSPORT_WIFI)); + mPrivateAddressCoordinator.updateUpstreamPrefix(wifiUpstream); + verifyNotifyConflictAndRelease(mHotspotIpServer); + + // Check whether return address is next address of prefix 192.168.128.0/17. + final LinkAddress classC2 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("192.168.128.42/24"), classC2); + when(mHotspotIpServer.getAddress()).thenReturn(classC2); + final UpstreamNetworkState mobileUpstream = buildUpstreamNetworkState(mMobileNetwork, + new LinkAddress("192.1.2.3/8"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(mobileUpstream); + verifyNotifyConflictAndRelease(mHotspotIpServer); + + // Check whether return address is under prefix 172.16.0.0/12. + final LinkAddress classB1 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("172.31.43.42/24"), classB1); + when(mHotspotIpServer.getAddress()).thenReturn(classB1); + final UpstreamNetworkState mobileUpstream2 = buildUpstreamNetworkState(mMobileNetwork2, + new LinkAddress("172.28.123.100/14"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(mobileUpstream2); + verifyNotifyConflictAndRelease(mHotspotIpServer); + + // 172.28.0.0 ~ 172.31.255.255 is not available. + // Check whether return address is next address of prefix 172.16.0.0/14. + final LinkAddress classB2 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("172.16.0.42/24"), classB2); + when(mHotspotIpServer.getAddress()).thenReturn(classB2); + + // Check whether new downstream is next address of address 172.16.0.42/24. + final LinkAddress classB3 = mPrivateAddressCoordinator.requestDownstreamAddress( + mUsbIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("172.16.1.42/24"), classB3); + when(mUsbIpServer.getAddress()).thenReturn(classB3); + final UpstreamNetworkState mobileUpstream3 = buildUpstreamNetworkState(mMobileNetwork3, + new LinkAddress("172.16.0.1/24"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(mobileUpstream3); + verifyNotifyConflictAndRelease(mHotspotIpServer); + verify(mUsbIpServer, never()).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); + + // Check whether return address is next address of prefix 172.16.1.42/24. + final LinkAddress classB4 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("172.16.2.42/24"), classB4); + when(mHotspotIpServer.getAddress()).thenReturn(classB4); + final UpstreamNetworkState mobileUpstream4 = buildUpstreamNetworkState(mMobileNetwork4, + new LinkAddress("172.16.0.1/13"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(mobileUpstream4); + verifyNotifyConflictAndRelease(mHotspotIpServer); + verifyNotifyConflictAndRelease(mUsbIpServer); + + // Check whether return address is next address of prefix 172.16.0.1/13. + final LinkAddress classB5 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("172.24.0.42/24"), classB5); + when(mHotspotIpServer.getAddress()).thenReturn(classB5); + // Check whether return address is next address of prefix 172.24.0.42/24. + final LinkAddress classB6 = mPrivateAddressCoordinator.requestDownstreamAddress( + mUsbIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("172.24.1.42/24"), classB6); + when(mUsbIpServer.getAddress()).thenReturn(classB6); + final UpstreamNetworkState mobileUpstream5 = buildUpstreamNetworkState(mMobileNetwork5, + new LinkAddress("172.24.0.1/12"), null, + makeNetworkCapabilities(TRANSPORT_CELLULAR)); + mPrivateAddressCoordinator.updateUpstreamPrefix(mobileUpstream5); + verifyNotifyConflictAndRelease(mHotspotIpServer); + verifyNotifyConflictAndRelease(mUsbIpServer); + + // Check whether return address is prefix 10.0.0.0/8 + subAddress 0.31.43.42. + final LinkAddress classA1 = mPrivateAddressCoordinator.requestDownstreamAddress( + mHotspotIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("10.31.43.42/24"), classA1); + when(mHotspotIpServer.getAddress()).thenReturn(classA1); + // Check whether new downstream is next address of address 10.31.43.42/24. + final LinkAddress classA2 = mPrivateAddressCoordinator.requestDownstreamAddress( + mUsbIpServer, true/* useLastAddress */); + assertEquals("Wrong prefix: ", new LinkAddress("10.31.44.42/24"), classA2); + } + + private void verifyNotifyConflictAndRelease(final IpServer ipServer) throws Exception { + verify(ipServer).sendMessage(IpServer.CMD_NOTIFY_PREFIX_CONFLICT); + mPrivateAddressCoordinator.releaseDownstream(ipServer); + reset(ipServer); + setUpIpServers(); + } + private int getSubAddress(final byte... ipv4Address) { assertEquals(4, ipv4Address.length); @@ -330,7 +557,7 @@ public final class PrivateAddressCoordinatorTest { @Test public void testEnableLegacyWifiP2PAddress() throws Exception { - when(mPrivateAddressCoordinator.getRandomSubAddr()).thenReturn( + when(mPrivateAddressCoordinator.getRandomInt()).thenReturn( getSubAddress(mLegacyWifiP2pAddress.getAddress().getAddress())); // No matter #shouldEnableWifiP2pDedicatedIp() is enabled or not, legacy wifi p2p prefix // is resevered. diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java index df570206e389..20e94b256ad1 100644 --- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java +++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java @@ -24,6 +24,9 @@ import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS; import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED; import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED; +import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.RouteInfo.RTN_UNICAST; import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED; import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY; @@ -179,6 +182,7 @@ public class TetheringTest { private static final String TEST_P2P_IFNAME = "test_p2p-p2p0-0"; private static final String TEST_NCM_IFNAME = "test_ncm0"; private static final String TEST_ETH_IFNAME = "test_eth0"; + private static final String TEST_BT_IFNAME = "test_pan0"; private static final String TETHERING_NAME = "Tethering"; private static final String[] PROVISIONING_APP_NAME = {"some", "app"}; private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app"; @@ -230,6 +234,7 @@ public class TetheringTest { private TetheringConfiguration mConfig; private EntitlementManager mEntitleMgr; private OffloadController mOffloadCtrl; + private PrivateAddressCoordinator mPrivateAddressCoordinator; private class TestContext extends BroadcastInterceptingContext { TestContext(Context base) { @@ -446,6 +451,18 @@ public class TetheringTest { public boolean isTetheringDenied() { return false; } + + + @Override + public PrivateAddressCoordinator getPrivateAddressCoordinator(Context ctx, + TetheringConfiguration cfg) { + final ArrayList<IpPrefix> prefixPool = new ArrayList<>(Arrays.asList( + new IpPrefix("192.168.0.0/16"), + new IpPrefix("172.16.0.0/12"), + new IpPrefix("10.0.0.0/8"))); + mPrivateAddressCoordinator = spy(new PrivateAddressCoordinator(ctx, cfg, prefixPool)); + return mPrivateAddressCoordinator; + } } private static UpstreamNetworkState buildMobileUpstreamState(boolean withIPv4, @@ -1875,27 +1892,36 @@ public class TetheringTest { sendConfigurationChanged(); } - private static UpstreamNetworkState buildV4WifiUpstreamState(final String ipv4Address, - final int prefixLength, final Network network) { + private static UpstreamNetworkState buildV4UpstreamState(final LinkAddress address, + final Network network, final String iface, final int transportType) { final LinkProperties prop = new LinkProperties(); - prop.setInterfaceName(TEST_WIFI_IFNAME); + prop.setInterfaceName(iface); - prop.addLinkAddress( - new LinkAddress(InetAddresses.parseNumericAddress(ipv4Address), - prefixLength)); + prop.addLinkAddress(address); final NetworkCapabilities capabilities = new NetworkCapabilities() - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI); + .addTransportType(transportType); return new UpstreamNetworkState(prop, capabilities, network); } + private void updateV4Upstream(final LinkAddress ipv4Address, final Network network, + final String iface, final int transportType) { + final UpstreamNetworkState upstream = buildV4UpstreamState(ipv4Address, network, iface, + transportType); + mTetheringDependencies.mUpstreamNetworkMonitorSM.sendMessage( + Tethering.TetherMainSM.EVENT_UPSTREAM_CALLBACK, + UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES, + 0, + upstream); + mLooper.dispatchAll(); + } + @Test public void testHandleIpConflict() throws Exception { final Network wifiNetwork = new Network(200); final Network[] allNetworks = { wifiNetwork }; when(mCm.getAllNetworks()).thenReturn(allNetworks); - UpstreamNetworkState upstreamNetwork = null; - runUsbTethering(upstreamNetwork); + runUsbTethering(null); final ArgumentCaptor<InterfaceConfigurationParcel> ifaceConfigCaptor = ArgumentCaptor.forClass(InterfaceConfigurationParcel.class); verify(mNetd).interfaceSetCfg(ifaceConfigCaptor.capture()); @@ -1903,13 +1929,10 @@ public class TetheringTest { verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( any(), any()); reset(mNetd, mUsbManager); - upstreamNetwork = buildV4WifiUpstreamState(ipv4Address, 30, wifiNetwork); - mTetheringDependencies.mUpstreamNetworkMonitorSM.sendMessage( - Tethering.TetherMainSM.EVENT_UPSTREAM_CALLBACK, - UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES, - 0, - upstreamNetwork); - mLooper.dispatchAll(); + + // Cause a prefix conflict by assigning a /30 out of the downstream's /24 to the upstream. + updateV4Upstream(new LinkAddress(InetAddresses.parseNumericAddress(ipv4Address), 30), + wifiNetwork, TEST_WIFI_IFNAME, TRANSPORT_WIFI); // verify turn off usb tethering verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE); mTethering.interfaceRemoved(TEST_USB_IFNAME); @@ -1921,9 +1944,10 @@ public class TetheringTest { @Test public void testNoAddressAvailable() throws Exception { final Network wifiNetwork = new Network(200); - final Network[] allNetworks = { wifiNetwork }; + final Network btNetwork = new Network(201); + final Network mobileNetwork = new Network(202); + final Network[] allNetworks = { wifiNetwork, btNetwork, mobileNetwork }; when(mCm.getAllNetworks()).thenReturn(allNetworks); - final String upstreamAddress = "192.168.0.100"; runUsbTethering(null); verify(mDhcpServer, timeout(DHCPSERVER_START_TIMEOUT_MS).times(1)).startWithCallbacks( any(), any()); @@ -1940,13 +1964,13 @@ public class TetheringTest { mLooper.dispatchAll(); reset(mUsbManager, mEm); - final UpstreamNetworkState upstreamNetwork = buildV4WifiUpstreamState( - upstreamAddress, 16, wifiNetwork); - mTetheringDependencies.mUpstreamNetworkMonitorSM.sendMessage( - Tethering.TetherMainSM.EVENT_UPSTREAM_CALLBACK, - UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES, - 0, - upstreamNetwork); + updateV4Upstream(new LinkAddress("192.168.0.100/16"), wifiNetwork, TEST_WIFI_IFNAME, + TRANSPORT_WIFI); + updateV4Upstream(new LinkAddress("172.16.0.0/12"), btNetwork, TEST_BT_IFNAME, + TRANSPORT_BLUETOOTH); + updateV4Upstream(new LinkAddress("10.0.0.0/8"), mobileNetwork, TEST_MOBILE_IFNAME, + TRANSPORT_CELLULAR); + mLooper.dispatchAll(); // verify turn off usb tethering verify(mUsbManager).setCurrentFunctions(UsbManager.FUNCTION_NONE); diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 6c7f235dec6f..d3abe871b80e 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -1608,7 +1608,7 @@ public class Vpn { */ public synchronized void onUserStopped() { // Switch off networking lockdown (if it was enabled) - setLockdown(false); + setVpnForcedLocked(false); mAlwaysOn = false; // Quit any active connections diff --git a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java index ec56e1ebc8e0..bd37e587aee7 100644 --- a/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java +++ b/services/robotests/backup/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java @@ -41,6 +41,7 @@ import static com.android.server.backup.testing.Utils.oneTimeIterable; import static com.android.server.backup.testing.Utils.transferStreamedData; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -2814,8 +2815,8 @@ public class KeyValueBackupTaskTest { } private static IterableSubject assertDirectory(Path directory) throws IOException { - return assertThat(oneTimeIterable(Files.newDirectoryStream(directory).iterator())) - .named("directory " + directory); + return assertWithMessage("directory " + directory).that( + oneTimeIterable(Files.newDirectoryStream(directory).iterator())); } private static void assertJournalDoesNotContain( diff --git a/services/robotests/backup/src/com/android/server/backup/testing/TestUtils.java b/services/robotests/backup/src/com/android/server/backup/testing/TestUtils.java index 3fe1f3f90f2f..3114a751d556 100644 --- a/services/robotests/backup/src/com/android/server/backup/testing/TestUtils.java +++ b/services/robotests/backup/src/com/android/server/backup/testing/TestUtils.java @@ -17,6 +17,7 @@ package com.android.server.backup.testing; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static org.robolectric.Shadows.shadowOf; @@ -95,8 +96,8 @@ public class TestUtils { * logcat before that. */ public static void assertLogcatAtMost(String tag, int level) { - assertThat(ShadowLog.getLogsForTag(tag).stream().allMatch(logItem -> logItem.type <= level)) - .named("All logs <= " + level) + assertWithMessage("All logs <= " + level).that( + ShadowLog.getLogsForTag(tag).stream().allMatch(logItem -> logItem.type <= level)) .isTrue(); } @@ -105,8 +106,8 @@ public class TestUtils { * logcat before that. */ public static void assertLogcatAtLeast(String tag, int level) { - assertThat(ShadowLog.getLogsForTag(tag).stream().anyMatch(logItem -> logItem.type >= level)) - .named("Any log >= " + level) + assertWithMessage("Any log >= " + level).that( + ShadowLog.getLogsForTag(tag).stream().anyMatch(logItem -> logItem.type >= level)) .isTrue(); } @@ -121,11 +122,10 @@ public class TestUtils { * that uses logcat before that. */ public static void assertLogcat(String tag, int... logs) { - assertThat( + assertWithMessage("Log items (specified per level)").that( ShadowLog.getLogsForTag(tag).stream() .map(logItem -> logItem.type) .collect(toSet())) - .named("Log items (specified per level)") .containsExactly(IntStream.of(logs).boxed().toArray()); } @@ -135,15 +135,13 @@ public class TestUtils { /** Declare shadow {@link ShadowEventLog} to use this. */ public static void assertEventLogged(int tag, Object... values) { - assertThat(ShadowEventLog.getEntries()) - .named("Event logs") + assertWithMessage("Event logs").that(ShadowEventLog.getEntries()) .contains(new ShadowEventLog.Entry(tag, Arrays.asList(values))); } /** Declare shadow {@link ShadowEventLog} to use this. */ public static void assertEventNotLogged(int tag, Object... values) { - assertThat(ShadowEventLog.getEntries()) - .named("Event logs") + assertWithMessage("Event logs").that(ShadowEventLog.getEntries()) .doesNotContain(new ShadowEventLog.Entry(tag, Arrays.asList(values))); } diff --git a/services/tests/mockingservicestests/src/com/android/server/location/LocationFudgerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/LocationFudgerTest.java index a0f48c674316..d67edddb30e6 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/LocationFudgerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/LocationFudgerTest.java @@ -79,7 +79,7 @@ public class LocationFudgerTest { Location coarse = mFudger.createCoarse(fine); assertThat(coarse).isNotNull(); - assertThat(coarse).isNotSameAs(fine); + assertThat(coarse).isNotSameInstanceAs(fine); assertThat(coarse.hasBearing()).isFalse(); assertThat(coarse.hasSpeed()).isFalse(); assertThat(coarse.hasAltitude()).isFalse(); diff --git a/services/tests/servicestests/src/com/android/server/integrity/IntegrityFileManagerTest.java b/services/tests/servicestests/src/com/android/server/integrity/IntegrityFileManagerTest.java index 41be54ab5b7a..f26e0941e008 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/IntegrityFileManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/IntegrityFileManagerTest.java @@ -194,7 +194,7 @@ public class IntegrityFileManagerTest { assertThat(rulesFetched.size()) .isEqualTo(INDEXING_BLOCK_SIZE * 2 + unindexedRuleCount); assertThat(rulesFetched) - .containsAllOf( + .containsAtLeast( getPackageNameIndexedRule(installedPackageName), getAppCertificateIndexedRule(installedAppCertificate)); } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/TestOnlyInsecureCertificateHelperTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/TestOnlyInsecureCertificateHelperTest.java index 6921bb27ceb2..8d5687c33419 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/TestOnlyInsecureCertificateHelperTest.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/TestOnlyInsecureCertificateHelperTest.java @@ -71,7 +71,7 @@ public class TestOnlyInsecureCertificateHelperTest { Map<String, Pair<SecretKey, byte[]>> filteredKeys = mHelper.keepOnlyWhitelistedInsecureKeys(rawKeys); assertThat(filteredKeys.entrySet()).containsExactlyElementsIn(expectedResult.entrySet()); - assertThat(filteredKeys.entrySet()).containsAllIn(rawKeys.entrySet()); + assertThat(filteredKeys.entrySet()).containsAtLeastElementsIn(rawKeys.entrySet()); } @Test @@ -85,7 +85,7 @@ public class TestOnlyInsecureCertificateHelperTest { Map<String, Pair<SecretKey, byte[]>> filteredKeys = mHelper.keepOnlyWhitelistedInsecureKeys(rawKeys); assertThat(filteredKeys.entrySet()).containsExactlyElementsIn(expectedResult.entrySet()); - assertThat(rawKeys.entrySet()).containsAllIn(filteredKeys.entrySet()); + assertThat(rawKeys.entrySet()).containsAtLeastElementsIn(filteredKeys.entrySet()); } @Test @@ -100,7 +100,7 @@ public class TestOnlyInsecureCertificateHelperTest { Map<String, Pair<SecretKey, byte[]>> filteredKeys = mHelper.keepOnlyWhitelistedInsecureKeys(rawKeys); assertThat(filteredKeys.entrySet()).containsExactlyElementsIn(expectedResult.entrySet()); - assertThat(rawKeys.entrySet()).containsAllIn(filteredKeys.entrySet()); + assertThat(rawKeys.entrySet()).containsAtLeastElementsIn(filteredKeys.entrySet()); } @Test @@ -122,7 +122,7 @@ public class TestOnlyInsecureCertificateHelperTest { Map<String, Pair<SecretKey, byte[]>> filteredKeys = mHelper.keepOnlyWhitelistedInsecureKeys(rawKeys); assertThat(filteredKeys.entrySet()).containsExactlyElementsIn(expectedResult.entrySet()); - assertThat(rawKeys.entrySet()).containsAllIn(filteredKeys.entrySet()); + assertThat(rawKeys.entrySet()).containsAtLeastElementsIn(filteredKeys.entrySet()); } @Test diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/certificate/CertXmlTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/certificate/CertXmlTest.java index 9836c64ea5b5..b0cb2ea85bf4 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/certificate/CertXmlTest.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/certificate/CertXmlTest.java @@ -70,7 +70,7 @@ public final class CertXmlTest { CertXml certXml = CertXml.parse(certXmlBytes); List<X509Certificate> endpointCerts = certXml.getAllEndpointCerts(); assertThat(endpointCerts).hasSize(3); - assertThat(endpointCerts).containsAllOf(TestData.LEAF_CERT_1, TestData.LEAF_CERT_2); + assertThat(endpointCerts).containsAtLeast(TestData.LEAF_CERT_1, TestData.LEAF_CERT_2); } @Test diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java index 44bb58f62253..22b07157e94e 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java @@ -639,7 +639,7 @@ public final class UserManagerTest { UserInfo user1 = createUser("User 1", 0); UserInfo user2 = createUser("User 2", 0); long[] serialNumbersOfUsers = mUserManager.getSerialNumbersOfUsers(false); - assertThat(serialNumbersOfUsers).asList().containsAllOf( + assertThat(serialNumbersOfUsers).asList().containsAtLeast( (long) user1.serialNumber, (long) user2.serialNumber); } diff --git a/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java b/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java index 102d5bb373c8..cc32d5c5a292 100644 --- a/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java +++ b/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java @@ -48,41 +48,25 @@ public class RollbackStoreTest { private static final String INSTALLER = "some.installer"; private static final Correspondence<VersionedPackage, VersionedPackage> VER_PKG_CORR = - new Correspondence<VersionedPackage, VersionedPackage>() { - @Override - public boolean compare(VersionedPackage a, VersionedPackage b) { - if (a == null || b == null) { - return a == b; - } - return a.equals(b); + Correspondence.from((VersionedPackage a, VersionedPackage b) -> { + if (a == null || b == null) { + return a == b; } - - @Override - public String toString() { - return "is the same as"; - } - }; + return a.equals(b); + }, "is the same as"); private static final Correspondence<PackageRollbackInfo.RestoreInfo, PackageRollbackInfo.RestoreInfo> RESTORE_INFO_CORR = - new Correspondence<PackageRollbackInfo.RestoreInfo, PackageRollbackInfo.RestoreInfo>() { - @Override - public boolean compare(PackageRollbackInfo.RestoreInfo a, - PackageRollbackInfo.RestoreInfo b) { - if (a == null || b == null) { - return a == b; - } - return a.userId == b.userId - && a.appId == b.appId - && Objects.equals(a.seInfo, b.seInfo); - } - - @Override - public String toString() { - return "is the same as"; + Correspondence.from((PackageRollbackInfo.RestoreInfo a, + PackageRollbackInfo.RestoreInfo b) -> { + if (a == null || b == null) { + return a == b; } - }; + return a.userId == b.userId + && a.appId == b.appId + && Objects.equals(a.seInfo, b.seInfo); + }, "is the same as"); private static final String JSON_ROLLBACK_NO_EXT = "{'info':{'rollbackId':123,'packages':" + "[{'versionRolledBackFrom':{'packageName':'blah','longVersionCode':55}," diff --git a/services/tests/servicestests/src/com/android/server/storage/DiskStatsFileLoggerTest.java b/services/tests/servicestests/src/com/android/server/storage/DiskStatsFileLoggerTest.java index 46224cb8f855..8fb2e6838412 100644 --- a/services/tests/servicestests/src/com/android/server/storage/DiskStatsFileLoggerTest.java +++ b/services/tests/servicestests/src/com/android/server/storage/DiskStatsFileLoggerTest.java @@ -132,7 +132,7 @@ public class DiskStatsFileLoggerTest extends AndroidTestCase { appSizes.getLong(i), cacheSizes.getLong(i)); apps.add(app); } - assertThat(apps).containsAllOf(new AppSizeGrouping("com.test.app", 1100, 20), + assertThat(apps).containsAtLeast(new AppSizeGrouping("com.test.app", 1100, 20), new AppSizeGrouping("com.test.app2", 11, 2)); } diff --git a/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java index f9343236662b..2372dd25cb56 100644 --- a/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java @@ -81,9 +81,7 @@ public class TunerResourceManagerServiceTest { // A correspondence to compare a FrontendResource and a TunerFrontendInfo. private static final Correspondence<FrontendResource, TunerFrontendInfo> FR_TFI_COMPARE = - new Correspondence<FrontendResource, TunerFrontendInfo>() { - @Override - public boolean compare(FrontendResource actual, TunerFrontendInfo expected) { + Correspondence.from((FrontendResource actual, TunerFrontendInfo expected) -> { if (actual == null || expected == null) { return (actual == null) && (expected == null); } @@ -91,13 +89,7 @@ public class TunerResourceManagerServiceTest { return actual.getId() == expected.getId() && actual.getType() == expected.getFrontendType() && actual.getExclusiveGroupId() == expected.getExclusiveGroupId(); - } - - @Override - public String toString() { - return "is correctly configured from "; - } - }; + }, "is correctly configured from "); @Before public void setUp() throws Exception { diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java index eca71b69ec0b..e5ae2d3f63ab 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java @@ -305,6 +305,7 @@ public class ShortcutHelperTest extends UiServiceTestCase { //when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(), // anyString(), anyInt(), any())).thenReturn(true); - assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isSameAs(si); + assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)) + .isSameInstanceAs(si); } } diff --git a/services/usb/java/com/android/server/usb/MtpNotificationManager.java b/services/usb/java/com/android/server/usb/MtpNotificationManager.java index 462ee19124ff..39f2f296a305 100644 --- a/services/usb/java/com/android/server/usb/MtpNotificationManager.java +++ b/services/usb/java/com/android/server/usb/MtpNotificationManager.java @@ -64,12 +64,13 @@ class MtpNotificationManager { private final Context mContext; private final OnOpenInAppListener mListener; + private final Receiver mReceiver; MtpNotificationManager(Context context, OnOpenInAppListener listener) { mContext = context; mListener = listener; - final Receiver receiver = new Receiver(); - context.registerReceiver(receiver, new IntentFilter(ACTION_OPEN_IN_APPS)); + mReceiver = new Receiver(); + context.registerReceiver(mReceiver, new IntentFilter(ACTION_OPEN_IN_APPS)); } void showNotification(UsbDevice device) { @@ -154,4 +155,8 @@ class MtpNotificationManager { static interface OnOpenInAppListener { void onOpenInApp(UsbDevice device); } + + public void unregister() { + mContext.unregisterReceiver(mReceiver); + } } diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java index d7b6b5d0d36a..26ee03c25013 100644 --- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java +++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java @@ -261,6 +261,15 @@ class UsbProfileGroupSettingsManager { } /** + * Unregister all broadcast receivers. Must be called explicitly before + * object deletion. + */ + public void unregisterReceivers() { + mPackageMonitor.unregister(); + mMtpNotificationManager.unregister(); + } + + /** * Remove all defaults and denied packages for a user. * * @param userToRemove The user diff --git a/services/usb/java/com/android/server/usb/UsbSettingsManager.java b/services/usb/java/com/android/server/usb/UsbSettingsManager.java index 7b677eea6b8f..8e53ff412f0a 100644 --- a/services/usb/java/com/android/server/usb/UsbSettingsManager.java +++ b/services/usb/java/com/android/server/usb/UsbSettingsManager.java @@ -124,6 +124,7 @@ class UsbSettingsManager { if (mSettingsByProfileGroup.indexOfKey(userToRemove.getIdentifier()) >= 0) { // The user to remove is the parent user of the group. The parent is the last user // that gets removed. All state will be removed with the user + mSettingsByProfileGroup.get(userToRemove.getIdentifier()).unregisterReceivers(); mSettingsByProfileGroup.remove(userToRemove.getIdentifier()); } else { // We cannot find the parent user of the user that is removed, hence try to remove diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt index 8fa0cde0f9cc..150577a21f5a 100644 --- a/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt +++ b/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt @@ -124,7 +124,7 @@ class ParcelablesTest<T : Parcelable>(private val inputData: InputData<T>) { data class InputData<T : Parcelable>(val valid: T, val validCopy: T, val validOther: T) { val kls = valid.javaClass init { - assertThat(valid).isNotSameAs(validCopy) + assertThat(valid).isNotSameInstanceAs(validCopy) // Don't use isInstanceOf because of phantom warnings in intellij about Class! assertThat(validCopy.javaClass).isEqualTo(valid.javaClass) assertThat(validOther.javaClass).isEqualTo(valid.javaClass) diff --git a/telecomm/java/android/telecom/CallerInfo.java b/telecomm/java/android/telecom/CallerInfo.java index fb6f99405759..aff2f0183a3b 100644 --- a/telecomm/java/android/telecom/CallerInfo.java +++ b/telecomm/java/android/telecom/CallerInfo.java @@ -405,7 +405,8 @@ public class CallerInfo { // Change the callerInfo number ONLY if it is an emergency number // or if it is the voicemail number. If it is either, take a // shortcut and skip the query. - if (PhoneNumberUtils.isLocalEmergencyNumber(context, number)) { + TelephonyManager tm = context.getSystemService(TelephonyManager.class); + if (tm.isEmergencyNumber(number)) { return new CallerInfo().markAsEmergency(context); } else if (PhoneNumberUtils.isVoiceMailNumber(null, subId, number)) { return new CallerInfo().markAsVoiceMail(context, subId); diff --git a/telecomm/java/android/telecom/CallerInfoAsyncQuery.java b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java index 4a81a8eea5cf..a9e1a8fc1952 100644 --- a/telecomm/java/android/telecom/CallerInfoAsyncQuery.java +++ b/telecomm/java/android/telecom/CallerInfoAsyncQuery.java @@ -34,6 +34,7 @@ import android.os.UserManager; import android.provider.ContactsContract.PhoneLookup; import android.telephony.PhoneNumberUtils; import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; import android.text.TextUtils; import java.util.ArrayList; @@ -481,7 +482,8 @@ public class CallerInfoAsyncQuery { cw.subId = subId; // check to see if these are recognized numbers, and use shortcuts if we can. - if (PhoneNumberUtils.isLocalEmergencyNumber(context, number)) { + TelephonyManager tm = context.getSystemService(TelephonyManager.class); + if (tm.isEmergencyNumber(number)) { cw.event = EVENT_EMERGENCY_NUMBER; } else if (PhoneNumberUtils.isVoiceMailNumber(context, subId, number)) { cw.event = EVENT_VOICEMAIL_NUMBER; diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt index ddc608413db8..5ad377273b90 100644 --- a/telephony/api/system-current.txt +++ b/telephony/api/system-current.txt @@ -660,7 +660,6 @@ package android.telephony { method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getDeviceSoftwareVersion(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getEmergencyNumberDbVersion(); - method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<java.lang.String> getEquivalentHomePlmns(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst(); method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.Map<java.lang.Integer,java.lang.Integer> getLogicalToPhysicalSlotMapping(); @@ -1722,7 +1721,6 @@ package android.telephony.ims.feature { ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities); ctor public MmTelFeature.MmTelCapabilities(int); method public final void addCapabilities(int); - method public final boolean isCapable(int); method public final void removeCapabilities(int); } diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index af49dc4bb9b3..a3cc0abea4ce 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -2514,13 +2514,12 @@ public final class SmsManager { /** * Send an MMS message * - * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the operation being completed on the subscription associated - * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the - * operation is performed on the correct subscription. + * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this + * manager on a multi-SIM device, this operation may fail sending the MMS message because no + * suitable default subscription could be found. In this case, if {@code sentIntent} is + * non-null, then the {@link PendingIntent} will be sent with an error code + * {@code RESULT_NO_DEFAULT_SMS_APP}. See {@link #getDefault()} for more information on the + * conditions where this operation may fail. * </p> * * @param context application context @@ -2539,21 +2538,30 @@ public final class SmsManager { } MmsManager m = (MmsManager) context.getSystemService(Context.MMS_SERVICE); if (m != null) { - m.sendMultimediaMessage(getSubscriptionId(), contentUri, locationUrl, configOverrides, - sentIntent, 0L /* messageId */); + resolveSubscriptionForOperation(new SubscriptionResolverResult() { + @Override + public void onSuccess(int subId) { + m.sendMultimediaMessage(subId, contentUri, locationUrl, configOverrides, + sentIntent, 0L /* messageId */); + } + + @Override + public void onFailure() { + notifySmsError(sentIntent, RESULT_NO_DEFAULT_SMS_APP); + } + }); } } /** * Download an MMS message from carrier by a given location URL * - * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the operation being completed on the subscription associated - * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the - * operation is performed on the correct subscription. + * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this + * manager on a multi-SIM device, this operation may fail downloading the MMS message because no + * suitable default subscription could be found. In this case, if {@code downloadedIntent} is + * non-null, then the {@link PendingIntent} will be sent with an error code + * {@code RESULT_NO_DEFAULT_SMS_APP}. See {@link #getDefault()} for more information on the + * conditions where this operation may fail. * </p> * * @param context application context @@ -2576,8 +2584,18 @@ public final class SmsManager { } MmsManager m = (MmsManager) context.getSystemService(Context.MMS_SERVICE); if (m != null) { - m.downloadMultimediaMessage(getSubscriptionId(), locationUrl, contentUri, - configOverrides, downloadedIntent, 0L /* messageId */); + resolveSubscriptionForOperation(new SubscriptionResolverResult() { + @Override + public void onSuccess(int subId) { + m.downloadMultimediaMessage(subId, locationUrl, contentUri, configOverrides, + downloadedIntent, 0L /* messageId */); + } + + @Override + public void onFailure() { + notifySmsError(downloadedIntent, RESULT_NO_DEFAULT_SMS_APP); + } + }); } } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index e7af0534b7c9..a0a90b6d8fbd 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -13330,9 +13330,7 @@ public class TelephonyManager { * @throws IllegalStateException if the Telephony process is not currently available. * @throws SecurityException if the caller doesn't have the permission. * - * @hide */ - @SystemApi @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public @NonNull List<String> getEquivalentHomePlmns() { try { diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java index 01d468cb53f6..de0fb86029dd 100644 --- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java +++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java @@ -285,8 +285,8 @@ public class MmTelFeature extends ImsFeature { public static final int CAPABILITY_TYPE_SMS = 1 << 3; /** - * @hide - */ + * @hide + */ @Override @SystemApi @TestApi public final void addCapabilities(@MmTelCapability int capabilities) { @@ -294,8 +294,8 @@ public class MmTelFeature extends ImsFeature { } /** - * @hide - */ + * @hide + */ @Override @SystemApi @TestApi public final void removeCapabilities(@MmTelCapability int capability) { @@ -303,17 +303,18 @@ public class MmTelFeature extends ImsFeature { } /** - * @hide - */ + * @param capabilities a bitmask of one or more {@link MmTelCapability}. + * + * @return true if all queried capabilities are true, otherwise false. + */ @Override - @SystemApi @TestApi public final boolean isCapable(@MmTelCapability int capabilities) { return super.isCapable(capabilities); } /** - * @hide - */ + * @hide + */ @NonNull @Override public String toString() { diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java index 1a4427034756..31e508c5b3c2 100644 --- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java @@ -80,12 +80,12 @@ public class SoftApConfigurationTest { assertThat(original.getMaxNumberOfClients()).isEqualTo(0); SoftApConfiguration unparceled = parcelUnparcel(original); - assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isNotSameInstanceAs(original); assertThat(unparceled).isEqualTo(original); assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); - assertThat(copy).isNotSameAs(original); + assertThat(copy).isNotSameInstanceAs(original); assertThat(copy).isEqualTo(original); assertThat(copy.hashCode()).isEqualTo(original.hashCode()); } @@ -104,12 +104,12 @@ public class SoftApConfigurationTest { assertThat(original.getMaxNumberOfClients()).isEqualTo(0); SoftApConfiguration unparceled = parcelUnparcel(original); - assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isNotSameInstanceAs(original); assertThat(unparceled).isEqualTo(original); assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); - assertThat(copy).isNotSameAs(original); + assertThat(copy).isNotSameInstanceAs(original); assertThat(copy).isEqualTo(original); assertThat(copy.hashCode()).isEqualTo(original.hashCode()); } @@ -145,12 +145,12 @@ public class SoftApConfigurationTest { assertThat(original.getAllowedClientList()).isEqualTo(testAllowedClientList); SoftApConfiguration unparceled = parcelUnparcel(original); - assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isNotSameInstanceAs(original); assertThat(unparceled).isEqualTo(original); assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); - assertThat(copy).isNotSameAs(original); + assertThat(copy).isNotSameInstanceAs(original); assertThat(copy).isEqualTo(original); assertThat(copy.hashCode()).isEqualTo(original.hashCode()); } @@ -171,12 +171,12 @@ public class SoftApConfigurationTest { SoftApConfiguration unparceled = parcelUnparcel(original); - assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isNotSameInstanceAs(original); assertThat(unparceled).isEqualTo(original); assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); - assertThat(copy).isNotSameAs(original); + assertThat(copy).isNotSameInstanceAs(original); assertThat(copy).isEqualTo(original); assertThat(copy.hashCode()).isEqualTo(original.hashCode()); } @@ -198,12 +198,12 @@ public class SoftApConfigurationTest { SoftApConfiguration unparceled = parcelUnparcel(original); - assertThat(unparceled).isNotSameAs(original); + assertThat(unparceled).isNotSameInstanceAs(original); assertThat(unparceled).isEqualTo(original); assertThat(unparceled.hashCode()).isEqualTo(original.hashCode()); SoftApConfiguration copy = new SoftApConfiguration.Builder(original).build(); - assertThat(copy).isNotSameAs(original); + assertThat(copy).isNotSameInstanceAs(original); assertThat(copy).isEqualTo(original); assertThat(copy.hashCode()).isEqualTo(original.hashCode()); } |