diff options
113 files changed, 2041 insertions, 698 deletions
diff --git a/Android.bp b/Android.bp index 891ee91f7ed9..670860bb2c51 100644 --- a/Android.bp +++ b/Android.bp @@ -520,24 +520,22 @@ gensrcs { name: "framework-javastream-protos", depfile: true, - tool_files: ["tools/genprotos.sh"], tools: [ "aprotoc", "protoc-gen-javastream", "soong_zip", ], - // TODO This should not be needed. If you set a custom OUT_DIR or OUT_DIR_COMMON_BASE you can - // end up with a command that is extremely long, potentially going passed MAX_ARG_STRLEN due to - // the way sbox rewrites the command. See b/70221552. - cmd: "$(location tools/genprotos.sh) " + - " $(location aprotoc) " + - " $(location protoc-gen-javastream) " + - " $(location soong_zip) " + - " $(genDir) " + - " $(depfile) " + - " $(in) " + - " $(out)", + cmd: "mkdir -p $(genDir)/$(in) " + + "&& $(location aprotoc) " + + " --plugin=$(location protoc-gen-javastream) " + + " --dependency_out=$(depfile) " + + " --javastream_out=$(genDir)/$(in) " + + " -Iexternal/protobuf/src " + + " -I . " + + " $(in) " + + "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)", + srcs: [ "core/proto/**/*.proto", "libs/incident/**/*.proto", @@ -865,28 +863,6 @@ python_binary_host { ], } -// TODO: Don't rely on this list by switching package.html into package-info.java -frameworks_base_subdirs = [ - "core/java", - "graphics/java", - "location/java", - "media/java", - "media/mca/effect/java", - "media/mca/filterfw/java", - "media/mca/filterpacks/java", - "drm/java", - "mms/java", - "opengl/java", - "sax/java", - "telecomm/java", - "telephony/common", - "telephony/java", - "wifi/java", - "lowpan/java", - "keystore/java", - "rs/java", -] - // Make the api/current.txt file available for use by modules in other // directories. filegroup { @@ -998,7 +974,6 @@ stubs_defaults { "test-runner/src/**/*.java", ], libs: framework_docs_only_libs, - local_sourcepaths: frameworks_base_subdirs, create_doc_stubs: true, annotations_enabled: true, api_levels_annotations_enabled: true, @@ -1059,7 +1034,6 @@ stubs_defaults { ":updatable-media-srcs", ], libs: ["framework-internal-utils"], - local_sourcepaths: frameworks_base_subdirs, installable: false, annotations_enabled: true, previous_api: ":last-released-public-api", diff --git a/api/current.txt b/api/current.txt index 4cf725677ca5..e3cbd429b852 100644 --- a/api/current.txt +++ b/api/current.txt @@ -2023,7 +2023,7 @@ package android { field public static final int fingerprint_icon_content_description = 17039384; // 0x1040018 field public static final int httpErrorBadUrl = 17039367; // 0x1040007 field public static final int httpErrorUnsupportedScheme = 17039368; // 0x1040008 - field public static final int no = 17039369; // 0x1040009 + field @Deprecated public static final int no = 17039369; // 0x1040009 field public static final int ok = 17039370; // 0x104000a field public static final int paste = 17039371; // 0x104000b field public static final int paste_as_plain_text = 17039385; // 0x1040019 @@ -2033,7 +2033,7 @@ package android { field public static final int status_bar_notification_info_overflow = 17039383; // 0x1040017 field public static final int unknownName = 17039374; // 0x104000e field public static final int untitled = 17039375; // 0x104000f - field public static final int yes = 17039379; // 0x1040013 + field @Deprecated public static final int yes = 17039379; // 0x1040013 } public static final class R.style { @@ -3021,9 +3021,9 @@ package android.accounts { field public final String type; } - public class AccountAuthenticatorActivity extends android.app.Activity { - ctor public AccountAuthenticatorActivity(); - method public final void setAccountAuthenticatorResult(android.os.Bundle); + @Deprecated public class AccountAuthenticatorActivity extends android.app.Activity { + ctor @Deprecated public AccountAuthenticatorActivity(); + method @Deprecated public final void setAccountAuthenticatorResult(android.os.Bundle); } public class AccountAuthenticatorResponse implements android.os.Parcelable { @@ -4244,8 +4244,8 @@ package android.app { method public android.app.AlertDialog show(); } - public class AliasActivity extends android.app.Activity { - ctor public AliasActivity(); + @Deprecated public class AliasActivity extends android.app.Activity { + ctor @Deprecated public AliasActivity(); } public class AppComponentFactory { @@ -8357,6 +8357,7 @@ package android.bluetooth { method public int describeContents(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean fetchUuidsWithSdp(); method public String getAddress(); + method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public String getAlias(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothClass getBluetoothClass(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getBondState(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public String getName(); @@ -8368,6 +8369,7 @@ package android.bluetooth { field public static final String ACTION_ACL_CONNECTED = "android.bluetooth.device.action.ACL_CONNECTED"; field public static final String ACTION_ACL_DISCONNECTED = "android.bluetooth.device.action.ACL_DISCONNECTED"; field public static final String ACTION_ACL_DISCONNECT_REQUESTED = "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED"; + field public static final String ACTION_ALIAS_CHANGED = "android.bluetooth.action.ALIAS_CHANGED"; field public static final String ACTION_BOND_STATE_CHANGED = "android.bluetooth.device.action.BOND_STATE_CHANGED"; field public static final String ACTION_CLASS_CHANGED = "android.bluetooth.device.action.CLASS_CHANGED"; field public static final String ACTION_FOUND = "android.bluetooth.device.action.FOUND"; @@ -44062,7 +44064,7 @@ package android.telephony { field public static final String KEY_CARRIER_DATA_CALL_PERMANENT_FAILURE_STRINGS = "carrier_data_call_permanent_failure_strings"; field public static final String KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT = "carrier_default_wfc_ims_mode_int"; field public static final String KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT = "carrier_default_wfc_ims_roaming_mode_int"; - field public static final String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL = "carrier_force_disable_etws_cmas_test_bool"; + field @Deprecated public static final String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL = "carrier_force_disable_etws_cmas_test_bool"; field public static final String KEY_CARRIER_IMS_GBA_REQUIRED_BOOL = "carrier_ims_gba_required_bool"; field public static final String KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL = "carrier_instant_lettering_available_bool"; field public static final String KEY_CARRIER_INSTANT_LETTERING_ENCODING_STRING = "carrier_instant_lettering_encoding_string"; @@ -45500,11 +45502,13 @@ package android.telephony.euicc { method @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void updateSubscriptionNickname(int, @Nullable String, @NonNull android.app.PendingIntent); field public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS = "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS"; field public static final String ACTION_NOTIFY_CARRIER_SETUP_INCOMPLETE = "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE"; + field public static final String ACTION_START_EUICC_ACTIVATION = "android.telephony.euicc.action.START_EUICC_ACTIVATION"; field public static final int EMBEDDED_SUBSCRIPTION_RESULT_ERROR = 2; // 0x2 field public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0; // 0x0 field public static final int EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR = 1; // 0x1 field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE"; field public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION"; + field public static final String EXTRA_USE_QR_SCANNER = "android.telephony.euicc.extra.USE_QR_SCANNER"; field public static final String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon"; } diff --git a/api/removed.txt b/api/removed.txt index b947918dc757..a4ccfb6db128 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -595,10 +595,6 @@ package android.provider { field public static final String VOLUME_VOICE = "volume_voice"; } - public static final class Telephony.Sms.Intents { - field public static final String SMS_EMERGENCY_CB_RECEIVED_ACTION = "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED"; - } - } package android.speech.tts { diff --git a/api/system-current.txt b/api/system-current.txt index 808f59ad6af3..0c76fecefc20 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1239,7 +1239,9 @@ package android.bluetooth { public final class BluetoothAdapter { method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean addOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean connectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice); method public boolean disableBLE(); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean disconnectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice); method public boolean enableBLE(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean enableNoAutoConnect(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean factoryReset(); @@ -1264,6 +1266,7 @@ package android.bluetooth { method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean isEncrypted(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean isInSilenceMode(); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean removeBond(); + method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean setAlias(@NonNull String); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setMetadata(int, @NonNull byte[]); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setPhonebookAccessPermission(int); method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setSilenceMode(boolean); @@ -1745,6 +1748,7 @@ package android.content.pm { field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000 field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000 field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000 + field public static final int PROTECTION_FLAG_TELEPHONY = 4194304; // 0x400000 field public static final int PROTECTION_FLAG_WELLBEING = 131072; // 0x20000 field @Nullable public final String backgroundPermission; field @StringRes public int requestRes; @@ -4704,6 +4708,7 @@ package android.net.wifi { method public boolean isPortableHotspotSupported(); method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled(); method public boolean isWifiScannerSupported(); + method @RequiresPermission("android.permission.NETWORK_SETTINGS") public void registerSoftApCallback(@NonNull android.net.wifi.WifiManager.SoftApCallback, @Nullable java.util.concurrent.Executor); method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void removeOnWifiUsabilityStatsListener(@NonNull android.net.wifi.WifiManager.OnWifiUsabilityStatsListener); method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void save(@NonNull android.net.wifi.WifiConfiguration, @Nullable android.net.wifi.WifiManager.ActionListener); method @RequiresPermission("android.permission.WIFI_SET_DEVICE_MOBILITY_STATE") public void setDeviceMobilityState(int); @@ -4762,6 +4767,11 @@ package android.net.wifi { method public void onWifiUsabilityStats(int, boolean, @NonNull android.net.wifi.WifiUsabilityStatsEntry); } + public static interface WifiManager.SoftApCallback { + method public void onConnectedClientsChanged(@NonNull java.util.List<android.net.wifi.WifiClient>); + method public void onStateChanged(int, int); + } + public class WifiNetworkConnectionStatistics implements android.os.Parcelable { ctor public WifiNetworkConnectionStatistics(int, int); ctor public WifiNetworkConnectionStatistics(); @@ -5661,14 +5671,6 @@ package android.os.storage { } -package android.os.telephony { - - public class TelephonyRegistryManager { - method public void notifyCarrierNetworkChange(boolean); - } - -} - package android.permission { public final class PermissionControllerManager { @@ -6137,6 +6139,10 @@ package android.provider { field public static final String SLOT_INDEX = "slot_index"; } + public static final class Telephony.Sms.Intents { + field public static final String ACTION_SMS_EMERGENCY_CB_RECEIVED = "android.provider.action.SMS_EMERGENCY_CB_RECEIVED"; + } + public final class TimeZoneRulesDataContract { field public static final String AUTHORITY = "com.android.timezone"; } @@ -6576,6 +6582,8 @@ package android.service.euicc { field public static final String ACTION_RESOLVE_DEACTIVATE_SIM = "android.service.euicc.action.RESOLVE_DEACTIVATE_SIM"; field public static final String ACTION_RESOLVE_NO_PRIVILEGES = "android.service.euicc.action.RESOLVE_NO_PRIVILEGES"; field public static final String ACTION_RESOLVE_RESOLVABLE_ERRORS = "android.service.euicc.action.RESOLVE_RESOLVABLE_ERRORS"; + field public static final String ACTION_START_CARRIER_ACTIVATION = "android.service.euicc.action.START_CARRIER_ACTIVATION"; + field public static final String ACTION_START_EUICC_ACTIVATION = "android.service.euicc.action.START_EUICC_ACTIVATION"; field public static final String ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED = "android.service.euicc.action.TOGGLE_SUBSCRIPTION_PRIVILEGED"; field public static final String CATEGORY_EUICC_UI = "android.service.euicc.category.EUICC_UI"; field public static final String EUICC_SERVICE_INTERFACE = "android.service.euicc.EuiccService"; @@ -7661,6 +7669,7 @@ package android.telephony { public final class DataSpecificRegistrationInfo implements android.os.Parcelable { method public int describeContents(); method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo(); + method public boolean isUsingCarrierAggregation(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR; } @@ -7773,6 +7782,7 @@ package android.telephony { method @Nullable public android.telephony.CellIdentity getCellIdentity(); method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo(); method public int getDomain(); + method public int getNrState(); method public int getRegistrationState(); method public int getRejectCause(); method public int getRoamingType(); @@ -8015,6 +8025,9 @@ package android.telephony { method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList(); method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForDomain(int); method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoListForTransportType(int); + method public int getNrFrequencyRange(); + method @Nullable public String getOperatorAlphaLongRaw(); + method @Nullable public String getOperatorAlphaShortRaw(); field public static final int ROAMING_TYPE_DOMESTIC = 2; // 0x2 field public static final int ROAMING_TYPE_INTERNATIONAL = 3; // 0x3 field public static final int ROAMING_TYPE_NOT_ROAMING = 0; // 0x0 @@ -8348,6 +8361,15 @@ package android.telephony { field public static final int SRVCC_STATE_HANDOVER_STARTED = 0; // 0x0 } + public class TelephonyRegistryManager { + method public void addOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener, @NonNull java.util.concurrent.Executor); + method public void addOnSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnSubscriptionsChangedListener, @NonNull java.util.concurrent.Executor); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyCallStateChangedForAllSubscriptions(int, @Nullable String); + method public void notifyCarrierNetworkChange(boolean); + method public void removeOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); + method public void removeOnSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); + } + public final class UiccAccessRule implements android.os.Parcelable { ctor public UiccAccessRule(byte[], @Nullable String, long); method public int describeContents(); @@ -8627,6 +8649,7 @@ package android.telephony.euicc { field public static final String EXTRA_ENABLE_SUBSCRIPTION = "android.telephony.euicc.extra.ENABLE_SUBSCRIPTION"; field public static final String EXTRA_FORCE_PROVISION = "android.telephony.euicc.extra.FORCE_PROVISION"; field public static final String EXTRA_FROM_SUBSCRIPTION_ID = "android.telephony.euicc.extra.FROM_SUBSCRIPTION_ID"; + field public static final String EXTRA_PHYSICAL_SLOT_ID = "android.telephony.euicc.extra.PHYSICAL_SLOT_ID"; field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.euicc.extra.SUBSCRIPTION_ID"; field public static final String EXTRA_SUBSCRIPTION_NICKNAME = "android.telephony.euicc.extra.SUBSCRIPTION_NICKNAME"; } diff --git a/api/test-current.txt b/api/test-current.txt index daeeaece171c..18d9f75b5aae 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -707,6 +707,7 @@ package android.content.pm { 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 @NonNull public abstract String getServicesSystemSharedLibraryPackageName(); method @NonNull public abstract String getSharedSystemSharedLibraryPackageName(); + method @Nullable public String[] getTelephonyPackageNames(); 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.permission.REVOKE_RUNTIME_PERMISSIONS") public abstract void revokeRuntimePermission(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); @@ -739,6 +740,7 @@ package android.content.pm { field public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 1048576; // 0x100000 field public static final int PROTECTION_FLAG_OEM = 16384; // 0x4000 field public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 65536; // 0x10000 + field public static final int PROTECTION_FLAG_TELEPHONY = 4194304; // 0x400000 field public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 32768; // 0x8000 field public static final int PROTECTION_FLAG_WELLBEING = 131072; // 0x20000 field @Nullable public final String backgroundPermission; diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java index 25cd342cb5e9..6470a04aefd6 100644 --- a/core/java/android/accounts/AbstractAccountAuthenticator.java +++ b/core/java/android/accounts/AbstractAccountAuthenticator.java @@ -103,8 +103,6 @@ import java.util.Arrays; * When writing an activity to satisfy these requests one must pass in the AccountManagerResponse * and return the result via that response when the activity finishes (or whenever else the * activity author deems it is the correct time to respond). - * The {@link AccountAuthenticatorActivity} handles this, so one may wish to extend that when - * writing activities to handle these requests. */ public abstract class AbstractAccountAuthenticator { private static final String TAG = "AccountAuthenticator"; diff --git a/core/java/android/accounts/AccountAuthenticatorActivity.java b/core/java/android/accounts/AccountAuthenticatorActivity.java index 967aa0424b1d..65ba35ff9e8d 100644 --- a/core/java/android/accounts/AccountAuthenticatorActivity.java +++ b/core/java/android/accounts/AccountAuthenticatorActivity.java @@ -32,7 +32,11 @@ import android.os.Bundle; * This result will be sent as the result of the request when the activity finishes. If this * is never set or if it is set to null then error {@link AccountManager#ERROR_CODE_CANCELED} * will be called on the response. + * + * @deprecated Applications should extend Activity themselves. This class is not compatible with + * AppCompat, and the functionality it provides is not complex. */ +@Deprecated public class AccountAuthenticatorActivity extends Activity { private AccountAuthenticatorResponse mAccountAuthenticatorResponse = null; private Bundle mResultBundle = null; diff --git a/core/java/android/app/AliasActivity.java b/core/java/android/app/AliasActivity.java index 37565298c8cb..37be90160d9a 100644 --- a/core/java/android/app/AliasActivity.java +++ b/core/java/android/app/AliasActivity.java @@ -39,7 +39,10 @@ import java.io.IOException; * To use this activity, you should include in the manifest for the associated * component an entry named "android.app.alias". It is a reference to an XML * resource describing an intent that launches the real application. + * + * @deprecated Use {@code <activity-alias>} or subclass Activity directly. */ +@Deprecated public class AliasActivity extends Activity { /** * This is the name under which you should store in your component the diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 360be350601d..835769f69951 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -3121,6 +3121,15 @@ public class ApplicationPackageManager extends PackageManager { } @Override + public String[] getTelephonyPackageNames() { + try { + return mPM.getTelephonyPackageNames(); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + + @Override public String getSystemCaptionsServicePackageName() { try { return mPM.getSystemCaptionsServicePackageName(); diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index dd39376f80ca..903dd493d187 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -1638,7 +1638,7 @@ public class NotificationManager { @Override public int hashCode() { return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders, - suppressedVisualEffects); + suppressedVisualEffects, state); } @Override @@ -1650,10 +1650,10 @@ public class NotificationManager { && other.priorityCallSenders == priorityCallSenders && other.priorityMessageSenders == priorityMessageSenders && suppressedVisualEffectsEqual(suppressedVisualEffects, - other.suppressedVisualEffects); + other.suppressedVisualEffects) + && other.state == this.state; } - private boolean suppressedVisualEffectsEqual(int suppressedEffects, int otherSuppressedVisualEffects) { if (suppressedEffects == otherSuppressedVisualEffects) { diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 646f0dc71b15..587d7b132c10 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -157,7 +157,7 @@ import android.os.health.SystemHealthManager; import android.os.image.DynamicSystemManager; import android.os.image.IDynamicSystemService; import android.os.storage.StorageManager; -import android.os.telephony.TelephonyRegistryManager; +import android.telephony.TelephonyRegistryManager; import android.permission.PermissionControllerManager; import android.permission.PermissionManager; import android.print.IPrintManager; @@ -173,8 +173,6 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.euicc.EuiccCardManager; import android.telephony.euicc.EuiccManager; -import android.telephony.ims.ImsManager; -import android.telephony.ims.RcsMessageManager; import android.util.ArrayMap; import android.util.Log; import android.view.ContextThemeWrapper; @@ -613,7 +611,7 @@ final class SystemServiceRegistry { new CachedServiceFetcher<TelephonyRegistryManager>() { @Override public TelephonyRegistryManager createService(ContextImpl ctx) { - return new TelephonyRegistryManager(); + return new TelephonyRegistryManager(ctx); }}); registerService(Context.TELEPHONY_SUBSCRIPTION_SERVICE, SubscriptionManager.class, @@ -623,22 +621,6 @@ final class SystemServiceRegistry { return new SubscriptionManager(ctx.getOuterContext()); }}); - registerService(Context.TELEPHONY_RCS_MESSAGE_SERVICE, RcsMessageManager.class, - new CachedServiceFetcher<RcsMessageManager>() { - @Override - public RcsMessageManager createService(ContextImpl ctx) { - return new RcsMessageManager(ctx.getOuterContext()); - } - }); - - registerService(Context.TELEPHONY_IMS_SERVICE, ImsManager.class, - new CachedServiceFetcher<ImsManager>() { - @Override - public ImsManager createService(ContextImpl ctx) { - return new ImsManager(ctx.getOuterContext()); - } - }); - registerService(Context.CARRIER_CONFIG_SERVICE, CarrierConfigManager.class, new CachedServiceFetcher<CarrierConfigManager>() { @Override diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 566b38738dc1..9d152a7faf44 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -1734,6 +1734,56 @@ public final class BluetoothAdapter { } /** + * Connects all enabled and supported bluetooth profiles between the local and remote device + * + * @param device is the remote device with which to connect these profiles + * @return true if all profiles successfully connected, false if an error occurred + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + public boolean connectAllEnabledProfiles(@NonNull BluetoothDevice device) { + try { + mServiceLock.readLock().lock(); + if (mService != null) { + return mService.connectAllEnabledProfiles(device); + } + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } + + return false; + } + + /** + * Disconnects all enabled and supported bluetooth profiles between the local and remote device + * + * @param device is the remote device with which to disconnect these profiles + * @return true if all profiles successfully disconnected, false if an error occurred + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN) + public boolean disconnectAllEnabledProfiles(@NonNull BluetoothDevice device) { + try { + mServiceLock.readLock().lock(); + if (mService != null) { + return mService.disconnectAllEnabledProfiles(device); + } + } catch (RemoteException e) { + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); + } + + return false; + } + + /** * Return true if the multi advertisement is supported by the chipset * * @return true if Multiple Advertisement feature is supported diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index c6160446c798..19f42b6a4c9e 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -173,13 +173,10 @@ public final class BluetoothDevice implements Parcelable { * changed. * <p>Always contains the extra field {@link #EXTRA_DEVICE}. * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. - * - * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @UnsupportedAppUsage public static final String ACTION_ALIAS_CHANGED = - "android.bluetooth.device.action.ALIAS_CHANGED"; + "android.bluetooth.action.ALIAS_CHANGED"; /** * Broadcast Action: Indicates a change in the bond state of a remote @@ -1048,10 +1045,11 @@ public final class BluetoothDevice implements Parcelable { * Get the Bluetooth alias of the remote device. * <p>Alias is the locally modified name of a remote device. * - * @return the Bluetooth alias, or null if no alias or there was a problem - * @hide + * @return the Bluetooth alias, the friendly device name if no alias, or + * null if there was a problem */ - @UnsupportedAppUsage(publicAlternatives = "Use {@link #getName()} instead.") + @Nullable + @RequiresPermission(Manifest.permission.BLUETOOTH) public String getAlias() { final IBluetooth service = sService; if (service == null) { @@ -1059,7 +1057,11 @@ public final class BluetoothDevice implements Parcelable { return null; } try { - return service.getRemoteAlias(this); + String alias = service.getRemoteAlias(this); + if (alias == null) { + return getName(); + } + return alias; } catch (RemoteException e) { Log.e(TAG, "", e); } @@ -1076,8 +1078,9 @@ public final class BluetoothDevice implements Parcelable { * @return true on success, false on error * @hide */ - @UnsupportedAppUsage - public boolean setAlias(String alias) { + @SystemApi + @RequiresPermission(Manifest.permission.BLUETOOTH) + public boolean setAlias(@NonNull String alias) { final IBluetooth service = sService; if (service == null) { Log.e(TAG, "BT not enabled. Cannot set Remote Device name"); diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java index dabe0fdac39a..f5aa01458481 100644 --- a/core/java/android/bluetooth/BluetoothProfile.java +++ b/core/java/android/bluetooth/BluetoothProfile.java @@ -324,4 +324,54 @@ public interface BluetoothProfile { return "STATE_UNKNOWN"; } } + + /** + * Convert an integer value of profile ID into human readable string + * + * @param profile profile ID + * @return profile name as String, UNKOWN_PROFILE if the profile ID is not defined. + * @hide + */ + static String getProfileName(int profile) { + switch(profile) { + case HEADSET: + return "HEADSET"; + case A2DP: + return "A2DP"; + case HID_HOST: + return "HID_HOST"; + case PAN: + return "PAN"; + case PBAP: + return "PBAP"; + case GATT: + return "GATT"; + case GATT_SERVER: + return "GATT_SERVER"; + case MAP: + return "MAP"; + case SAP: + return "SAP"; + case A2DP_SINK: + return "A2DP_SINK"; + case AVRCP_CONTROLLER: + return "AVRCP_CONTROLLER"; + case AVRCP: + return "AVRCP"; + case HEADSET_CLIENT: + return "HEADSET_CLIENT"; + case PBAP_CLIENT: + return "PBAP_CLIENT"; + case MAP_CLIENT: + return "MAP_CLIENT"; + case HID_DEVICE: + return "HID_DEVICE"; + case OPP: + return "OPP"; + case HEARING_AID: + return "HEARING_AID"; + default: + return "UNKNOWN_PROFILE"; + } + } } diff --git a/core/java/android/companion/BluetoothDeviceFilterUtils.java b/core/java/android/companion/BluetoothDeviceFilterUtils.java index 75e726bfad0d..0f67f6b50251 100644 --- a/core/java/android/companion/BluetoothDeviceFilterUtils.java +++ b/core/java/android/companion/BluetoothDeviceFilterUtils.java @@ -129,7 +129,7 @@ public class BluetoothDeviceFilterUtils { @UnsupportedAppUsage public static String getDeviceDisplayNameInternal(@NonNull BluetoothDevice device) { - return firstNotEmpty(device.getAliasName(), device.getAddress()); + return firstNotEmpty(device.getAlias(), device.getAddress()); } @UnsupportedAppUsage diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index a3b918d095e0..a12e4da6e23e 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -63,6 +63,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.storage.StorageManager; import android.provider.MediaStore; +import android.telephony.TelephonyRegistryManager; import android.util.AttributeSet; import android.view.Display; import android.view.DisplayAdjustments; @@ -4747,7 +4748,7 @@ public abstract class Context { /** * Use with {@link #getSystemService(String)} to retrieve an - * {@link android.os.telephony.TelephonyRegistryManager}. + * {@link TelephonyRegistryManager}. * @hide */ @SystemApi diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index a7eecd7f4306..7538dca76d18 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -753,6 +753,8 @@ interface IPackageManager { String getWellbeingPackageName(); + String[] getTelephonyPackageNames(); + String getAppPredictionServicePackageName(); String getSystemCaptionsServicePackageName(); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index a93297e9d51b..81670cd0d2b8 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -7368,6 +7368,18 @@ public abstract class PackageManager { } /** + * @return the system defined telephony package names, or null if there's none. + * + * @hide + */ + @Nullable + @TestApi + public String[] getTelephonyPackageNames() { + throw new UnsupportedOperationException( + "getTelephonyPackageNames not implemented in subclass"); + } + + /** * @return the system defined content capture service package name, or null if there's none. * * @hide diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 672994e79134..28d9152b3707 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -59,6 +59,7 @@ public abstract class PackageManagerInternal { public static final int PACKAGE_CONFIGURATOR = 9; public static final int PACKAGE_INCIDENT_REPORT_APPROVER = 10; public static final int PACKAGE_APP_PREDICTOR = 11; + public static final int PACKAGE_TELEPHONY = 12; @IntDef(value = { PACKAGE_SYSTEM, PACKAGE_SETUP_WIZARD, @@ -72,6 +73,7 @@ public abstract class PackageManagerInternal { PACKAGE_CONFIGURATOR, PACKAGE_INCIDENT_REPORT_APPROVER, PACKAGE_APP_PREDICTOR, + PACKAGE_TELEPHONY, }) @Retention(RetentionPolicy.SOURCE) public @interface KnownPackage {} @@ -715,10 +717,11 @@ public abstract class PackageManagerInternal { */ public abstract boolean isResolveActivityComponent(@NonNull ComponentInfo component); + /** - * Returns the package name for a known package. + * Returns a list of package names for a known package */ - public abstract @Nullable String getKnownPackageName( + public abstract @NonNull String[] getKnownPackageNames( @KnownPackage int knownPackage, int userId); /** diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index dd5c6a53cc20..c77c53f387e2 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -237,6 +237,17 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { @TestApi public static final int PROTECTION_FLAG_APP_PREDICTOR = 0x200000; + /** + * Additional flag for {@link #protectionLevel}, corresponding + * to the <code>telephony</code> value of + * {@link android.R.attr#protectionLevel}. + * + * @hide + */ + @SystemApi + @TestApi + public static final int PROTECTION_FLAG_TELEPHONY = 0x400000; + /** @hide */ @IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = { PROTECTION_FLAG_PRIVILEGED, @@ -258,6 +269,7 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { PROTECTION_FLAG_CONFIGURATOR, PROTECTION_FLAG_INCIDENT_REPORT_APPROVER, PROTECTION_FLAG_APP_PREDICTOR, + PROTECTION_FLAG_TELEPHONY, }) @Retention(RetentionPolicy.SOURCE) public @interface ProtectionFlags {} @@ -501,6 +513,9 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { if ((level & PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR) != 0) { protLevel += "|appPredictor"; } + if ((level & PermissionInfo.PROTECTION_FLAG_TELEPHONY) != 0) { + protLevel += "|telephony"; + } return protLevel; } diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java index 5bc9953e0d05..990c1142284c 100644 --- a/core/java/android/net/StaticIpConfiguration.java +++ b/core/java/android/net/StaticIpConfiguration.java @@ -25,6 +25,8 @@ import android.net.shared.InetAddressUtils; import android.os.Parcel; import android.os.Parcelable; +import com.android.internal.util.Preconditions; + import java.net.InetAddress; import java.util.ArrayList; import java.util.List; @@ -152,6 +154,7 @@ public final class StaticIpConfiguration implements Parcelable { * @return The {@link Builder} for chaining. */ public @NonNull Builder setDnsServers(@NonNull Iterable<InetAddress> dnsServers) { + Preconditions.checkNotNull(dnsServers); mDnsServers = dnsServers; return this; } @@ -175,8 +178,10 @@ public final class StaticIpConfiguration implements Parcelable { final StaticIpConfiguration config = new StaticIpConfiguration(); config.ipAddress = mIpAddress; config.gateway = mGateway; - for (InetAddress server : mDnsServers) { - config.dnsServers.add(server); + if (mDnsServers != null) { + for (InetAddress server : mDnsServers) { + config.dnsServers.add(server); + } } config.domains = mDomains; return config; diff --git a/core/java/android/net/util/MultinetworkPolicyTracker.java b/core/java/android/net/util/MultinetworkPolicyTracker.java index 4e88149b8095..aa0f6220036c 100644 --- a/core/java/android/net/util/MultinetworkPolicyTracker.java +++ b/core/java/android/net/util/MultinetworkPolicyTracker.java @@ -94,7 +94,8 @@ public class MultinetworkPolicyTracker { } }; - TelephonyManager.from(ctx).listen(new PhoneStateListener(handler.getLooper()) { + ctx.getSystemService(TelephonyManager.class).listen( + new PhoneStateListener(handler.getLooper()) { @Override public void onActiveDataSubscriptionIdChanged(int subId) { mActiveSubId = subId; diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index 48fc2a6bf449..e3f6e120d9c6 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -888,7 +888,7 @@ public class RecoverySystem { } List<SubscriptionInfo> invisibleSubs = new ArrayList<>(); for (SubscriptionInfo sub : availableSubs) { - if (sub.isEmbedded() && !subscriptionManager.isSubscriptionVisible(sub)) { + if (sub.isEmbedded() && sub.getGroupUuid() != null && sub.isOpportunistic()) { invisibleSubs.add(sub); } } diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 9c9829fb08e2..c15618bdaa78 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -1295,8 +1295,11 @@ public class UserManager { mContext.getContentResolver(), Settings.Global.ALLOW_USER_SWITCHING_WHEN_SYSTEM_USER_LOCKED, 0) != 0; boolean isSystemUserUnlocked = isUserUnlocked(UserHandle.SYSTEM); - boolean inCall = TelephonyManager.getDefault().getCallState() - != TelephonyManager.CALL_STATE_IDLE; + boolean inCall = false; + TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class); + if (telephonyManager != null) { + inCall = telephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE; + } boolean isUserSwitchDisallowed = hasUserRestriction(DISALLOW_USER_SWITCH); return (allowUserSwitchingWhenSystemUserLocked || isSystemUserUnlocked) && !inCall && !isUserSwitchDisallowed; diff --git a/core/java/android/os/image/DynamicSystemManager.java b/core/java/android/os/image/DynamicSystemManager.java index 0e00d5e9b7bf..4c92c28c1bfa 100644 --- a/core/java/android/os/image/DynamicSystemManager.java +++ b/core/java/android/os/image/DynamicSystemManager.java @@ -101,6 +101,19 @@ public class DynamicSystemManager { } } /** + * Start DynamicSystem installation. + * + * @return true if the call succeeds + */ + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) + public boolean startInstallation() { + try { + return mService.startInstallation(); + } catch (RemoteException e) { + throw new RuntimeException(e.toString()); + } + } + /** * Start DynamicSystem installation. This call may take an unbounded amount of time. The caller * may use another thread to call the getStartProgress() to get the progress. * @@ -112,9 +125,9 @@ public class DynamicSystemManager { * true. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) - public Session startInstallation(String name, long size, boolean readOnly) { + public Session createPartition(String name, long size, boolean readOnly) { try { - if (mService.startInstallation(name, size, readOnly)) { + if (mService.createPartition(name, size, readOnly)) { return new Session(); } else { return null; @@ -123,7 +136,18 @@ public class DynamicSystemManager { throw new RuntimeException(e.toString()); } } - + /** + * Finish a previously started installation. Installations without a cooresponding + * finishInstallation() will be cleaned up during device boot. + */ + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) + public boolean finishInstallation() { + try { + return mService.finishInstallation(); + } catch (RemoteException e) { + throw new RuntimeException(e.toString()); + } + } /** * Query the progress of the current installation operation. This can be called while the * installation is in progress. diff --git a/core/java/android/os/image/IDynamicSystemService.aidl b/core/java/android/os/image/IDynamicSystemService.aidl index 75f67854743f..69cbab2c68ad 100644 --- a/core/java/android/os/image/IDynamicSystemService.aidl +++ b/core/java/android/os/image/IDynamicSystemService.aidl @@ -21,15 +21,26 @@ import android.gsi.GsiProgress; interface IDynamicSystemService { /** - * Start DynamicSystem installation. This call may take 60~90 seconds. The caller + * Start DynamicSystem installation. + * @return true if the call succeeds + */ + boolean startInstallation(); + + /** + * Create a DSU partition. This call may take 60~90 seconds. The caller * may use another thread to call the getStartProgress() to get the progress. - * * @param name The DSU partition name * @param size Size of the DSU image in bytes * @param readOnly True if this partition is readOnly * @return true if the call succeeds */ - boolean startInstallation(@utf8InCpp String name, long size, boolean readOnly); + boolean createPartition(@utf8InCpp String name, long size, boolean readOnly); + + /** + * Finish a previously started installation. Installations without + * a cooresponding finishInstallation() will be cleaned up during device boot. + */ + boolean finishInstallation(); /** * Query the progress of the current installation operation. This can be called while diff --git a/core/java/android/service/carrier/CarrierService.java b/core/java/android/service/carrier/CarrierService.java index 9184d6d51f44..eefc1b70bac9 100644 --- a/core/java/android/service/carrier/CarrierService.java +++ b/core/java/android/service/carrier/CarrierService.java @@ -22,7 +22,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.PersistableBundle; import android.os.ResultReceiver; -import android.os.telephony.TelephonyRegistryManager; +import android.telephony.TelephonyRegistryManager; import android.util.Log; /** diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java index 21c3be3df1fc..bc6a9e848e2a 100644 --- a/core/java/android/service/euicc/EuiccService.java +++ b/core/java/android/service/euicc/EuiccService.java @@ -21,6 +21,7 @@ import android.annotation.CallSuper; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SdkConstant; import android.annotation.SystemApi; import android.app.Service; import android.content.Intent; @@ -104,6 +105,26 @@ public abstract class EuiccService extends Service { "android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE"; /** + * Intent action sent by the LPA to launch a carrier app Activity for eSIM activation, e.g. a + * carrier login screen. Carrier apps wishing to support this activation method must implement + * an Activity that responds to this intent action. Upon completion, the Activity must return + * one of the following results to the LPA: + * + * <p>{@code Activity.RESULT_CANCELED}: The LPA should treat this as an back button and abort + * the activation flow. + * <p>{@code Activity.RESULT_OK}: The LPA should try to get an activation code from the carrier + * app by binding to the carrier app service implementing + * {@link #ACTION_BIND_CARRIER_PROVISIONING_SERVICE}. + * <p>{@code Activity.RESULT_OK} with + * {@link android.telephony.euicc.EuiccManager#EXTRA_USE_QR_SCANNER} set to true: The LPA should + * start a QR scanner for the user to scan an eSIM profile QR code. + * <p>For other results: The LPA should treat this as an error. + **/ + @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_START_CARRIER_ACTIVATION = + "android.service.euicc.action.START_CARRIER_ACTIVATION"; + + /** * @see android.telephony.euicc.EuiccManager#ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS * The difference is this one is used by system to bring up the LUI. */ @@ -138,6 +159,15 @@ public abstract class EuiccService extends Service { public static final String ACTION_RENAME_SUBSCRIPTION_PRIVILEGED = "android.service.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED"; + /** + * @see android.telephony.euicc.EuiccManager#ACTION_START_EUICC_ACTIVATION. This is + * a protected intent that can only be sent by the system, and requires the + * {@link android.Manifest.permission#BIND_EUICC_SERVICE} permission. + */ + @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_START_EUICC_ACTIVATION = + "android.service.euicc.action.START_EUICC_ACTIVATION"; + // LUI resolution actions. These are called by the platform to resolve errors in situations that // require user interaction. // TODO(b/33075886): Define extras for any input parameters to these dialogs once they are diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index e5bfb4dfb7b4..2af827e36696 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -35,8 +35,8 @@ import android.telephony.Annotation.SrvccState; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; -import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.IPhoneStateListener; +import com.android.internal.annotations.VisibleForTesting; import dalvik.system.VMRuntime; diff --git a/core/java/android/os/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index b67409988da0..456789fb77bc 100644 --- a/core/java/android/os/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -13,12 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.os.telephony; +package android.telephony; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; +import android.annotation.TestApi; +import android.content.Context; import android.net.LinkProperties; import android.net.NetworkCapabilities; +import android.os.Binder; import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerExecutor; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.Annotation; @@ -41,8 +49,15 @@ import android.telephony.SignalStrength; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.ims.ImsReasonInfo; +import android.util.Log; + +import com.android.internal.telephony.IOnSubscriptionsChangedListener; import com.android.internal.telephony.ITelephonyRegistry; + +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; /** * A centralized place to notify telephony related status changes, e.g, {@link ServiceState} update @@ -59,9 +74,26 @@ public class TelephonyRegistryManager { private static final String TAG = "TelephonyRegistryManager"; private static ITelephonyRegistry sRegistry; + private final Context mContext; + + /** + * A mapping between {@link SubscriptionManager.OnSubscriptionsChangedListener} and + * its callback IOnSubscriptionsChangedListener. + */ + private final Map<SubscriptionManager.OnSubscriptionsChangedListener, + IOnSubscriptionsChangedListener> mSubscriptionChangedListenerMap = new HashMap<>(); + /** + * A mapping between {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} and + * its callback IOnSubscriptionsChangedListener. + */ + private final Map<SubscriptionManager.OnOpportunisticSubscriptionsChangedListener, + IOnSubscriptionsChangedListener> mOpportunisticSubscriptionChangedListenerMap + = new HashMap<>(); + /** @hide **/ - public TelephonyRegistryManager() { + public TelephonyRegistryManager(@NonNull Context context) { + mContext = context; if (sRegistry == null) { sRegistry = ITelephonyRegistry.Stub.asInterface( ServiceManager.getService("telephony.registry")); @@ -69,6 +101,113 @@ public class TelephonyRegistryManager { } /** + * Register for changes to the list of active {@link SubscriptionInfo} records or to the + * individual records themselves. When a change occurs the onSubscriptionsChanged method of + * the listener will be invoked immediately if there has been a notification. The + * onSubscriptionChanged method will also be triggered once initially when calling this + * function. + * + * @param listener an instance of {@link SubscriptionManager.OnSubscriptionsChangedListener} + * with onSubscriptionsChanged overridden. + * @param executor the executor that will execute callbacks. + */ + public void addOnSubscriptionsChangedListener( + @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener, + @NonNull Executor executor) { + IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { + @Override + public void onSubscriptionsChanged () { + Log.d(TAG, "onSubscriptionsChangedListener callback received."); + executor.execute(() -> listener.onSubscriptionsChanged()); + } + }; + mSubscriptionChangedListenerMap.put(listener, callback); + try { + sRegistry.addOnSubscriptionsChangedListener(mContext.getOpPackageName(), callback); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Unregister the {@link SubscriptionManager.OnSubscriptionsChangedListener}. This is not + * strictly necessary as the listener will automatically be unregistered if an attempt to + * invoke the listener fails. + * + * @param listener that is to be unregistered. + */ + public void removeOnSubscriptionsChangedListener( + @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener) { + if (mSubscriptionChangedListenerMap.get(listener) == null) { + return; + } + try { + sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(), + mSubscriptionChangedListenerMap.get(listener)); + mSubscriptionChangedListenerMap.remove(listener); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Register for changes to the list of opportunistic subscription records or to the + * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged + * method of the listener will be invoked immediately if there has been a notification. + * + * @param listener an instance of + * {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} with + * onOpportunisticSubscriptionsChanged overridden. + * @param executor an Executor that will execute callbacks. + */ + public void addOnOpportunisticSubscriptionsChangedListener( + @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener, + @NonNull Executor executor) { + /** + * The callback methods need to be called on the executor thread where + * this object was created. If the binder did that for us it'd be nice. + */ + IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { + @Override + public void onSubscriptionsChanged() { + final long identity = Binder.clearCallingIdentity(); + try { + Log.d(TAG, "onOpportunisticSubscriptionsChanged callback received."); + executor.execute(() -> listener.onOpportunisticSubscriptionsChanged()); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + }; + mOpportunisticSubscriptionChangedListenerMap.put(listener, callback); + try { + sRegistry.addOnOpportunisticSubscriptionsChangedListener(mContext.getOpPackageName(), + callback); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Unregister the {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} + * that is currently listening opportunistic subscriptions change. This is not strictly + * necessary as the listener will automatically be unregistered if an attempt to invoke the + * listener fails. + * + * @param listener that is to be unregistered. + */ + public void removeOnOpportunisticSubscriptionsChangedListener( + @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener) { + try { + sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(), + mOpportunisticSubscriptionChangedListenerMap.get(listener)); + mOpportunisticSubscriptionChangedListenerMap.remove(listener); + } catch (RemoteException ex) { + // system server crash + } + } + + /** * Informs the system of an intentional upcoming carrier network change by a carrier app. * This call only used to allow the system to provide alternative UI while telephony is * performing an action that may result in intentional, temporary network lack of connectivity. @@ -98,14 +237,33 @@ public class TelephonyRegistryManager { * @param slotIndex for which call state changed. Can be derived from subId except when subId is * invalid. * @param state latest call state. e.g, offhook, ringing - * @param incomingNumer incoming phone number. + * @param incomingNumber incoming phone number. * * @hide */ public void notifyCallStateChanged(int subId, int slotIndex, @CallState int state, - String incomingNumer) { + String incomingNumber) { try { - sRegistry.notifyCallState(slotIndex, subId, state, incomingNumer); + sRegistry.notifyCallState(slotIndex, subId, state, incomingNumber); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Notify call state changed on all subscriptions. + * + * @param state latest call state. e.g, offhook, ringing + * @param incomingNumber incoming phone number. + * @hide + */ + @SystemApi + @TestApi + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void notifyCallStateChangedForAllSubscriptions(@CallState int state, + @Nullable String incomingNumber) { + try { + sRegistry.notifyCallStateForAllSubs(state, incomingNumber); } catch (RemoteException ex) { // system server crash } @@ -545,4 +703,15 @@ public class TelephonyRegistryManager { } } + /** + * @param activeDataSubId + * @hide + */ + public void notifyActiveDataSubIdChanged(int activeDataSubId) { + try { + sRegistry.notifyActiveDataSubIdChanged(activeDataSubId); + } catch (RemoteException ex) { + + } + } } diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java index c11089ba19bd..49f77e11cf80 100644 --- a/core/java/com/android/internal/app/LocaleStore.java +++ b/core/java/com/android/internal/app/LocaleStore.java @@ -194,7 +194,7 @@ public class LocaleStore { private static Set<String> getSimCountries(Context context) { Set<String> result = new HashSet<>(); - TelephonyManager tm = TelephonyManager.from(context); + TelephonyManager tm = context.getSystemService(TelephonyManager.class); if (tm != null) { String iso = tm.getSimCountryIso().toUpperCase(Locale.US); diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl index 5857642cbd4e..7dcb12c9e72b 100644 --- a/core/java/com/android/internal/compat/IPlatformCompat.aidl +++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl @@ -133,7 +133,7 @@ interface IPlatformCompat boolean isChangeEnabledByUid(long changeId, int uid); /** - * Add overrides to compatibility changes. + * Add overrides to compatibility changes. Kills the app to allow the changes to take effect. * * @param overrides Parcelable containing the compat change overrides to be applied. * @param packageName The package name of the app whose changes will be overridden. @@ -142,7 +142,28 @@ interface IPlatformCompat void setOverrides(in CompatibilityChangeConfig overrides, in String packageName); /** - * Revert overrides to compatibility changes. + * Add overrides to compatibility changes. Doesn't kill the app, to be only used in tests. + * + * @param overrides Parcelable containing the compat change overrides to be applied. + * @param packageName The package name of the app whose changes will be overridden. + * + */ + void setOverridesForTest(in CompatibilityChangeConfig overrides, in String packageName); + + /** + * Removes an override previously added via {@link #setOverrides(CompatibilityChangeConfig, + * String)}. This restores the default behaviour for the given change and app, once any app + * processes have been restarted. + * Kills the app to allow the changes to take effect. + * + * @param changeId The ID of the change that was overridden. + * @param packageName The app package name that was overridden. + * @return {@code true} if an override existed; + */ + boolean clearOverride(long changeId, String packageName); + + /** + * Revert overrides to compatibility changes. Kills the app to allow the changes to take effect. * * @param packageName The package name of the app whose overrides will be cleared. * @@ -150,6 +171,15 @@ interface IPlatformCompat void clearOverrides(in String packageName); /** + * Revert overrides to compatibility changes. Doesn't kill the app, to be only used in tests. + * + * @param packageName The package name of the app whose overrides will be cleared. + * + */ + void clearOverridesForTest(in String packageName); + + + /** * Get configs for an application. * * @param appInfo The application whose config will be returned. diff --git a/core/java/com/android/internal/package-info.java b/core/java/com/android/internal/package-info.java new file mode 100644 index 000000000000..8a226dbdc9fe --- /dev/null +++ b/core/java/com/android/internal/package-info.java @@ -0,0 +1,4 @@ +/** + * @hide + */ +package com.android.internal; diff --git a/telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl b/core/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl index 493b1ff6aba7..493b1ff6aba7 100644 --- a/telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl +++ b/core/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl index 90019eef62fd..084a3cc64a35 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -29,6 +29,9 @@ import android.telephony.SignalStrength; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; +/** + * {@hide} + */ oneway interface IPhoneStateListener { void onServiceStateChanged(in ServiceState serviceState); void onSignalStrengthChanged(int asu); diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index d7a7af1d530f..d7a7af1d530f 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 9a90555041d7..9e4c2220576c 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -667,6 +667,8 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p char dex2oatImageCompilerFilterBuf[sizeof("--compiler-filter=")-1 + PROPERTY_VALUE_MAX]; char dex2oatThreadsBuf[sizeof("-j")-1 + PROPERTY_VALUE_MAX]; char dex2oatThreadsImageBuf[sizeof("-j")-1 + PROPERTY_VALUE_MAX]; + char dex2oatCpuSetBuf[sizeof("--cpu-set=")-1 + PROPERTY_VALUE_MAX]; + char dex2oatCpuSetImageBuf[sizeof("--cpu-set=")-1 + PROPERTY_VALUE_MAX]; char dex2oat_isa_variant_key[PROPERTY_KEY_MAX]; char dex2oat_isa_variant[sizeof("--instruction-set-variant=") -1 + PROPERTY_VALUE_MAX]; char dex2oat_isa_features_key[PROPERTY_KEY_MAX]; @@ -956,6 +958,10 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p parseCompilerOption("dalvik.vm.dex2oat-threads", dex2oatThreadsBuf, "-j", "-Xcompiler-option"); parseCompilerOption("dalvik.vm.image-dex2oat-threads", dex2oatThreadsImageBuf, "-j", "-Ximage-compiler-option"); + parseCompilerOption("dalvik.vm.dex2oat-cpu-set", dex2oatCpuSetBuf, "--cpu-set=", + "-Xcompiler-option"); + parseCompilerOption("dalvik.vm.image-dex2oat-cpu-set", dex2oatCpuSetImageBuf, "--cpu-set=", + "-Ximage-compiler-option"); // The runtime will compile a boot image, when necessary, not using installd. Thus, we need to // pass the instruction-set-features/variant as an image-compiler-option. diff --git a/core/jni/core_jni_helpers.h b/core/jni/core_jni_helpers.h index 16ef753c0cd0..f03f42737134 100644 --- a/core/jni/core_jni_helpers.h +++ b/core/jni/core_jni_helpers.h @@ -22,6 +22,18 @@ #include <nativehelper/scoped_utf_chars.h> #include <android_runtime/AndroidRuntime.h> +// Host targets (layoutlib) do not differentiate between regular and critical native methods, +// and they need all the JNI methods to have JNIEnv* and jclass/jobject as their first two arguments. +// The following macro allows to have those arguments when compiling for host while omitting them when +// compiling for Android. +#ifdef __ANDROID__ +#define CRITICAL_JNI_PARAMS +#define CRITICAL_JNI_PARAMS_COMMA +#else +#define CRITICAL_JNI_PARAMS JNIEnv*, jclass +#define CRITICAL_JNI_PARAMS_COMMA JNIEnv*, jclass, +#endif + namespace android { // Defines some helpful functions. diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 1f20d7afb983..74b4f34ebbf4 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -142,7 +142,7 @@ <protected-broadcast android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" /> <protected-broadcast android:name="android.bluetooth.device.action.UUID" /> <protected-broadcast android:name="android.bluetooth.device.action.MAS_INSTANCE" /> - <protected-broadcast android:name="android.bluetooth.device.action.ALIAS_CHANGED" /> + <protected-broadcast android:name="android.bluetooth.action.ALIAS_CHANGED" /> <protected-broadcast android:name="android.bluetooth.device.action.FOUND" /> <protected-broadcast android:name="android.bluetooth.device.action.CLASS_CHANGED" /> <protected-broadcast android:name="android.bluetooth.device.action.ACL_CONNECTED" /> @@ -1626,7 +1626,7 @@ @hide This should only be used by Settings and SystemUI. --> <permission android:name="android.permission.NETWORK_SETTINGS" - android:protectionLevel="signature" /> + android:protectionLevel="signature|telephony" /> <!-- Allows SetupWizard to call methods in Networking services <p>Not for use by any other third-party or privileged applications. @@ -2146,12 +2146,12 @@ <!-- Must be required by a telephony data service to ensure that only the system can bind to it. - <p>Protection level: signature + <p>Protection level: signature|telephony @SystemApi @hide --> <permission android:name="android.permission.BIND_TELEPHONY_DATA_SERVICE" - android:protectionLevel="signature" /> + android:protectionLevel="signature|telephony" /> <!-- Must be required by a NetworkService to ensure that only the system can bind to it. @@ -2172,11 +2172,11 @@ <!-- @SystemApi Must be required by an EuiccService to ensure that only the system can bind to it. - <p>Protection level: signature + <p>Protection level: signature|telephony @hide --> <permission android:name="android.permission.BIND_EUICC_SERVICE" - android:protectionLevel="signature" /> + android:protectionLevel="signature|telephony" /> <!-- ================================== --> <!-- Permissions for sdcard interaction --> @@ -2956,7 +2956,7 @@ @hide --> <permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" - android:protectionLevel="signature" /> + android:protectionLevel="signature|telephony" /> <!-- @SystemApi Allows an application to use {@link android.view.WindowManager.LayoutsParams#SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS} @@ -3736,7 +3736,7 @@ @hide --> <permission android:name="android.permission.DEVICE_POWER" - android:protectionLevel="signature" /> + android:protectionLevel="signature|telephony" /> <!-- Allows toggling battery saver on the system. Superseded by DEVICE_POWER permission. @hide @SystemApi @@ -3771,13 +3771,13 @@ <p>Not for use by third-party applications. --> <permission android:name="android.permission.BROADCAST_SMS" - android:protectionLevel="signature" /> + android:protectionLevel="signature|telephony" /> <!-- Allows an application to broadcast a WAP PUSH receipt notification. <p>Not for use by third-party applications. --> <permission android:name="android.permission.BROADCAST_WAP_PUSH" - android:protectionLevel="signature" /> + android:protectionLevel="signature|telephony" /> <!-- @SystemApi Allows an application to broadcast privileged networking requests. <p>Not for use by third-party applications. @@ -4392,13 +4392,13 @@ {@link android.provider.BlockedNumberContract}. @hide --> <permission android:name="android.permission.READ_BLOCKED_NUMBERS" - android:protectionLevel="signature" /> + android:protectionLevel="signature|telephony" /> <!-- Allows the holder to write blocked numbers. See {@link android.provider.BlockedNumberContract}. @hide --> <permission android:name="android.permission.WRITE_BLOCKED_NUMBERS" - android:protectionLevel="signature" /> + android:protectionLevel="signature|telephony" /> <!-- Must be required by an {@link android.service.vr.VrListenerService}, to ensure that only the system can bind to it. diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 77fca8fe4d8e..17045d812f4b 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -295,6 +295,9 @@ <!-- Additional flag from base permission type: this permission can be automatically granted to the system app predictor --> <flag name="appPredictor" value="0x200000" /> + <!-- Additional flag from base permission type: this permission can be automatically + granted to the system telephony apps --> + <flag name="telephony" value="0x400000" /> </attr> <!-- Flags indicating more context for a permission group. --> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 6c0fe46563c4..84d4857b032d 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3677,6 +3677,15 @@ --> <string name="config_defaultWellbeingPackage" translatable="false"></string> + + <!-- The package name for the system telephony apps. + This package must be trusted, as it will be granted with permissions with special telephony + protection level. Note, framework by default support multiple telephony apps, each package + name is separated by comma. + Example: "com.android.phone,com.android.stk,com.android.providers.telephony" + --> + <string name="config_telephonyPackages" translatable="false">"com.android.phone,com.android.stk,com.android.providers.telephony,com.android.ons"</string> + <!-- The component name for the default system attention service. This service must be trusted, as it can be activated without explicit consent of the user. See android.attention.AttentionManagerService. diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 6efa2d653b4c..e729b03c1b82 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -3056,9 +3056,9 @@ <string name="ok">OK</string> <!-- Preference framework strings. --> <string name="cancel">Cancel</string> - <!-- Preference framework strings. --> + <!-- Preference framework strings. {@deprecated Do not use. Incorrectly matches android.R.string.ok rather than "yes".} --> <string name="yes">OK</string> - <!-- Preference framework strings. --> + <!-- Preference framework strings. {@deprecated Do not use. Incorrectly matches android.R.string.cancel rather than "no".} --> <string name="no">Cancel</string> <!-- This is the generic "attention" string to be used in attention dialogs. Typically combined with setIconAttribute(android.R.attr.alertDialogIcon) diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 0804703a585b..e8cd271118dc 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3464,6 +3464,7 @@ <java-symbol type="string" name="config_defaultAutofillService" /> <java-symbol type="string" name="config_defaultTextClassifierPackage" /> <java-symbol type="string" name="config_defaultWellbeingPackage" /> + <java-symbol type="string" name="config_telephonyPackages" /> <java-symbol type="string" name="config_defaultContentCaptureService" /> <java-symbol type="string" name="config_defaultAugmentedAutofillService" /> <java-symbol type="string" name="config_defaultAppPredictionService" /> diff --git a/media/java/android/media/tv/OWNER b/media/java/android/media/tv/OWNERS index 64c0bb53e894..64c0bb53e894 100644 --- a/media/java/android/media/tv/OWNER +++ b/media/java/android/media/tv/OWNERS diff --git a/packages/CtsShim/Android.bp b/packages/CtsShim/Android.bp new file mode 100644 index 000000000000..7728464f8652 --- /dev/null +++ b/packages/CtsShim/Android.bp @@ -0,0 +1,74 @@ +// +// Copyright (C) 2016 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +//########################################################## +// Variant: Privileged app + +android_app_import { + name: "CtsShimPrivPrebuilt", + + // this needs to be a privileged application + privileged: true, + + // Make sure the build system doesn't try to resign the APK + dex_preopt: { + enabled: false, + }, + + arch: { + arm: { + apk: "apk/arm/CtsShimPriv.apk", + }, + arm64: { + apk: "apk/arm/CtsShimPriv.apk", + }, + x86: { + apk: "apk/x86/CtsShimPriv.apk", + }, + x86_64: { + apk: "apk/x86/CtsShimPriv.apk", + }, + }, + presigned: true, +} + +//########################################################## +// Variant: System app + +android_app_import { + name: "CtsShimPrebuilt", + + // Make sure the build system doesn't try to resign the APK + dex_preopt: { + enabled: false, + }, + + arch: { + arm: { + apk: "apk/arm/CtsShim.apk", + }, + arm64: { + apk: "apk/arm/CtsShim.apk", + }, + x86: { + apk: "apk/x86/CtsShim.apk", + }, + x86_64: { + apk: "apk/x86/CtsShim.apk", + }, + }, + presigned: true, +} diff --git a/packages/CtsShim/Android.mk b/packages/CtsShim/Android.mk deleted file mode 100644 index 12972f14514b..000000000000 --- a/packages/CtsShim/Android.mk +++ /dev/null @@ -1,64 +0,0 @@ -# -# Copyright (C) 2016 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -LOCAL_PATH := $(call my-dir) - -########################################################### -# Variant: Privileged app - -include $(CLEAR_VARS) - -LOCAL_MODULE := CtsShimPrivPrebuilt -LOCAL_MODULE_TAGS := optional -# this needs to be a privileged application -LOCAL_PRIVILEGED_MODULE := true -LOCAL_MODULE_CLASS := APPS -LOCAL_BUILT_MODULE_STEM := package.apk -# Make sure the build system doesn't try to resign the APK -LOCAL_CERTIFICATE := PRESIGNED -LOCAL_DEX_PREOPT := false -LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64 - -LOCAL_SRC_FILES_arm := apk/arm/CtsShimPriv.apk -LOCAL_SRC_FILES_arm64 := apk/arm/CtsShimPriv.apk -LOCAL_SRC_FILES_x86 := apk/x86/CtsShimPriv.apk -LOCAL_SRC_FILES_x86_64 := apk/x86/CtsShimPriv.apk - -include $(BUILD_PREBUILT) - - -########################################################### -# Variant: System app - -include $(CLEAR_VARS) - -LOCAL_MODULE := CtsShimPrebuilt -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_CLASS := APPS -LOCAL_BUILT_MODULE_STEM := package.apk -# Make sure the build system doesn't try to resign the APK -LOCAL_CERTIFICATE := PRESIGNED -LOCAL_DEX_PREOPT := false -LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64 - -LOCAL_SRC_FILES_arm := apk/arm/CtsShim.apk -LOCAL_SRC_FILES_arm64 := apk/arm/CtsShim.apk -LOCAL_SRC_FILES_x86 := apk/x86/CtsShim.apk -LOCAL_SRC_FILES_x86_64 := apk/x86/CtsShim.apk - -include $(BUILD_PREBUILT) - -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/packages/CtsShim/build/Android.bp b/packages/CtsShim/build/Android.bp new file mode 100644 index 000000000000..ede1fab64973 --- /dev/null +++ b/packages/CtsShim/build/Android.bp @@ -0,0 +1,117 @@ +// Copyright (C) 2019 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. + +// Build rules to build shim apks. + +//########################################################## +// Variant: Privileged app upgrade + +android_app { + name: "CtsShimPrivUpgrade", + // this needs to be a privileged application + privileged: true, + + sdk_version: "current", + optimize: { + enabled: false, + }, + dex_preopt: { + enabled: false, + }, + + manifest: "shim_priv_upgrade/AndroidManifest.xml", + + compile_multilib: "both", + jni_libs: ["libshim_jni"], +} + +genrule { + name: "generate_priv_manifest", + srcs: [ + "shim_priv/AndroidManifest.xml", + ":CtsShimPrivUpgrade" + ], + out: ["AndroidManifest.xml"], + cmd: "sed -e s/__HASH__/`sha512sum -b $(location :CtsShimPrivUpgrade) | cut -d' ' -f1`/ $(location shim_priv/AndroidManifest.xml) > $(out)", +} + +//########################################################## +// Variant: Privileged app + +android_app { + name: "CtsShimPriv", + // this needs to be a privileged application + privileged: true, + + sdk_version: "current", + optimize: { + enabled: false, + }, + dex_preopt: { + enabled: false, + }, + + manifest: ":generate_priv_manifest", + + compile_multilib: "both", + jni_libs: ["libshim_jni"], + // Explicitly uncompress native libs rather than letting the build system doing it and destroy the + // v2/v3 signature. + use_embedded_native_libs: true, +} + +//########################################################## +// Variant: Privileged app upgrade w/ the wrong SHA + +android_app { + name: "CtsShimPrivUpgradeWrongSHA", + // this needs to be a privileged application + privileged: true, + + sdk_version: "current", + optimize: { + enabled: false, + }, + dex_preopt: { + enabled: false, + }, + // anything to make this package's SHA different from CtsShimPrivUpgrade + aaptflags: [ + "--version-name", + "WrongSHA", + ], + + manifest: "shim_priv_upgrade/AndroidManifest.xml", + + compile_multilib: "both", + jni_libs: ["libshim_jni"], + +} + +//########################################################## +// Variant: System app + +android_app { + name: "CtsShim", + + sdk_version: "current", + optimize: { + enabled: false, + }, + dex_preopt: { + enabled: false, + }, + + manifest: "shim/AndroidManifest.xml", +} diff --git a/packages/CtsShim/build/Android.mk b/packages/CtsShim/build/Android.mk deleted file mode 100644 index 03eb0d9aad5a..000000000000 --- a/packages/CtsShim/build/Android.mk +++ /dev/null @@ -1,116 +0,0 @@ -# -# Copyright (C) 2016 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -LOCAL_PATH := $(my-dir) - -########################################################### -# Variant: Privileged app upgrade - -include $(CLEAR_VARS) -# this needs to be a privileged application -LOCAL_PRIVILEGED_MODULE := true - -LOCAL_MODULE_TAGS := optional -LOCAL_SDK_VERSION := current -LOCAL_PROGUARD_ENABLED := disabled -LOCAL_DEX_PREOPT := false - -LOCAL_PACKAGE_NAME := CtsShimPrivUpgrade - -LOCAL_MANIFEST_FILE := shim_priv_upgrade/AndroidManifest.xml - -LOCAL_MULTILIB := both -LOCAL_JNI_SHARED_LIBRARIES := libshim_jni - -include $(BUILD_PACKAGE) -my_shim_priv_upgrade_apk := $(LOCAL_BUILT_MODULE) - -########################################################### -# Variant: Privileged app - -include $(CLEAR_VARS) -# this needs to be a privileged application -LOCAL_PRIVILEGED_MODULE := true - -LOCAL_MODULE_TAGS := optional -LOCAL_SDK_VERSION := current -LOCAL_PROGUARD_ENABLED := disabled -LOCAL_DEX_PREOPT := false - -LOCAL_PACKAGE_NAME := CtsShimPriv - -# Generate the upgrade key by taking the hash of the built CtsShimPrivUpgrade apk -gen := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),,true)/AndroidManifest.xml -$(gen): PRIVATE_CUSTOM_TOOL = sed -e "s/__HASH__/`sha512sum $(PRIVATE_INPUT_APK) | cut -d' ' -f1`/" $< >$@ -$(gen): PRIVATE_INPUT_APK := $(my_shim_priv_upgrade_apk) -$(gen): $(LOCAL_PATH)/shim_priv/AndroidManifest.xml $(my_shim_priv_upgrade_apk) - $(transform-generated-source) - -my_shim_priv_upgrade_apk := - -LOCAL_FULL_MANIFEST_FILE := $(gen) - -LOCAL_MULTILIB := both -LOCAL_JNI_SHARED_LIBRARIES := libshim_jni - -LOCAL_USE_AAPT2 := true - -include $(BUILD_PACKAGE) - -########################################################### -# Variant: Privileged app upgrade w/ the wrong SHA - -include $(CLEAR_VARS) -# this needs to be a privileged application -LOCAL_PRIVILEGED_MODULE := true - -LOCAL_MODULE_TAGS := optional -LOCAL_SDK_VERSION := current -LOCAL_PROGUARD_ENABLED := disabled -LOCAL_DEX_PREOPT := false -# anything to make this package's SHA different from CtsShimPrivUpgrade -LOCAL_AAPT_FLAGS := --version-name WrongSHA - -LOCAL_PACKAGE_NAME := CtsShimPrivUpgradeWrongSHA - -LOCAL_MANIFEST_FILE := shim_priv_upgrade/AndroidManifest.xml - -LOCAL_MULTILIB := both -LOCAL_JNI_SHARED_LIBRARIES := libshim_jni - -include $(BUILD_PACKAGE) - - -########################################################### -# Variant: System app - -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional -LOCAL_SDK_VERSION := current -LOCAL_PROGUARD_ENABLED := disabled -LOCAL_DEX_PREOPT := false - -LOCAL_PACKAGE_NAME := CtsShim - -LOCAL_MANIFEST_FILE := shim/AndroidManifest.xml - -LOCAL_USE_AAPT2 := true - -include $(BUILD_PACKAGE) - -########################################################### -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java index 738c4257d2c5..19ae97070188 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java @@ -102,9 +102,10 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { Thread thread = new Thread( () -> { - mDynSystem.startInstallation("userdata", mUserdataSize, false); + mDynSystem.startInstallation(); + mDynSystem.createPartition("userdata", mUserdataSize, false); mInstallationSession = - mDynSystem.startInstallation("system", mSystemSize, true); + mDynSystem.createPartition("system", mSystemSize, true); }); thread.start(); @@ -157,6 +158,7 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { reportedInstalledSize = installedSize; } } + mDynSystem.finishInstallation(); return null; } catch (Exception e) { diff --git a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java index bc5a2c05e379..69bd0ed0c59c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/DeviceInfoUtils.java @@ -29,6 +29,8 @@ import android.system.StructUtsname; import android.telephony.PhoneNumberUtils; import android.telephony.SubscriptionInfo; import android.telephony.TelephonyManager; +import android.text.BidiFormatter; +import android.text.TextDirectionHeuristics; import android.text.TextUtils; import android.text.format.DateFormat; import android.util.Log; @@ -206,4 +208,15 @@ public class DeviceInfoUtils { return sb.toString(); } + /** + * To get the formatting text for display in a potentially opposite-directionality context + * without garbling. + * @param subscriptionInfo {@link SubscriptionInfo} subscription information. + * @return Returns phone number with Bidi format. + */ + public static String getBidiFormattedPhoneNumber(Context context, + SubscriptionInfo subscriptionInfo) { + final String phoneNumber = getFormattedPhoneNumber(context, subscriptionInfo); + return BidiFormatter.getInstance().unicodeWrap(phoneNumber, TextDirectionHeuristics.LTR); + } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 9a95288a69ae..ec5bc96f574c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -363,12 +363,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> /** * Get name from remote device - * @return {@link BluetoothDevice#getAliasName()} if - * {@link BluetoothDevice#getAliasName()} is not null otherwise return + * @return {@link BluetoothDevice#getAlias()} if + * {@link BluetoothDevice#getAlias()} is not null otherwise return * {@link BluetoothDevice#getAddress()} */ public String getName() { - final String aliasName = mDevice.getAliasName(); + final String aliasName = mDevice.getAlias(); return TextUtils.isEmpty(aliasName) ? getAddress() : aliasName; } @@ -426,7 +426,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> * @return true if device's alias name is not null nor empty, false otherwise */ public boolean hasHumanReadableName() { - return !TextUtils.isEmpty(mDevice.getAliasName()); + return !TextUtils.isEmpty(mDevice.getAlias()); } /** @@ -573,7 +573,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } if (BluetoothUtils.D) { - Log.e(TAG, "updating profiles for " + mDevice.getAliasName() + ", " + mDevice); + Log.e(TAG, "updating profiles for " + mDevice.getAlias() + ", " + mDevice); BluetoothClass bluetoothClass = mDevice.getBluetoothClass(); if (bluetoothClass != null) Log.v(TAG, "Class: " + bluetoothClass.toString()); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java index 33e754044873..7050db14bfb1 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java @@ -166,7 +166,7 @@ public class CachedBluetoothDeviceManager { return cachedDevice.getName(); } - String name = device.getAliasName(); + String name = device.getAlias(); if (name != null) { return name; } diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java index ea3c1d95925c..092cbf3c7c12 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java @@ -222,7 +222,8 @@ public class DataUsageController { } } - return TelephonyManager.from(mContext).createForSubscriptionId(subscriptionId); + return mContext.getSystemService( + TelephonyManager.class).createForSubscriptionId(subscriptionId); } public void setMobileDataEnabled(boolean enabled) { diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS b/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS index d5d2e9e8c146..f506b7c12d81 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS @@ -1,7 +1,7 @@ # Default reviewers for this and subdirectories. +qal@google.com +arcwang@google.com +govenliu@google.com asapperstein@google.com -asargent@google.com -dling@google.com -zhfan@google.com # Emergency approvers in case the above are not available
\ No newline at end of file diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java index dc47de8546db..c37509b55f7f 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java @@ -95,9 +95,9 @@ public class CachedBluetoothDeviceManagerTest { when(mDevice1.getName()).thenReturn(DEVICE_NAME_1); when(mDevice2.getName()).thenReturn(DEVICE_NAME_2); when(mDevice3.getName()).thenReturn(DEVICE_NAME_3); - when(mDevice1.getAliasName()).thenReturn(DEVICE_ALIAS_1); - when(mDevice2.getAliasName()).thenReturn(DEVICE_ALIAS_2); - when(mDevice3.getAliasName()).thenReturn(DEVICE_ALIAS_3); + when(mDevice1.getAlias()).thenReturn(DEVICE_ALIAS_1); + when(mDevice2.getAlias()).thenReturn(DEVICE_ALIAS_2); + when(mDevice3.getAlias()).thenReturn(DEVICE_ALIAS_3); when(mDevice1.getBluetoothClass()).thenReturn(DEVICE_CLASS_1); when(mDevice2.getBluetoothClass()).thenReturn(DEVICE_CLASS_2); when(mDevice3.getBluetoothClass()).thenReturn(DEVICE_CLASS_2); @@ -224,7 +224,7 @@ public class CachedBluetoothDeviceManagerTest { assertThat(cachedDevice1.getName()).isEqualTo(DEVICE_ALIAS_1); final String newAliasName = "NewAliasName"; - when(mDevice1.getAliasName()).thenReturn(newAliasName); + when(mDevice1.getAlias()).thenReturn(newAliasName); mCachedDeviceManager.onDeviceNameUpdated(mDevice1); assertThat(cachedDevice1.getName()).isEqualTo(newAliasName); } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java index 93dcbfeab172..999916d39cd0 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java @@ -699,7 +699,7 @@ public class CachedBluetoothDeviceTest { @Test public void deviceName_testAliasNameAvailable() { - when(mDevice.getAliasName()).thenReturn(DEVICE_ALIAS); + when(mDevice.getAlias()).thenReturn(DEVICE_ALIAS); when(mDevice.getName()).thenReturn(DEVICE_NAME); CachedBluetoothDevice cachedBluetoothDevice = new CachedBluetoothDevice(mContext, mProfileManager, mDevice); @@ -722,7 +722,7 @@ public class CachedBluetoothDeviceTest { @Test public void deviceName_testRenameDevice() { final String[] alias = {DEVICE_ALIAS}; - doAnswer(invocation -> alias[0]).when(mDevice).getAliasName(); + doAnswer(invocation -> alias[0]).when(mDevice).getAlias(); doAnswer(invocation -> { alias[0] = (String) invocation.getArguments()[0]; return true; @@ -839,14 +839,14 @@ public class CachedBluetoothDeviceTest { @Test public void getName_aliasNameNotNull_returnAliasName() { - when(mDevice.getAliasName()).thenReturn(DEVICE_NAME); + when(mDevice.getAlias()).thenReturn(DEVICE_NAME); assertThat(mCachedDevice.getName()).isEqualTo(DEVICE_NAME); } @Test public void getName_aliasNameIsNull_returnAddress() { - when(mDevice.getAliasName()).thenReturn(null); + when(mDevice.getAlias()).thenReturn(null); assertThat(mCachedDevice.getName()).isEqualTo(DEVICE_ADDRESS); } @@ -854,7 +854,7 @@ public class CachedBluetoothDeviceTest { @Test public void setName_setDeviceNameIsNotNull() { final String name = "test name"; - when(mDevice.getAliasName()).thenReturn(DEVICE_NAME); + when(mDevice.getAlias()).thenReturn(DEVICE_NAME); mCachedDevice.setName(name); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java index 2b5466c4161f..7be176a37bb4 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java @@ -75,8 +75,8 @@ public class HearingAidDeviceManagerTest { when(mDevice2.getAddress()).thenReturn(DEVICE_ADDRESS_2); when(mDevice1.getName()).thenReturn(DEVICE_NAME_1); when(mDevice2.getName()).thenReturn(DEVICE_NAME_2); - when(mDevice1.getAliasName()).thenReturn(DEVICE_ALIAS_1); - when(mDevice2.getAliasName()).thenReturn(DEVICE_ALIAS_2); + when(mDevice1.getAlias()).thenReturn(DEVICE_ALIAS_1); + when(mDevice2.getAlias()).thenReturn(DEVICE_ALIAS_2); when(mDevice1.getBluetoothClass()).thenReturn(DEVICE_CLASS); when(mDevice2.getBluetoothClass()).thenReturn(DEVICE_CLASS); when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java index 3da5e766c389..f7bee30a087f 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java @@ -75,7 +75,7 @@ public class DataUsageControllerTest { public void setUp() throws RemoteException { MockitoAnnotations.initMocks(this); when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager); - when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); + when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager); when(mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)) .thenReturn(mSubscriptionManager); when(mContext.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java index 4b56f037f8ed..f73ca1c36005 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java @@ -24,6 +24,7 @@ import android.net.ConnectivityManager; import android.net.wifi.WifiClient; import android.net.wifi.WifiManager; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.UserManager; import android.util.Log; @@ -109,7 +110,8 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof mCallbacks.add(callback); if (mWifiManager != null) { if (mCallbacks.size() == 1) { - mWifiManager.registerSoftApCallback(this, mMainHandler); + mWifiManager.registerSoftApCallback(this, + new HandlerExecutor(mMainHandler)); } else { // mWifiManager#registerSoftApCallback triggers a call to // onConnectedClientsChanged on the Main Handler. In order to always update diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java index 7f32ad5c6c1f..7496e3ade351 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java @@ -43,6 +43,7 @@ import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import java.util.ArrayList; +import java.util.concurrent.Executor; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -73,7 +74,7 @@ public class HotspotControllerImplTest extends SysuiTestCase { .onConnectedClientsChanged(new ArrayList<>()); return null; }).when(mWifiManager).registerSoftApCallback(any(WifiManager.SoftApCallback.class), - any(Handler.class)); + any(Executor.class)); mController = new HotspotControllerImpl(mContext, new Handler(mLooper.getLooper())); } diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java index 190e6cf2d35c..7b02b6e0ac11 100644 --- a/services/core/java/com/android/server/DynamicSystemService.java +++ b/services/core/java/com/android/server/DynamicSystemService.java @@ -18,7 +18,6 @@ package com.android.server; import android.content.Context; import android.content.pm.PackageManager; -import android.gsi.GsiInstallParams; import android.gsi.GsiProgress; import android.gsi.IGsiService; import android.gsi.IGsid; @@ -47,6 +46,7 @@ public class DynamicSystemService extends IDynamicSystemService.Stub implements private static final int GSID_ROUGH_TIMEOUT_MS = 8192; private static final String PATH_DEFAULT = "/data/gsi"; private Context mContext; + private String mInstallPath; private volatile IGsiService mGsiService; DynamicSystemService(Context context) { @@ -115,8 +115,8 @@ public class DynamicSystemService extends IDynamicSystemService.Stub implements } @Override - public boolean startInstallation(String name, long size, boolean readOnly) - throws RemoteException { + public boolean startInstallation() throws RemoteException { + IGsiService service = getGsiService(); // priority from high to low: sysprop -> sdcard -> /data String path = SystemProperties.get("os.aot.path"); if (path.isEmpty()) { @@ -138,14 +138,19 @@ public class DynamicSystemService extends IDynamicSystemService.Stub implements } Slog.i(TAG, "startInstallation -> " + path); } + mInstallPath = path; + if (service.openInstall(path) != 0) { + Slog.i(TAG, "Failed to open " + path); + return false; + } + return true; + } + + @Override + public boolean createPartition(String name, long size, boolean readOnly) + throws RemoteException { IGsiService service = getGsiService(); - GsiInstallParams installParams = new GsiInstallParams(); - installParams.installDir = path; - installParams.name = name; - installParams.size = size; - installParams.wipe = readOnly; - installParams.readOnly = readOnly; - if (service.beginGsiInstall(installParams) != 0) { + if (service.createPartition(name, size, readOnly) != 0) { Slog.i(TAG, "Failed to install " + name); return false; } @@ -153,6 +158,16 @@ public class DynamicSystemService extends IDynamicSystemService.Stub implements } @Override + public boolean finishInstallation() throws RemoteException { + IGsiService service = getGsiService(); + if (service.closeInstall() != 0) { + Slog.i(TAG, "Failed to finish installation"); + return false; + } + return true; + } + + @Override public GsiProgress getInstallationProgress() throws RemoteException { return getGsiService().getInstallProgress(); } @@ -190,6 +205,8 @@ public class DynamicSystemService extends IDynamicSystemService.Stub implements @Override public boolean remove() throws RemoteException { + IGsiService gsiService = getGsiService(); + String install_dir = gsiService.getInstalledGsiImageDir(); return getGsiService().removeGsi(); } diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java index 83ad4e7e7100..454941ccdb03 100644 --- a/services/core/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -89,6 +89,7 @@ public class Watchdog extends Thread { "/system/bin/drmserver", "/system/bin/mediadrmserver", "/system/bin/mediaserver", + "/system/bin/netd", "/system/bin/sdcard", "/system/bin/surfaceflinger", "/system/bin/vold", diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index e5c8ba515446..5af1480af94b 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -349,7 +349,6 @@ import com.android.server.ThreadPriorityBooster; import com.android.server.Watchdog; import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto; import com.android.server.appop.AppOpsService; -import com.android.server.compat.CompatConfig; import com.android.server.compat.PlatformCompat; import com.android.server.contentcapture.ContentCaptureManagerInternal; import com.android.server.firewall.IntentFirewall; @@ -5049,8 +5048,9 @@ public class ActivityManagerService extends IActivityManager.Stub bindApplicationTimeMillis = SystemClock.elapsedRealtime(); mAtmInternal.preBindApplication(app.getWindowProcessController()); final ActiveInstrumentation instr2 = app.getActiveInstrumentation(); - long[] disabledCompatChanges = CompatConfig.get().getDisabledChanges(app.info); + long[] disabledCompatChanges = {}; if (mPlatformCompat != null) { + disabledCompatChanges = mPlatformCompat.getDisabledChanges(app.info); mPlatformCompat.resetReporting(app.info); } if (app.isolatedEntryPoint != null) { diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 6e92e80424fa..d9e4844209d0 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -41,6 +41,7 @@ import android.app.usage.AppStandbyInfo; import android.app.usage.ConfigurationStats; import android.app.usage.IUsageStatsManager; import android.app.usage.UsageStatsManager; +import android.compat.Compatibility; import android.content.ComponentCallbacks2; import android.content.ComponentName; import android.content.Context; @@ -80,15 +81,17 @@ import android.os.UserManager; import android.text.TextUtils; import android.text.format.Time; import android.util.ArrayMap; +import android.util.ArraySet; import android.util.DebugUtils; import android.util.DisplayMetrics; import android.util.proto.ProtoOutputStream; import android.view.Display; +import com.android.internal.compat.CompatibilityChangeConfig; import com.android.internal.util.HexDump; import com.android.internal.util.MemInfoReader; import com.android.internal.util.Preconditions; -import com.android.server.compat.CompatConfig; +import com.android.server.compat.PlatformCompat; import java.io.BufferedReader; import java.io.File; @@ -2868,56 +2871,49 @@ final class ActivityManagerShellCommand extends ShellCommand { return 0; } - private void killPackage(String packageName, PrintWriter pw) throws RemoteException { - int uid = mPm.getPackageUid(packageName, 0, mUserId); - if (uid < 0) { - // uid is negative if the package wasn't found. - pw.println("Didn't find package " + packageName + " on device."); - } else { - pw.println("Killing package " + packageName + " (UID " + uid + ")."); - final long origId = Binder.clearCallingIdentity(); - mInterface.killUid(UserHandle.getAppId(uid), - UserHandle.USER_ALL, "killPackage"); - Binder.restoreCallingIdentity(origId); - } - } - private int runCompat(PrintWriter pw) throws RemoteException { - final CompatConfig config = CompatConfig.get(); + final PlatformCompat platformCompat = (PlatformCompat) + ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE); String toggleValue = getNextArgRequired(); long changeId; String changeIdString = getNextArgRequired(); try { changeId = Long.parseLong(changeIdString); } catch (NumberFormatException e) { - changeId = config.lookupChangeId(changeIdString); + changeId = platformCompat.lookupChangeId(changeIdString); } if (changeId == -1) { pw.println("Unknown or invalid change: '" + changeIdString + "'."); + return -1; } String packageName = getNextArgRequired(); + if (!platformCompat.isKnownChangeId(changeId)) { + pw.println("Warning! Change " + changeId + " is not known yet. Enabling/disabling it" + + " could have no effect."); + } + ArraySet<Long> enabled = new ArraySet<>(); + ArraySet<Long> disabled = new ArraySet<>(); switch (toggleValue) { case "enable": - if (!config.addOverride(changeId, packageName, true)) { - pw.println("Warning! Change " + changeId + " is not known yet. Enabling it" - + " could have no effect."); - } + enabled.add(changeId); pw.println("Enabled change " + changeId + " for " + packageName + "."); - killPackage(packageName, pw); + CompatibilityChangeConfig overrides = + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(enabled, disabled)); + platformCompat.setOverrides(overrides, packageName); return 0; case "disable": - if (!config.addOverride(changeId, packageName, false)) { - pw.println("Warning! Change " + changeId + " is not known yet. Disabling it" - + " could have no effect."); - } + disabled.add(changeId); pw.println("Disabled change " + changeId + " for " + packageName + "."); - killPackage(packageName, pw); + overrides = + new CompatibilityChangeConfig( + new Compatibility.ChangeConfig(enabled, disabled)); + platformCompat.setOverrides(overrides, packageName); return 0; case "reset": - if (config.removeOverride(changeId, packageName)) { + if (platformCompat.clearOverride(changeId, packageName)) { pw.println("Reset change " + changeId + " for " + packageName + " to default value."); - killPackage(packageName, pw); } else { pw.println("No override exists for changeId " + changeId + "."); } diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java index 525531635df6..0524f91a01fb 100644 --- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java +++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java @@ -445,7 +445,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_RADIO) != 0) { // We were asked to fetch Telephony data. if (mTelephony == null) { - mTelephony = TelephonyManager.from(mContext); + mTelephony = mContext.getSystemService(TelephonyManager.class); } if (mTelephony != null) { diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index c2f452932775..567404697395 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -731,7 +731,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub public void notePhoneState(int state) { enforceCallingPermission(); - int simState = TelephonyManager.getDefault().getSimState(); + int simState = mContext.getSystemService(TelephonyManager.class).getSimState(); synchronized (mStats) { mStats.notePhoneStateLocked(state, simState); } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 1f1e8a5b3868..48f08e3226e3 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -3911,8 +3911,7 @@ public class AudioService extends IAudioService.Stub final boolean muteSystem = (zenPolicy.priorityCategories & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0; final boolean muteNotificationAndRing = ZenModeConfig - .areAllPriorityOnlyNotificationZenSoundsMuted( - mNm.getConsolidatedNotificationPolicy()); + .areAllPriorityOnlyNotificationZenSoundsMuted(zenPolicy); return muteAlarms && isAlarm(streamType) || muteMedia && isMedia(streamType) || muteSystem && isSystem(streamType) @@ -3924,11 +3923,13 @@ public class AudioService extends IAudioService.Stub } /** - * DND total silence: media and alarms streams are tied to the muted ringer - * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)} - * DND alarms only: notification, ringer + system muted (by default tied to muted ringer mode) - * DND priority only: alarms, media, system streams can be muted separate from ringer based on - * zenPolicy (this method determines which streams) + * Notifications, ringer and system sounds are controlled by the ringer: + * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)} but can + * also be muted by DND based on the DND mode: + * DND total silence: media and alarms streams can be muted by DND + * DND alarms only: no streams additionally controlled by DND + * DND priority only: alarms, media, system, ringer and notification streams can be muted by + * DND. The current applied zenPolicy determines which streams will be muted by DND. * @return true if changed, else false */ private boolean updateZenModeAffectedStreams() { @@ -3949,6 +3950,11 @@ public class AudioService extends IAudioService.Stub & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) { zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM; } + + if (ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(zenPolicy)) { + zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION; + zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING; + } } if (mZenModeAffectedStreams != zenModeAffectedStreams) { diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java index d6ec22b078ea..490cce347188 100644 --- a/services/core/java/com/android/server/compat/CompatConfig.java +++ b/services/core/java/com/android/server/compat/CompatConfig.java @@ -43,13 +43,14 @@ import java.util.HashSet; import java.util.Set; import javax.xml.datatype.DatatypeConfigurationException; + /** * This class maintains state relating to platform compatibility changes. * * <p>It stores the default configuration for each change, and any per-package overrides that have * been configured. */ -public final class CompatConfig { +final class CompatConfig { private static final String TAG = "CompatConfig"; @@ -61,13 +62,13 @@ public final class CompatConfig { private final LongSparseArray<CompatChange> mChanges = new LongSparseArray<>(); @VisibleForTesting - public CompatConfig() { + CompatConfig() { } /** * @return The static instance of this class to be used within the system server. */ - public static CompatConfig get() { + static CompatConfig get() { return sInstance; } @@ -77,7 +78,7 @@ public final class CompatConfig { * * @param change The change to add. Any change with the same ID will be overwritten. */ - public void addChange(CompatChange change) { + void addChange(CompatChange change) { synchronized (mChanges) { mChanges.put(change.getId(), change); } @@ -89,10 +90,10 @@ public final class CompatConfig { * * @param app The app in question * @return A sorted long array of change IDs. We use a primitive array to minimize memory - * footprint: Every app process will store this array statically so we aim to reduce - * overhead as much as possible. + * footprint: Every app process will store this array statically so we aim to reduce + * overhead as much as possible. */ - public long[] getDisabledChanges(ApplicationInfo app) { + long[] getDisabledChanges(ApplicationInfo app) { LongArray disabled = new LongArray(); synchronized (mChanges) { for (int i = 0; i < mChanges.size(); ++i) { @@ -113,7 +114,7 @@ public final class CompatConfig { * @param name Name of the change to look up * @return The change ID, or {@code -1} if no change with that name exists. */ - public long lookupChangeId(String name) { + long lookupChangeId(String name) { synchronized (mChanges) { for (int i = 0; i < mChanges.size(); ++i) { if (TextUtils.equals(mChanges.valueAt(i).getName(), name)) { @@ -128,11 +129,11 @@ public final class CompatConfig { * Find if a given change is enabled for a given application. * * @param changeId The ID of the change in question - * @param app App to check for + * @param app App to check for * @return {@code true} if the change is enabled for this app. Also returns {@code true} if the - * change ID is not known, as unknown changes are enabled by default. + * change ID is not known, as unknown changes are enabled by default. */ - public boolean isChangeEnabled(long changeId, ApplicationInfo app) { + boolean isChangeEnabled(long changeId, ApplicationInfo app) { synchronized (mChanges) { CompatChange c = mChanges.get(changeId); if (c == null) { @@ -150,14 +151,15 @@ public final class CompatConfig { * * <p>Note, package overrides are not persistent and will be lost on system or runtime restart. * - * @param changeId The ID of the change to be overridden. Note, this call will succeed even if - * this change is not known; it will only have any effect if any code in the - * platform is gated on the ID given. + * @param changeId The ID of the change to be overridden. Note, this call will succeed even + * if + * this change is not known; it will only have any effect if any code in the + * platform is gated on the ID given. * @param packageName The app package name to override the change for. - * @param enabled If the change should be enabled or disabled. + * @param enabled If the change should be enabled or disabled. * @return {@code true} if the change existed before adding the override. */ - public boolean addOverride(long changeId, String packageName, boolean enabled) { + boolean addOverride(long changeId, String packageName, boolean enabled) { boolean alreadyKnown = true; synchronized (mChanges) { CompatChange c = mChanges.get(changeId); @@ -172,15 +174,27 @@ public final class CompatConfig { } /** + * Check whether the change is known to the compat config. + * + * @return {@code true} if the change is known. + */ + boolean isKnownChangeId(long changeId) { + synchronized (mChanges) { + CompatChange c = mChanges.get(changeId); + return c != null; + } + } + + /** * Removes an override previously added via {@link #addOverride(long, String, boolean)}. This * restores the default behaviour for the given change and app, once any app processes have been * restarted. * - * @param changeId The ID of the change that was overridden. + * @param changeId The ID of the change that was overridden. * @param packageName The app package name that was overridden. * @return {@code true} if an override existed; */ - public boolean removeOverride(long changeId, String packageName) { + boolean removeOverride(long changeId, String packageName) { boolean overrideExists = false; synchronized (mChanges) { CompatChange c = mChanges.get(changeId); @@ -191,22 +205,22 @@ public final class CompatConfig { } return overrideExists; } + /** * Overrides the enabled state for a given change and app. This method is intended to be used * *only* for debugging purposes. * * <p>Note, package overrides are not persistent and will be lost on system or runtime restart. * - * @param overrides list of overrides to default changes config. + * @param overrides list of overrides to default changes config. * @param packageName app for which the overrides will be applied. */ - public void addOverrides( - CompatibilityChangeConfig overrides, String packageName) { + void addOverrides(CompatibilityChangeConfig overrides, String packageName) { synchronized (mChanges) { - for (Long changeId: overrides.enabledChanges()) { + for (Long changeId : overrides.enabledChanges()) { addOverride(changeId, packageName, true); } - for (Long changeId: overrides.disabledChanges()) { + for (Long changeId : overrides.disabledChanges()) { addOverride(changeId, packageName, false); } } @@ -221,7 +235,7 @@ public final class CompatConfig { * * @param packageName The package for which the overrides should be purged. */ - public void removePackageOverrides(String packageName) { + void removePackageOverrides(String packageName) { synchronized (mChanges) { for (int i = 0; i < mChanges.size(); ++i) { mChanges.valueAt(i).removePackageOverride(packageName); @@ -230,11 +244,11 @@ public final class CompatConfig { } /** - * Dumps the current list of compatibility config information. - * - * @param pw The {@link PrintWriter} instance to which the information will be dumped. - */ - public void dumpConfig(PrintWriter pw) { + * Dumps the current list of compatibility config information. + * + * @param pw The {@link PrintWriter} instance to which the information will be dumped. + */ + void dumpConfig(PrintWriter pw) { synchronized (mChanges) { if (mChanges.size() == 0) { pw.println("No compat overrides."); @@ -252,10 +266,10 @@ public final class CompatConfig { * * @param applicationInfo the {@link ApplicationInfo} for which the info should be dumped. * @return A {@link CompatibilityChangeConfig} which contains the compat config info for the - * given app. + * given app. */ - public CompatibilityChangeConfig getAppConfig(ApplicationInfo applicationInfo) { + CompatibilityChangeConfig getAppConfig(ApplicationInfo applicationInfo) { Set<Long> enabled = new HashSet<>(); Set<Long> disabled = new HashSet<>(); synchronized (mChanges) { @@ -276,15 +290,15 @@ public final class CompatConfig { * * @return An array of {@link CompatibilityChangeInfo} with the current changes. */ - public CompatibilityChangeInfo[] dumpChanges() { + CompatibilityChangeInfo[] dumpChanges() { synchronized (mChanges) { CompatibilityChangeInfo[] changeInfos = new CompatibilityChangeInfo[mChanges.size()]; for (int i = 0; i < mChanges.size(); ++i) { CompatChange change = mChanges.valueAt(i); changeInfos[i] = new CompatibilityChangeInfo(change.getId(), - change.getName(), - change.getEnableAfterTargetSdk(), - change.getDisabled()); + change.getName(), + change.getEnableAfterTargetSdk(), + change.getDisabled()); } return changeInfos; } diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index 75e2d220898d..ae5ad7ea1261 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -16,9 +16,13 @@ package com.android.server.compat; +import android.app.ActivityManager; +import android.app.IActivityManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.os.Binder; +import android.os.RemoteException; import android.os.UserHandle; import android.util.Slog; import android.util.StatsLog; @@ -106,12 +110,32 @@ public class PlatformCompat extends IPlatformCompat.Stub { @Override public void setOverrides(CompatibilityChangeConfig overrides, String packageName) { CompatConfig.get().addOverrides(overrides, packageName); + killPackage(packageName); + } + + @Override + public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName) { + CompatConfig.get().addOverrides(overrides, packageName); } @Override public void clearOverrides(String packageName) { CompatConfig config = CompatConfig.get(); config.removePackageOverrides(packageName); + killPackage(packageName); + } + + @Override + public void clearOverridesForTest(String packageName) { + CompatConfig config = CompatConfig.get(); + config.removePackageOverrides(packageName); + } + + @Override + public boolean clearOverride(long changeId, String packageName) { + boolean existed = CompatConfig.get().removeOverride(changeId, packageName); + killPackage(packageName); + return existed; } @Override @@ -124,6 +148,39 @@ public class PlatformCompat extends IPlatformCompat.Stub { return CompatConfig.get().dumpChanges(); } + /** + * Check whether the change is known to the compat config. + * @param changeId + * @return {@code true} if the change is known. + */ + public boolean isKnownChangeId(long changeId) { + return CompatConfig.get().isKnownChangeId(changeId); + + } + + /** + * Retrieves the set of disabled changes for a given app. Any change ID not in the returned + * array is by default enabled for the app. + * + * @param appInfo The app in question + * @return A sorted long array of change IDs. We use a primitive array to minimize memory + * footprint: Every app process will store this array statically so we aim to reduce + * overhead as much as possible. + */ + public long[] getDisabledChanges(ApplicationInfo appInfo) { + return CompatConfig.get().getDisabledChanges(appInfo); + } + + /** + * Look up a change ID by name. + * + * @param name Name of the change to look up + * @return The change ID, or {@code -1} if no change with that name exists. + */ + public long lookupChangeId(String name) { + return CompatConfig.get().lookupChangeId(name); + } + @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return; @@ -151,4 +208,34 @@ public class PlatformCompat extends IPlatformCompat.Stub { private void reportChange(long changeId, int uid, int state) { mChangeReporter.reportChange(uid, changeId, state); } + + private void killPackage(String packageName) { + int uid = -1; + try { + uid = mContext.getPackageManager().getPackageUid(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + Slog.w(TAG, "Didn't find package " + packageName + " on device.", e); + return; + } + + Slog.d(TAG, "Killing package " + packageName + " (UID " + uid + ")."); + killUid(UserHandle.getAppId(uid), + UserHandle.USER_ALL, "PlatformCompat overrides"); + } + + private void killUid(int appId, int userId, String reason) { + final long identity = Binder.clearCallingIdentity(); + try { + IActivityManager am = ActivityManager.getService(); + if (am != null) { + try { + am.killUid(appId, userId, reason); + } catch (RemoteException e) { + /* ignore - same process */ + } + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } } diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index b3804c4d7ec5..acedc3635730 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -286,8 +286,8 @@ public class Tethering extends BaseNetworkObserver { private void startStateMachineUpdaters(Handler handler) { mCarrierConfigChange.startListening(); - TelephonyManager.from(mContext).listen(mPhoneStateListener, - PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE); + mContext.getSystemService(TelephonyManager.class).listen( + mPhoneStateListener, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE); IntentFilter filter = new IntentFilter(); filter.addAction(UsbManager.ACTION_USB_STATE); diff --git a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java index 2e72fbd95931..93227bd78a81 100644 --- a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java +++ b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java @@ -321,7 +321,11 @@ class GnssNetworkConnectivityHandler { private void handleUpdateNetworkState(Network network, boolean isConnected, NetworkCapabilities capabilities) { - boolean networkAvailable = isConnected && TelephonyManager.getDefault().getDataEnabled(); + boolean networkAvailable = false; + TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class); + if (telephonyManager != null) { + networkAvailable = isConnected && telephonyManager.getDataEnabled(); + } NetworkAttributes networkAttributes = updateTrackedNetworksState(isConnected, network, capabilities); String apn = networkAttributes.mApn; diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 41806cabef3f..08c94267e969 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -337,7 +337,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager, - wakeLock, getDefaultClock(), TelephonyManager.getDefault(), + wakeLock, getDefaultClock(), context.getSystemService(TelephonyManager.class), new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(), new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir()); service.registerLocalService(); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 0d9dcff51b49..faac78d68879 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -7234,7 +7234,7 @@ public class NotificationManagerService extends SystemService { } private void listenForCallState() { - TelephonyManager.from(getContext()).listen(new PhoneStateListener() { + getContext().getSystemService(TelephonyManager.class).listen(new PhoneStateListener() { @Override public void onCallStateChanged(int state, String incomingNumber) { if (mCallState == state) return; diff --git a/services/core/java/com/android/server/pm/ComponentResolver.java b/services/core/java/com/android/server/pm/ComponentResolver.java index 8facce112b52..dbe83670d3a0 100644 --- a/services/core/java/com/android/server/pm/ComponentResolver.java +++ b/services/core/java/com/android/server/pm/ComponentResolver.java @@ -49,6 +49,7 @@ import android.util.Pair; import android.util.Slog; import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.ArrayUtils; import com.android.server.IntentResolver; import java.io.PrintWriter; @@ -375,8 +376,11 @@ public class ComponentResolver { addProvidersLocked(pkg, chatty); addServicesLocked(pkg, chatty); } - final String setupWizardPackage = sPackageManagerInternal.getKnownPackageName( - PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM); + // expect single setupwizard package + final String setupWizardPackage = ArrayUtils.firstOrNull( + sPackageManagerInternal.getKnownPackageNames( + PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM)); + for (int i = newIntents.size() - 1; i >= 0; --i) { final PackageParser.ActivityIntentInfo intentInfo = newIntents.get(i); final PackageParser.Package disabledPkg = sPackageManagerInternal @@ -410,8 +414,11 @@ public class ComponentResolver { final List<ActivityIntentInfo> protectedFilters = mProtectedFilters; mProtectedFilters = null; - final String setupWizardPackage = sPackageManagerInternal.getKnownPackageName( - PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM); + // expect single setupwizard package + final String setupWizardPackage = ArrayUtils.firstOrNull( + sPackageManagerInternal.getKnownPackageNames( + PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM)); + if (DEBUG_FILTERS && setupWizardPackage == null) { Slog.i(TAG, "No setup wizard;" + " All protected intents capped to priority 0"); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 868b90ac1f26..d7d73451e74b 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1406,6 +1406,7 @@ public class PackageManagerService extends IPackageManager.Stub final @Nullable String mConfiguratorPackage; final @Nullable String mAppPredictionServicePackage; final @Nullable String mIncidentReportApproverPackage; + final @Nullable String[] mTelephonyPackages; final @NonNull String mServicesSystemSharedLibraryPackageName; final @NonNull String mSharedSystemSharedLibraryPackageName; @@ -3116,6 +3117,7 @@ public class PackageManagerService extends IPackageManager.Stub mContext.getString(R.string.config_deviceConfiguratorPackageName); mAppPredictionServicePackage = getAppPredictionServicePackageName(); mIncidentReportApproverPackage = getIncidentReportApproverPackageName(); + mTelephonyPackages = getTelephonyPackageNames(); // Now that we know all of the shared libraries, update all clients to have // the correct library paths. @@ -21175,6 +21177,16 @@ public class PackageManagerService extends IPackageManager.Stub } @Override + public String[] getTelephonyPackageNames() { + String names = mContext.getString(R.string.config_telephonyPackages); + String[] telephonyPackageNames = null; + if (!TextUtils.isEmpty(names)) { + telephonyPackageNames = names.trim().split(","); + } + return telephonyPackageNames; + } + + @Override public void setApplicationEnabledSetting(String appPackageName, int newState, int flags, int userId, String callingPackage) { if (!sUserManager.exists(userId)) return; @@ -24323,34 +24335,36 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public String getKnownPackageName(int knownPackage, int userId) { + public @NonNull String[] getKnownPackageNames(int knownPackage, int userId) { switch(knownPackage) { case PackageManagerInternal.PACKAGE_BROWSER: - return getDefaultBrowserPackageName(userId); + return new String[]{getDefaultBrowserPackageName(userId)}; case PackageManagerInternal.PACKAGE_INSTALLER: - return mRequiredInstallerPackage; + return new String[]{mRequiredInstallerPackage}; case PackageManagerInternal.PACKAGE_SETUP_WIZARD: - return mSetupWizardPackage; + return new String[]{mSetupWizardPackage}; case PackageManagerInternal.PACKAGE_SYSTEM: - return "android"; + return new String[]{"android"}; case PackageManagerInternal.PACKAGE_VERIFIER: - return mRequiredVerifierPackage; + return new String[]{mRequiredVerifierPackage}; case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER: - return mSystemTextClassifierPackage; + return new String[]{mSystemTextClassifierPackage}; case PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER: - return mRequiredPermissionControllerPackage; + return new String[]{mRequiredPermissionControllerPackage}; case PackageManagerInternal.PACKAGE_WELLBEING: - return mWellbeingPackage; + return new String[]{mWellbeingPackage}; case PackageManagerInternal.PACKAGE_DOCUMENTER: - return mDocumenterPackage; + return new String[]{mDocumenterPackage}; case PackageManagerInternal.PACKAGE_CONFIGURATOR: - return mConfiguratorPackage; + return new String[]{mConfiguratorPackage}; case PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER: - return mIncidentReportApproverPackage; + return new String[]{mIncidentReportApproverPackage}; case PackageManagerInternal.PACKAGE_APP_PREDICTOR: - return mAppPredictionServicePackage; + return new String[]{mAppPredictionServicePackage}; + case PackageManagerInternal.PACKAGE_TELEPHONY: + return mTelephonyPackages; } - return null; + return ArrayUtils.emptyArray(String.class); } @Override diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java index 6d22faa7032e..c39dcfefb2e8 100644 --- a/services/core/java/com/android/server/pm/permission/BasePermission.java +++ b/services/core/java/com/android/server/pm/permission/BasePermission.java @@ -276,6 +276,9 @@ public final class BasePermission { public boolean isAppPredictor() { return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR) != 0; } + public boolean isTelephony() { + return (protectionLevel & PermissionInfo.PROTECTION_FLAG_TELEPHONY) != 0; + } public void transfer(@NonNull String origPackageName, @NonNull String newPackageName) { if (!origPackageName.equals(sourcePackageName)) { diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java index f76298592c2b..5870986a264f 100644 --- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java @@ -436,17 +436,20 @@ public final class DefaultPermissionGrantPolicy { // Installer grantSystemFixedPermissionsToSystemPackage( - getKnownPackage(PackageManagerInternal.PACKAGE_INSTALLER, userId), + ArrayUtils.firstOrNull(getKnownPackages( + PackageManagerInternal.PACKAGE_INSTALLER, userId)), userId, STORAGE_PERMISSIONS); // Verifier - final String verifier = getKnownPackage(PackageManagerInternal.PACKAGE_VERIFIER, userId); + final String verifier = ArrayUtils.firstOrNull(getKnownPackages( + PackageManagerInternal.PACKAGE_VERIFIER, userId)); grantSystemFixedPermissionsToSystemPackage(verifier, userId, STORAGE_PERMISSIONS); grantPermissionsToSystemPackage(verifier, userId, PHONE_PERMISSIONS, SMS_PERMISSIONS); // SetupWizard grantPermissionsToSystemPackage( - getKnownPackage(PackageManagerInternal.PACKAGE_SETUP_WIZARD, userId), userId, + ArrayUtils.firstOrNull(getKnownPackages( + PackageManagerInternal.PACKAGE_SETUP_WIZARD, userId)), userId, PHONE_PERMISSIONS, CONTACTS_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS, CAMERA_PERMISSIONS); @@ -595,7 +598,8 @@ public final class DefaultPermissionGrantPolicy { userId, CONTACTS_PERMISSIONS, CALENDAR_PERMISSIONS); // Browser - String browserPackage = getKnownPackage(PackageManagerInternal.PACKAGE_BROWSER, userId); + String browserPackage = ArrayUtils.firstOrNull(getKnownPackages( + PackageManagerInternal.PACKAGE_BROWSER, userId)); if (browserPackage == null) { browserPackage = getDefaultSystemHandlerActivityPackageForCategory( Intent.CATEGORY_APP_BROWSER, userId); @@ -760,8 +764,8 @@ public final class DefaultPermissionGrantPolicy { } } - private String getKnownPackage(int knownPkgId, int userId) { - return mServiceInternal.getKnownPackageName(knownPkgId, userId); + private @NonNull String[] getKnownPackages(int knownPkgId, int userId) { + return mServiceInternal.getKnownPackageNames(knownPkgId, userId); } private void grantDefaultPermissionsToDefaultSystemDialerApp( diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 6d1f2d3e1e57..6a7c622b7e33 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -1706,8 +1706,9 @@ public class PermissionManagerService { } } } - final String systemPackageName = mPackageManagerInt.getKnownPackageName( - PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM); + // expect single system package + String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames( + PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM)); final PackageParser.Package systemPackage = mPackageManagerInt.getPackage(systemPackageName); @@ -1823,18 +1824,19 @@ public class PermissionManagerService { // need a separate flag anymore. Hence we need to check which // permissions are needed by the permission controller if (!allowed && bp.isInstaller() - && (pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( - PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM)) - || pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( + && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( + PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM), + pkg.packageName) || ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER, - UserHandle.USER_SYSTEM)))) { + UserHandle.USER_SYSTEM), pkg.packageName)) { // If this permission is to be granted to the system installer and // this app is an installer, then it gets the permission. allowed = true; } if (!allowed && bp.isVerifier() - && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( - PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) { + && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( + PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM), + pkg.packageName)) { // If this permission is to be granted to the system verifier and // this app is a verifier, then it gets the permission. allowed = true; @@ -1850,53 +1852,64 @@ public class PermissionManagerService { allowed = origPermissions.hasInstallPermission(perm); } if (!allowed && bp.isSetup() - && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( - PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) { + && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( + PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM), + pkg.packageName)) { // If this permission is to be granted to the system setup wizard and // this app is a setup wizard, then it gets the permission. allowed = true; } if (!allowed && bp.isSystemTextClassifier() - && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( + && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER, - UserHandle.USER_SYSTEM))) { + UserHandle.USER_SYSTEM), pkg.packageName)) { // Special permissions for the system default text classifier. allowed = true; } if (!allowed && bp.isConfigurator() - && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( - PackageManagerInternal.PACKAGE_CONFIGURATOR, - UserHandle.USER_SYSTEM))) { + && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( + PackageManagerInternal.PACKAGE_CONFIGURATOR, + UserHandle.USER_SYSTEM), pkg.packageName)) { // Special permissions for the device configurator. allowed = true; } if (!allowed && bp.isWellbeing() - && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( - PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM))) { + && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( + PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM), + pkg.packageName)) { // Special permission granted only to the OEM specified wellbeing app allowed = true; } if (!allowed && bp.isDocumenter() - && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( - PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM))) { + && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( + PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM), + pkg.packageName)) { // If this permission is to be granted to the documenter and // this app is the documenter, then it gets the permission. allowed = true; } if (!allowed && bp.isIncidentReportApprover() - && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( + && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER, - UserHandle.USER_SYSTEM))) { + UserHandle.USER_SYSTEM), pkg.packageName)) { // If this permission is to be granted to the incident report approver and // this app is the incident report approver, then it gets the permission. allowed = true; } if (!allowed && bp.isAppPredictor() - && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName( - PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM))) { + && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( + PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM), + pkg.packageName)) { // Special permissions for the system app predictor. allowed = true; } + if (!allowed && bp.isTelephony() + && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames( + PackageManagerInternal.PACKAGE_TELEPHONY, UserHandle.USER_SYSTEM), + pkg.packageName)) { + // Special permissions for the system telephony apps. + allowed = true; + } } return allowed; } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 37931be4eb10..2e56fb096e3b 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1939,7 +1939,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } TelephonyManager getTelephonyManager() { - return TelephonyManager.from(mContext); + return mContext.getSystemService(TelephonyManager.class); } TrustManager getTrustManager() { diff --git a/services/net/java/android/net/NetworkStackClient.java b/services/net/java/android/net/NetworkStackClient.java index 69e24063210d..865e3b8cc109 100644 --- a/services/net/java/android/net/NetworkStackClient.java +++ b/services/net/java/android/net/NetworkStackClient.java @@ -103,7 +103,7 @@ public class NetworkStackClient { // checks here should be kept in sync with PermissionUtil. if (caller != Process.SYSTEM_UID && caller != Process.NETWORK_STACK_UID - && !UserHandle.isSameApp(caller, Process.BLUETOOTH_UID)) { + && UserHandle.getAppId(caller) != Process.BLUETOOTH_UID) { throw new SecurityException( "Only the system server should try to bind to the network stack."); } diff --git a/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java index 0605d9e18069..50437b4d5f3e 100644 --- a/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java @@ -36,7 +36,7 @@ public class DynamicSystemServiceTest extends AndroidTestCase { public void test1() { assertTrue("dynamic_system service available", mService != null); try { - mService.startInstallation("userdata", 8L << 30, false); + mService.startInstallation(); fail("DynamicSystemService did not throw SecurityException as expected"); } catch (SecurityException e) { // expected diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java index dcab78ede287..8cd6ef9c132f 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java @@ -98,7 +98,7 @@ public class ZenModeConfigTest extends UiServiceTestCase { suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_AMBIENT; Policy expectedPolicy = new Policy(priorityCategories, priorityCallSenders, - priorityMessageSenders, suppressedVisualEffects); + priorityMessageSenders, suppressedVisualEffects, 0); assertEquals(expectedPolicy, config.toNotificationPolicy(zenPolicy)); } diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java index f27b944d2cff..087937d5ade2 100644 --- a/telephony/java/android/provider/Telephony.java +++ b/telephony/java/android/provider/Telephony.java @@ -1127,8 +1127,9 @@ public final class Telephony { * values:</p> * * <ul> - * <li><em>"message"</em> - An SmsCbMessage object containing the broadcast message - * data, including ETWS or CMAS warning notification info if present.</li> + * <li><em>"message"</em> - An {@link android.telephony.SmsCbMessage} object + * containing the broadcast message data, including ETWS or CMAS warning notification + * info if present.</li> * </ul> * * <p>The extra values can be extracted using @@ -1139,11 +1140,12 @@ public final class Telephony { * * <p>Requires {@link android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST} to * receive.</p> - * @removed + * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - public static final String SMS_EMERGENCY_CB_RECEIVED_ACTION = - "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED"; + @SystemApi + public static final String ACTION_SMS_EMERGENCY_CB_RECEIVED = + "android.provider.action.SMS_EMERGENCY_CB_RECEIVED"; /** * Broadcast Action: A new CDMA SMS has been received containing Service Category diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index f34c7a8543ab..c0e03a738fb1 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -809,7 +809,9 @@ public class CarrierConfigManager { /** * The default flag specifying whether ETWS/CMAS test setting is forcibly disabled in * Settings->More->Emergency broadcasts menu even though developer options is turned on. + * @deprecated moved to cellbroadcastreceiver resource show_test_settings */ + @Deprecated public static final String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL = "carrier_force_disable_etws_cmas_test_bool"; @@ -828,13 +830,6 @@ public class CarrierConfigManager { "disable_severe_when_extreme_disabled_bool"; /** - * The message expiration time in milliseconds for duplicate detection purposes. - * @hide - */ - public static final String KEY_MESSAGE_EXPIRATION_TIME_LONG = - "message_expiration_time_long"; - - /** * The data call retry configuration for different types of APN. * @hide */ @@ -3387,7 +3382,6 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL, false); sDefaults.putBoolean(KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL, false); sDefaults.putBoolean(KEY_DISABLE_SEVERE_WHEN_EXTREME_DISABLED_BOOL, true); - sDefaults.putLong(KEY_MESSAGE_EXPIRATION_TIME_LONG, 86400000L); sDefaults.putStringArray(KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS, new String[]{ "default:default_randomization=2000,5000,10000,20000,40000,80000:5000,160000:5000," + "320000:5000,640000:5000,1280000:5000,1800000:5000", diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java index 407ced71a0e7..270eafe642b7 100644 --- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java +++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java @@ -203,9 +203,12 @@ public final class DataSpecificRegistrationInfo implements Parcelable { } /** + * Get whether network has configured carrier aggregation or not. + * * @return {@code true} if using carrier aggregation. * @hide */ + @SystemApi public boolean isUsingCarrierAggregation() { return mIsUsingCarrierAggregation; } diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java index 3e028715fd6d..bbf746fcf3c4 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -323,9 +323,12 @@ public final class NetworkRegistrationInfo implements Parcelable { public @Domain int getDomain() { return mDomain; } /** + * Get the 5G NR connection state. + * * @return the 5G NR connection state. * @hide */ + @SystemApi public @NRState int getNrState() { return mNrState; } diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index c57512973c3d..3fd8990ffc9a 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -988,6 +988,9 @@ public class ServiceState implements Parcelable { case RIL_RADIO_TECHNOLOGY_LTE_CA: rtString = "LTE_CA"; break; + case RIL_RADIO_TECHNOLOGY_NR: + rtString = "LTE_NR"; + break; default: rtString = "Unexpected"; Rlog.w(LOG_TAG, "Unexpected radioTechnology=" + rt); @@ -1406,9 +1409,12 @@ public class ServiceState implements Parcelable { } /** + * Get the 5G NR frequency range the device is currently registered. + * * @return the frequency range of 5G NR. * @hide */ + @SystemApi public @FrequencyRange int getNrFrequencyRange() { return mNrFrequencyRange; } @@ -1486,44 +1492,44 @@ public class ServiceState implements Parcelable { /** @hide */ public static int rilRadioTechnologyToNetworkType(@RilRadioTechnology int rat) { switch(rat) { - case ServiceState.RIL_RADIO_TECHNOLOGY_GPRS: + case RIL_RADIO_TECHNOLOGY_GPRS: return TelephonyManager.NETWORK_TYPE_GPRS; - case ServiceState.RIL_RADIO_TECHNOLOGY_EDGE: + case RIL_RADIO_TECHNOLOGY_EDGE: return TelephonyManager.NETWORK_TYPE_EDGE; - case ServiceState.RIL_RADIO_TECHNOLOGY_UMTS: + case RIL_RADIO_TECHNOLOGY_UMTS: return TelephonyManager.NETWORK_TYPE_UMTS; - case ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA: + case RIL_RADIO_TECHNOLOGY_HSDPA: return TelephonyManager.NETWORK_TYPE_HSDPA; - case ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA: + case RIL_RADIO_TECHNOLOGY_HSUPA: return TelephonyManager.NETWORK_TYPE_HSUPA; - case ServiceState.RIL_RADIO_TECHNOLOGY_HSPA: + case RIL_RADIO_TECHNOLOGY_HSPA: return TelephonyManager.NETWORK_TYPE_HSPA; - case ServiceState.RIL_RADIO_TECHNOLOGY_IS95A: - case ServiceState.RIL_RADIO_TECHNOLOGY_IS95B: + case RIL_RADIO_TECHNOLOGY_IS95A: + case RIL_RADIO_TECHNOLOGY_IS95B: return TelephonyManager.NETWORK_TYPE_CDMA; - case ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT: + case RIL_RADIO_TECHNOLOGY_1xRTT: return TelephonyManager.NETWORK_TYPE_1xRTT; - case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0: + case RIL_RADIO_TECHNOLOGY_EVDO_0: return TelephonyManager.NETWORK_TYPE_EVDO_0; - case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A: + case RIL_RADIO_TECHNOLOGY_EVDO_A: return TelephonyManager.NETWORK_TYPE_EVDO_A; - case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B: + case RIL_RADIO_TECHNOLOGY_EVDO_B: return TelephonyManager.NETWORK_TYPE_EVDO_B; - case ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD: + case RIL_RADIO_TECHNOLOGY_EHRPD: return TelephonyManager.NETWORK_TYPE_EHRPD; - case ServiceState.RIL_RADIO_TECHNOLOGY_LTE: + case RIL_RADIO_TECHNOLOGY_LTE: return TelephonyManager.NETWORK_TYPE_LTE; - case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP: + case RIL_RADIO_TECHNOLOGY_HSPAP: return TelephonyManager.NETWORK_TYPE_HSPAP; - case ServiceState.RIL_RADIO_TECHNOLOGY_GSM: + case RIL_RADIO_TECHNOLOGY_GSM: return TelephonyManager.NETWORK_TYPE_GSM; - case ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA: + case RIL_RADIO_TECHNOLOGY_TD_SCDMA: return TelephonyManager.NETWORK_TYPE_TD_SCDMA; - case ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN: + case RIL_RADIO_TECHNOLOGY_IWLAN: return TelephonyManager.NETWORK_TYPE_IWLAN; - case ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA: + case RIL_RADIO_TECHNOLOGY_LTE_CA: return TelephonyManager.NETWORK_TYPE_LTE_CA; - case ServiceState.RIL_RADIO_TECHNOLOGY_NR: + case RIL_RADIO_TECHNOLOGY_NR: return TelephonyManager.NETWORK_TYPE_NR; default: return TelephonyManager.NETWORK_TYPE_UNKNOWN; @@ -1554,6 +1560,7 @@ public class ServiceState implements Parcelable { return AccessNetworkType.CDMA2000; case RIL_RADIO_TECHNOLOGY_LTE: case RIL_RADIO_TECHNOLOGY_LTE_CA: + case RIL_RADIO_TECHNOLOGY_NR: return AccessNetworkType.EUTRAN; case RIL_RADIO_TECHNOLOGY_IWLAN: return AccessNetworkType.IWLAN; @@ -1567,43 +1574,45 @@ public class ServiceState implements Parcelable { public static int networkTypeToRilRadioTechnology(int networkType) { switch(networkType) { case TelephonyManager.NETWORK_TYPE_GPRS: - return ServiceState.RIL_RADIO_TECHNOLOGY_GPRS; + return RIL_RADIO_TECHNOLOGY_GPRS; case TelephonyManager.NETWORK_TYPE_EDGE: - return ServiceState.RIL_RADIO_TECHNOLOGY_EDGE; + return RIL_RADIO_TECHNOLOGY_EDGE; case TelephonyManager.NETWORK_TYPE_UMTS: - return ServiceState.RIL_RADIO_TECHNOLOGY_UMTS; + return RIL_RADIO_TECHNOLOGY_UMTS; case TelephonyManager.NETWORK_TYPE_HSDPA: - return ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA; + return RIL_RADIO_TECHNOLOGY_HSDPA; case TelephonyManager.NETWORK_TYPE_HSUPA: - return ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA; + return RIL_RADIO_TECHNOLOGY_HSUPA; case TelephonyManager.NETWORK_TYPE_HSPA: - return ServiceState.RIL_RADIO_TECHNOLOGY_HSPA; + return RIL_RADIO_TECHNOLOGY_HSPA; case TelephonyManager.NETWORK_TYPE_CDMA: - return ServiceState.RIL_RADIO_TECHNOLOGY_IS95A; + return RIL_RADIO_TECHNOLOGY_IS95A; case TelephonyManager.NETWORK_TYPE_1xRTT: - return ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT; + return RIL_RADIO_TECHNOLOGY_1xRTT; case TelephonyManager.NETWORK_TYPE_EVDO_0: - return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0; + return RIL_RADIO_TECHNOLOGY_EVDO_0; case TelephonyManager.NETWORK_TYPE_EVDO_A: - return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A; + return RIL_RADIO_TECHNOLOGY_EVDO_A; case TelephonyManager.NETWORK_TYPE_EVDO_B: - return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B; + return RIL_RADIO_TECHNOLOGY_EVDO_B; case TelephonyManager.NETWORK_TYPE_EHRPD: - return ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD; + return RIL_RADIO_TECHNOLOGY_EHRPD; case TelephonyManager.NETWORK_TYPE_LTE: - return ServiceState.RIL_RADIO_TECHNOLOGY_LTE; + return RIL_RADIO_TECHNOLOGY_LTE; case TelephonyManager.NETWORK_TYPE_HSPAP: - return ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP; + return RIL_RADIO_TECHNOLOGY_HSPAP; case TelephonyManager.NETWORK_TYPE_GSM: - return ServiceState.RIL_RADIO_TECHNOLOGY_GSM; + return RIL_RADIO_TECHNOLOGY_GSM; case TelephonyManager.NETWORK_TYPE_TD_SCDMA: - return ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA; + return RIL_RADIO_TECHNOLOGY_TD_SCDMA; case TelephonyManager.NETWORK_TYPE_IWLAN: - return ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN; + return RIL_RADIO_TECHNOLOGY_IWLAN; case TelephonyManager.NETWORK_TYPE_LTE_CA: - return ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA; + return RIL_RADIO_TECHNOLOGY_LTE_CA; + case TelephonyManager.NETWORK_TYPE_NR: + return RIL_RADIO_TECHNOLOGY_NR; default: - return ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN; + return RIL_RADIO_TECHNOLOGY_UNKNOWN; } } @@ -1692,7 +1701,8 @@ public class ServiceState implements Parcelable { || radioTechnology == RIL_RADIO_TECHNOLOGY_GSM || radioTechnology == RIL_RADIO_TECHNOLOGY_TD_SCDMA || radioTechnology == RIL_RADIO_TECHNOLOGY_IWLAN - || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA; + || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA + || radioTechnology == RIL_RADIO_TECHNOLOGY_NR; } @@ -1968,8 +1978,11 @@ public class ServiceState implements Parcelable { /** * The current registered raw data network operator name in long alphanumeric format. * + * @return long raw name of operator, null if unregistered or unknown * @hide */ + @Nullable + @SystemApi public String getOperatorAlphaLongRaw() { return mOperatorAlphaLongRaw; } @@ -1984,8 +1997,11 @@ public class ServiceState implements Parcelable { /** * The current registered raw data network operator name in short alphanumeric format. * + * @return short raw name of operator, null if unregistered or unknown * @hide */ + @Nullable + @SystemApi public String getOperatorAlphaShortRaw() { return mOperatorAlphaShortRaw; } diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 54e87afb2da9..daeacf8206b4 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -520,7 +520,6 @@ public final class SmsManager { throw new IllegalArgumentException("Invalid message body"); } - final Context context = ActivityThread.currentApplication().getApplicationContext(); // We will only show the SMS disambiguation dialog in the case that the message is being // persisted. This is for two reasons: // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific @@ -629,7 +628,6 @@ public final class SmsManager { final int finalPriority = priority; final int finalValidity = validityPeriod; - final Context context = ActivityThread.currentApplication().getApplicationContext(); // We will only show the SMS disambiguation dialog in the case that the message is being // persisted. This is for two reasons: // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific @@ -933,7 +931,6 @@ public final class SmsManager { } if (parts.size() > 1) { - final Context context = ActivityThread.currentApplication().getApplicationContext(); // We will only show the SMS disambiguation dialog in the case that the message is being // persisted. This is for two reasons: // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific @@ -1174,7 +1171,6 @@ public final class SmsManager { if (parts.size() > 1) { final int finalPriority = priority; final int finalValidity = validityPeriod; - final Context context = ActivityThread.currentApplication().getApplicationContext(); if (persistMessage) { resolveSubscriptionForOperation(new SubscriptionResolverResult() { @Override @@ -1331,7 +1327,6 @@ public final class SmsManager { throw new IllegalArgumentException("Invalid message data"); } - final Context context = ActivityThread.currentApplication().getApplicationContext(); resolveSubscriptionForOperation(new SubscriptionResolverResult() { @Override public void onSuccess(int subId) { diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 0e1dda7a9cce..9d1b7a918327 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -49,6 +49,7 @@ import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.Looper; import android.os.Message; import android.os.ParcelUuid; @@ -61,10 +62,8 @@ import android.telephony.ims.ImsMmTelManager; import android.util.DisplayMetrics; import android.util.Log; -import com.android.internal.telephony.IOnSubscriptionsChangedListener; import com.android.internal.telephony.ISetOpportunisticDataCallback; import com.android.internal.telephony.ISub; -import com.android.internal.telephony.ITelephonyRegistry; import com.android.internal.telephony.PhoneConstants; import com.android.internal.util.Preconditions; @@ -931,20 +930,24 @@ public class SubscriptionManager { OnSubscriptionsChangedListenerHandler(Looper looper) { super(looper); } - - @Override - public void handleMessage(Message msg) { - if (DBG) { - log("handleMessage: invoke the overriden onSubscriptionsChanged()"); - } - OnSubscriptionsChangedListener.this.onSubscriptionsChanged(); - } } - private final Handler mHandler; + /** + * Posted executor callback on the handler associated with a given looper. + * The looper can be the calling thread's looper or the looper passed from the + * constructor {@link #OnSubscriptionsChangedListener(Looper)}. + */ + private final HandlerExecutor mExecutor; + + /** + * @hide + */ + public HandlerExecutor getHandlerExecutor() { + return mExecutor; + } public OnSubscriptionsChangedListener() { - mHandler = new OnSubscriptionsChangedListenerHandler(); + mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler()); } /** @@ -953,7 +956,7 @@ public class SubscriptionManager { * @hide */ public OnSubscriptionsChangedListener(Looper looper) { - mHandler = new OnSubscriptionsChangedListenerHandler(looper); + mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler(looper)); } /** @@ -965,18 +968,6 @@ public class SubscriptionManager { if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN"); } - /** - * The callback methods need to be called on the handler thread where - * this object was created. If the binder did that for us it'd be nice. - */ - IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { - @Override - public void onSubscriptionsChanged() { - if (DBG) log("callback: received, sendEmptyMessage(0) to handler"); - mHandler.sendEmptyMessage(0); - } - }; - private void log(String s) { Rlog.d(LOG_TAG, s); } @@ -1018,21 +1009,19 @@ public class SubscriptionManager { * onSubscriptionsChanged overridden. */ public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { + if (listener == null) return; String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>"; if (DBG) { logd("register OnSubscriptionsChangedListener pkgName=" + pkgName + " listener=" + listener); } - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available. Where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.addOnSubscriptionsChangedListener(pkgName, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + // We use the TelephonyRegistry as it runs in the system and thus is always + // available. Where as SubscriptionController could crash and not be available + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.addOnSubscriptionsChangedListener(listener, + listener.mExecutor); } } @@ -1044,21 +1033,18 @@ public class SubscriptionManager { * @param listener that is to be unregistered. */ public void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { + if (listener == null) return; String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; if (DBG) { logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug + " listener=" + listener); } - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + // We use the TelephonyRegistry as it runs in the system and thus is always + // available where as SubscriptionController could crash and not be available + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.removeOnSubscriptionsChangedListener(listener); } } @@ -1077,7 +1063,6 @@ public class SubscriptionManager { * for #onOpportunisticSubscriptionsChanged to be invoked. */ public static class OnOpportunisticSubscriptionsChangedListener { - private Executor mExecutor; /** * Callback invoked when there is any change to any SubscriptionInfo. Typically * this method would invoke {@link #getActiveSubscriptionInfoList} @@ -1086,27 +1071,6 @@ public class SubscriptionManager { if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN"); } - private void setExecutor(Executor executor) { - mExecutor = executor; - } - - /** - * The callback methods need to be called on the handler thread where - * this object was created. If the binder did that for us it'd be nice. - */ - IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { - @Override - public void onSubscriptionsChanged() { - final long identity = Binder.clearCallingIdentity(); - try { - if (DBG) log("onOpportunisticSubscriptionsChanged callback received."); - mExecutor.execute(() -> onOpportunisticSubscriptionsChanged()); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - }; - private void log(String s) { Rlog.d(LOG_TAG, s); } @@ -1133,18 +1097,13 @@ public class SubscriptionManager { + " listener=" + listener); } - listener.setExecutor(executor); - - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available. Where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.addOnOpportunisticSubscriptionsChangedListener(pkgName, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + // We use the TelephonyRegistry as it runs in the system and thus is always + // available where as SubscriptionController could crash and not be available + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.addOnOpportunisticSubscriptionsChangedListener( + listener, executor); } } @@ -1164,16 +1123,10 @@ public class SubscriptionManager { logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug=" + pkgForDebug + " listener=" + listener); } - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.removeOnOpportunisticSubscriptionsChangedListener(listener); } } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 4f858880f2d6..55212cd969f0 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -2784,6 +2784,8 @@ public class TelephonyManager { /** Class of broadly defined "4G" networks. {@hide} */ @UnsupportedAppUsage public static final int NETWORK_CLASS_4_G = 3; + /** Class of broadly defined "5G" networks. {@hide} */ + public static final int NETWORK_CLASS_5_G = 4; /** * Return general class of network type, such as "3G" or "4G". In cases @@ -2816,6 +2818,8 @@ public class TelephonyManager { case NETWORK_TYPE_IWLAN: case NETWORK_TYPE_LTE_CA: return NETWORK_CLASS_4_G; + case NETWORK_TYPE_NR: + return NETWORK_CLASS_5_G; default: return NETWORK_CLASS_UNKNOWN; } diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java index cde7bc9c1390..cb66a9650f2f 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -189,6 +189,29 @@ public class EuiccManager { "android.telephony.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED"; /** + * Intent action sent by a carrier app to launch the eSIM activation flow provided by the LPA UI + * (LUI). The carrier app must send this intent with one of the following: + * + * <p>{@link #EXTRA_USE_QR_SCANNER} not set or set to false: The LPA should try to get an + * activation code from the carrier app by binding to the carrier app service implementing + * {@link android.service.euicc.EuiccService#ACTION_BIND_CARRIER_PROVISIONING_SERVICE}. + * <p>{@link #EXTRA_USE_QR_SCANNER} set to true: The LPA should launch a QR scanner for the user + * to scan an eSIM profile QR code. + * + * <p>Upon completion, the LPA should return one of the following results to the carrier app: + * + * <p>{@code Activity.RESULT_OK}: The LPA has succeeded in downloading the new eSIM profile. + * <p>{@code Activity.RESULT_CANCELED}: The carrier app should treat this as if the user pressed + * the back button. + * <p>Anything else: The carrier app should treat this as an error. + * + * <p>LPA needs to check if caller's package name is allowed to perform this action. + **/ + @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_START_EUICC_ACTIVATION = + "android.telephony.euicc.action.START_EUICC_ACTIVATION"; + + /** * Result code for an operation indicating that the operation succeeded. */ public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0; @@ -342,10 +365,20 @@ public class EuiccManager { * * @hide */ - // TODO: Make this a @SystemApi. + @SystemApi public static final String EXTRA_PHYSICAL_SLOT_ID = "android.telephony.euicc.extra.PHYSICAL_SLOT_ID"; + + /** + * Key for an extra set on actions {@link #ACTION_START_EUICC_ACTIVATION} providing a boolean + * value of whether to start eSIM activation with QR scanner. + * + * <p>Expected type of the extra data: boolean + **/ + public static final String EXTRA_USE_QR_SCANNER = + "android.telephony.euicc.extra.USE_QR_SCANNER"; + /** * Optional meta-data attribute for a carrier app providing an icon to use to represent the * carrier. If not provided, the app's launcher icon will be used as a fallback. diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java index d85cf151b9eb..11bc5de08c66 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java @@ -33,7 +33,7 @@ import java.util.Locale; * All relevant header information is now sent as a Parcelable * {@link android.telephony.SmsCbMessage} object in the "message" extra of the * {@link android.provider.Telephony.Sms.Intents#SMS_CB_RECEIVED_ACTION} or - * {@link android.provider.Telephony.Sms.Intents#SMS_EMERGENCY_CB_RECEIVED_ACTION} intent. + * {@link android.provider.Telephony.Sms.Intents#ACTION_SMS_EMERGENCY_CB_RECEIVED} intent. * The raw PDU is no longer sent to SMS CB applications. */ public class SmsCbHeader { diff --git a/tests/PlatformCompatGating/Android.bp b/tests/PlatformCompatGating/Android.bp new file mode 100644 index 000000000000..5e9ef8efc402 --- /dev/null +++ b/tests/PlatformCompatGating/Android.bp @@ -0,0 +1,33 @@ +// +// Copyright (C) 2019 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. +// + +android_test { + name: "PlatformCompatGating", + // Only compile source java files in this apk. + srcs: ["src/**/*.java"], + certificate: "platform", + libs: [ + "android.test.runner", + "android.test.base", + ], + static_libs: [ + "junit", + "android-support-test", + "mockito-target-minus-junit4", + "truth-prebuilt", + "platform-compat-test-rules" + ], +} diff --git a/tests/PlatformCompatGating/AndroidManifest.xml b/tests/PlatformCompatGating/AndroidManifest.xml new file mode 100644 index 000000000000..7f14b83fbc75 --- /dev/null +++ b/tests/PlatformCompatGating/AndroidManifest.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.tests.gating"> + <application android:label="GatingTest"> + <uses-library android:name="android.test.runner" /> + </application> + + <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.tests.gating"/> +</manifest> diff --git a/tests/PlatformCompatGating/AndroidTest.xml b/tests/PlatformCompatGating/AndroidTest.xml new file mode 100644 index 000000000000..c62684837332 --- /dev/null +++ b/tests/PlatformCompatGating/AndroidTest.xml @@ -0,0 +1,30 @@ +<!-- Copyright (C) 2018 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<configuration description="Test compatibility change gating."> + <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/> + <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> + <option name="test-file-name" value="PlatformCompatGating.apk"/> + </target_preparer> + <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/> + <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/> + <option name="test-suite-tag" value="apct"/> + <option name="test-tag" value="Gating"/> + + <test class="com.android.tradefed.testtype.AndroidJUnitTest"> + <option name="package" value="com.android.tests.gating"/> + <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/> + <option name="hidden-api-checks" value="false"/> + </test> +</configuration> diff --git a/tests/PlatformCompatGating/src/com/android/compat/testing/DummyApi.java b/tests/PlatformCompatGating/src/com/android/compat/testing/DummyApi.java new file mode 100644 index 000000000000..731be8e3d9f0 --- /dev/null +++ b/tests/PlatformCompatGating/src/com/android/compat/testing/DummyApi.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.compat.testing; + +import android.compat.Compatibility; +import android.content.Context; +import android.os.RemoteException; +import android.os.ServiceManager; + +import com.android.internal.compat.IPlatformCompat; + +/** + * This is a dummy API to test gating + * + * @hide + */ +public class DummyApi { + + public static final long CHANGE_ID = 666013; + public static final long CHANGE_ID_1 = 666014; + public static final long CHANGE_ID_2 = 666015; + public static final long CHANGE_SYSTEM_SERVER = 666016; + + /** + * Dummy method + * @return "A" if change is enabled, "B" otherwise. + */ + public static String dummyFunc() { + if (Compatibility.isChangeEnabled(CHANGE_ID)) { + return "A"; + } + return "B"; + } + + /** + * Dummy combined method + * @return "0" if {@link CHANGE_ID_1} is disabled and {@link CHANGE_ID_2} is disabled, + "1" if {@link CHANGE_ID_1} is disabled and {@link CHANGE_ID_2} is enabled, + "2" if {@link CHANGE_ID_1} is enabled and {@link CHANGE_ID_2} is disabled, + "3" if {@link CHANGE_ID_1} is enabled and {@link CHANGE_ID_2} is enabled. + */ + public static String dummyCombinedFunc() { + if (!Compatibility.isChangeEnabled(CHANGE_ID_1) + && !Compatibility.isChangeEnabled(CHANGE_ID_2)) { + return "0"; + } else if (!Compatibility.isChangeEnabled(CHANGE_ID_1) + && Compatibility.isChangeEnabled(CHANGE_ID_2)) { + return "1"; + } else if (Compatibility.isChangeEnabled(CHANGE_ID_1) + && !Compatibility.isChangeEnabled(CHANGE_ID_2)) { + return "2"; + } + return "3"; + } + + /** + * Dummy api using system server API. + */ + public static boolean dummySystemServer(Context context) { + IPlatformCompat platformCompat = IPlatformCompat.Stub + .asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); + if (platformCompat == null) { + throw new RuntimeException("Could not obtain IPlatformCompat instance!"); + } + String packageName = context.getPackageName(); + try { + return platformCompat.isChangeEnabledByPackageName(CHANGE_SYSTEM_SERVER, packageName, + context.getUserId()); + } catch (RemoteException e) { + throw new RuntimeException("Could not get change value!", e); + } + } +} diff --git a/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java new file mode 100644 index 000000000000..dc317f1941c7 --- /dev/null +++ b/tests/PlatformCompatGating/src/com/android/tests/gating/PlatformCompatGatingTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.tests.gating; + +import static com.google.common.truth.Truth.assertThat; + +import android.compat.testing.PlatformCompatChangeRule; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import com.android.compat.testing.DummyApi; + +import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges; +import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +/** + * Tests for platform compatibility change gating. + */ +@RunWith(AndroidJUnit4.class) +public class PlatformCompatGatingTest { + + @Rule + public TestRule compatChangeRule = new PlatformCompatChangeRule(); + + @Test + @EnableCompatChanges({DummyApi.CHANGE_ID}) + public void testDummyGatingPositive() { + assertThat(DummyApi.dummyFunc()).isEqualTo("A"); + } + + @Test + @DisableCompatChanges({DummyApi.CHANGE_ID}) + public void testDummyGatingNegative() { + assertThat(DummyApi.dummyFunc()).isEqualTo("B"); + } + + @Test + @DisableCompatChanges({DummyApi.CHANGE_ID_1, DummyApi.CHANGE_ID_2}) + public void testDummyGatingCombined0() { + assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("0"); + } + + @Test + @DisableCompatChanges({DummyApi.CHANGE_ID_1}) + @EnableCompatChanges({DummyApi.CHANGE_ID_2}) + public void testDummyGatingCombined1() { + assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("1"); + } + + @Test + @EnableCompatChanges({DummyApi.CHANGE_ID_1}) + @DisableCompatChanges({DummyApi.CHANGE_ID_2}) + public void testDummyGatingCombined2() { + assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("2"); + } + + @Test + @EnableCompatChanges({DummyApi.CHANGE_ID_1, DummyApi.CHANGE_ID_2}) + public void testDummyGatingCombined3() { + assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("3"); + } + + @Test + @EnableCompatChanges({DummyApi.CHANGE_SYSTEM_SERVER}) + public void testDummyGatingPositiveSystemServer() { + assertThat( + DummyApi.dummySystemServer(InstrumentationRegistry.getTargetContext())).isTrue(); + } + + @Test + @DisableCompatChanges({DummyApi.CHANGE_SYSTEM_SERVER}) + public void testDummyGatingNegativeSystemServer() { + assertThat( + DummyApi.dummySystemServer(InstrumentationRegistry.getTargetContext())).isFalse(); + } +} diff --git a/tests/PlatformCompatGating/test-rules/Android.bp b/tests/PlatformCompatGating/test-rules/Android.bp new file mode 100644 index 000000000000..8211ef523ee7 --- /dev/null +++ b/tests/PlatformCompatGating/test-rules/Android.bp @@ -0,0 +1,26 @@ +// +// Copyright (C) 2019 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. +// + +java_library { + name: "platform-compat-test-rules", + srcs: ["src/**/*.java"], + static_libs: [ + "junit", + "android-support-test", + "truth-prebuilt", + "core-compat-test-rules" + ], +}
\ No newline at end of file diff --git a/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java new file mode 100644 index 000000000000..932ec643d478 --- /dev/null +++ b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.compat.testing; + +import android.app.Instrumentation; +import android.compat.Compatibility; +import android.compat.Compatibility.ChangeConfig; +import android.content.Context; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.support.test.InstrumentationRegistry; + +import com.android.internal.compat.CompatibilityChangeConfig; +import com.android.internal.compat.IPlatformCompat; + +import libcore.junit.util.compat.CoreCompatChangeRule; + +import org.junit.runners.model.Statement; + +/** + * Allows tests to specify the which change to disable. + * + * <p>To use add the following to the test class. It will only change the behavior of a test method + * if it is annotated with + * {@link libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges} and/or + * {@link libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges}. + * </p> + * <pre> + * @Rule + * public TestRule compatChangeRule = new PlatformCompatChangeRule(); + * </pre> + * + * <p>Each test method that needs to disable a specific change needs to be annotated + * with {@link libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges} and/or + * {@link libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges} specifying the change + * id. e.g.: + * </p> + * <pre> + * @Test + * @DisableCompatChanges({42}) + * public void testAsIfChange42Disabled() { + * // check behavior + * } + * + * @Test + * @EnableCompatChanges({42}) + * public void testAsIfChange42Enabled() { + * // check behavior + * + * </pre> + */ +public class PlatformCompatChangeRule extends CoreCompatChangeRule { + + @Override + protected Statement createStatementForConfig(final Statement statement, ChangeConfig config) { + return new CompatChangeStatement(statement, config); + } + + + private static class CompatChangeStatement extends Statement { + private final Statement mTestStatement; + private final ChangeConfig mConfig; + + private CompatChangeStatement(Statement testStatement, ChangeConfig config) { + this.mTestStatement = testStatement; + this.mConfig = config; + } + + @Override + public void evaluate() throws Throwable { + Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + String packageName = instrumentation.getTargetContext().getPackageName(); + IPlatformCompat platformCompat = IPlatformCompat.Stub + .asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); + if (platformCompat == null) { + throw new IllegalStateException("Could not get IPlatformCompat service!"); + } + Compatibility.setOverrides(mConfig); + try { + platformCompat.setOverridesForTest(new CompatibilityChangeConfig(mConfig), + packageName); + try { + mTestStatement.evaluate(); + } finally { + platformCompat.clearOverridesForTest(packageName); + } + } catch (RemoteException e) { + throw new RuntimeException("Could not call IPlatformCompat binder method!", e); + } finally { + Compatibility.clearOverrides(); + } + } + } +} diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 61f37fd6c7e2..d6ce32018190 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -20,6 +20,9 @@ import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.content.pm.PackageManager.MATCH_ANY_USER; import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; +import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_SUPL; +import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; +import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; import static android.net.ConnectivityManager.NETID_UNSET; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; @@ -28,6 +31,7 @@ import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_MOBILE_FOTA; import static android.net.ConnectivityManager.TYPE_MOBILE_MMS; +import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS; import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK; @@ -145,6 +149,7 @@ import android.net.MatchAllNetworkSpecifier; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkFactory; +import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.NetworkSpecifier; import android.net.NetworkStack; @@ -244,6 +249,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Predicate; import kotlin.reflect.KClass; @@ -330,6 +336,9 @@ public class ConnectivityServiceTest { private class MockContext extends BroadcastInterceptingContext { private final MockContentResolver mContentResolver; + // Contains all registered receivers since this object was created. Useful to clear + // them when needed, as BroadcastInterceptingContext does not provide this facility. + private final List<BroadcastReceiver> mRegisteredReceivers = new ArrayList<>(); @Spy private Resources mResources; private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>(); @@ -343,6 +352,7 @@ public class ConnectivityServiceTest { "wifi,1,1,1,-1,true", "mobile,0,0,0,-1,true", "mobile_mms,2,0,2,60000,true", + "mobile_supl,3,0,2,60000,true", }); when(mResources.getStringArray( @@ -410,6 +420,19 @@ public class ConnectivityServiceTest { // make sure the code does not rely on unexpected permissions. super.enforceCallingOrSelfPermission(permission, message); } + + @Override + public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { + mRegisteredReceivers.add(receiver); + return super.registerReceiver(receiver, filter); + } + + public void clearRegisteredReceivers() { + // super.unregisterReceiver is a no-op for receivers that are not registered (because + // they haven't been registered or because they have already been unregistered). + // For the same reason, don't bother clearing mRegisteredReceivers. + for (final BroadcastReceiver rcv : mRegisteredReceivers) unregisterReceiver(rcv); + } } private void waitForIdle() { @@ -1228,16 +1251,25 @@ public class ConnectivityServiceTest { * broadcasts are received. */ private ConditionVariable waitForConnectivityBroadcasts(final int count) { + return waitForConnectivityBroadcasts(count, intent -> true); + } + + private ConditionVariable waitForConnectivityBroadcasts(final int count, + @NonNull final Predicate<Intent> filter) { final ConditionVariable cv = new ConditionVariable(); - mServiceContext.registerReceiver(new BroadcastReceiver() { + final IntentFilter intentFilter = new IntentFilter(CONNECTIVITY_ACTION); + intentFilter.addAction(CONNECTIVITY_ACTION_SUPL); + final BroadcastReceiver receiver = new BroadcastReceiver() { private int remaining = count; public void onReceive(Context context, Intent intent) { + if (!filter.test(intent)) return; if (--remaining == 0) { cv.open(); mServiceContext.unregisterReceiver(this); } } - }, new IntentFilter(CONNECTIVITY_ACTION)); + }; + mServiceContext.registerReceiver(receiver, intentFilter); return cv; } @@ -1258,6 +1290,75 @@ public class ConnectivityServiceTest { } @Test + public void testNetworkFeature() throws Exception { + // Connect the cell agent and wait for the connected broadcast. + mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); + mCellNetworkAgent.addCapability(NET_CAPABILITY_SUPL); + final ConditionVariable cv1 = waitForConnectivityBroadcasts(1, + intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE); + mCellNetworkAgent.connect(true); + waitFor(cv1); + + // Build legacy request for SUPL. + final NetworkCapabilities legacyCaps = new NetworkCapabilities(); + legacyCaps.addTransportType(TRANSPORT_CELLULAR); + legacyCaps.addCapability(NET_CAPABILITY_SUPL); + final NetworkRequest legacyRequest = new NetworkRequest(legacyCaps, TYPE_MOBILE_SUPL, + ConnectivityManager.REQUEST_ID_UNSET, NetworkRequest.Type.REQUEST); + + // Send request and check that the legacy broadcast for SUPL is sent correctly. + final TestNetworkCallback callback = new TestNetworkCallback(); + final ConditionVariable cv2 = waitForConnectivityBroadcasts(1, + intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); + mCm.requestNetwork(legacyRequest, callback); + callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); + waitFor(cv2); + + // File another request, withdraw it and make sure no broadcast is sent + final ConditionVariable cv3 = waitForConnectivityBroadcasts(1); + final TestNetworkCallback callback2 = new TestNetworkCallback(); + mCm.requestNetwork(legacyRequest, callback2); + callback2.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); + mCm.unregisterNetworkCallback(callback2); + assertFalse(cv3.block(800)); // 800ms long enough to at least flake if this is sent + // As the broadcast did not fire, the receiver was not unregistered. Do this now. + mServiceContext.clearRegisteredReceivers(); + + // Withdraw the request and check that the broadcast for disconnection is sent. + final ConditionVariable cv4 = waitForConnectivityBroadcasts(1, intent -> + !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected() + && intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); + mCm.unregisterNetworkCallback(callback); + waitFor(cv4); + + // Re-file the request and expect the connected broadcast again + final ConditionVariable cv5 = waitForConnectivityBroadcasts(1, + intent -> intent.getIntExtra(EXTRA_NETWORK_TYPE, -1) == TYPE_MOBILE_SUPL); + final TestNetworkCallback callback3 = new TestNetworkCallback(); + mCm.requestNetwork(legacyRequest, callback3); + callback3.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent); + waitFor(cv5); + + // Disconnect the network and expect two disconnected broadcasts, one for SUPL and one + // for mobile. Use a small hack to check that both have been sent, but the order is + // not contractual. + final AtomicBoolean vanillaAction = new AtomicBoolean(false); + final AtomicBoolean suplAction = new AtomicBoolean(false); + final ConditionVariable cv6 = waitForConnectivityBroadcasts(2, intent -> { + if (intent.getAction().equals(CONNECTIVITY_ACTION)) { + vanillaAction.set(true); + } else if (intent.getAction().equals(CONNECTIVITY_ACTION_SUPL)) { + suplAction.set(true); + } + return !((NetworkInfo) intent.getExtra(EXTRA_NETWORK_INFO, -1)).isConnected(); + }); + mCellNetworkAgent.disconnect(); + waitFor(cv6); + assertTrue(vanillaAction.get()); + assertTrue(suplAction.get()); + } + + @Test public void testLingering() throws Exception { verifyNoNetwork(); mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); diff --git a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt index f045369459c9..42d4cf3c382b 100644 --- a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt +++ b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt @@ -18,6 +18,7 @@ package com.android.server import android.net.ConnectivityManager.TYPE_ETHERNET import android.net.ConnectivityManager.TYPE_MOBILE +import android.net.ConnectivityManager.TYPE_MOBILE_SUPL import android.net.ConnectivityManager.TYPE_WIFI import android.net.ConnectivityManager.TYPE_WIMAX import android.net.NetworkInfo.DetailedState.CONNECTED @@ -46,7 +47,7 @@ const val UNSUPPORTED_TYPE = TYPE_WIMAX @RunWith(AndroidJUnit4::class) @SmallTest class LegacyTypeTrackerTest { - private val supportedTypes = arrayOf(TYPE_MOBILE, TYPE_WIFI, TYPE_ETHERNET) + private val supportedTypes = arrayOf(TYPE_MOBILE, TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_SUPL) private val mMockService = mock(ConnectivityService::class.java).apply { doReturn(false).`when`(this).isDefaultNetwork(any()) @@ -70,6 +71,26 @@ class LegacyTypeTrackerTest { } @Test + fun testSupl() { + val mobileNai = mock(NetworkAgentInfo::class.java) + mTracker.add(TYPE_MOBILE, mobileNai) + verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE) + reset(mMockService) + mTracker.add(TYPE_MOBILE_SUPL, mobileNai) + verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE_SUPL) + reset(mMockService) + mTracker.remove(TYPE_MOBILE_SUPL, mobileNai, false /* wasDefault */) + verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE_SUPL) + reset(mMockService) + mTracker.add(TYPE_MOBILE_SUPL, mobileNai) + verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, CONNECTED, TYPE_MOBILE_SUPL) + reset(mMockService) + mTracker.remove(mobileNai, false) + verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE_SUPL) + verify(mMockService).sendLegacyNetworkBroadcast(mobileNai, DISCONNECTED, TYPE_MOBILE) + } + + @Test fun testAddNetwork() { val mobileNai = mock(NetworkAgentInfo::class.java) val wifiNai = mock(NetworkAgentInfo::class.java) diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java index 5f62c08f55f3..9e5717b4bd64 100644 --- a/tests/net/java/com/android/server/connectivity/TetheringTest.java +++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java @@ -208,6 +208,12 @@ public class TetheringTest { if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; return super.getSystemService(name); } + + @Override + public String getSystemServiceName(Class<?> serviceClass) { + if (TelephonyManager.class.equals(serviceClass)) return Context.TELEPHONY_SERVICE; + return super.getSystemServiceName(serviceClass); + } } public class MockIpServerDependencies extends IpServer.Dependencies { diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java index 1d29a824d10d..4d42a612030d 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java @@ -192,8 +192,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { mService = new NetworkStatsService( mServiceContext, mNetManager, mAlarmManager, wakeLock, mClock, - TelephonyManager.getDefault(), mSettings, mStatsFactory, - new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir)); + mServiceContext.getSystemService(TelephonyManager.class), mSettings, + mStatsFactory, new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir)); mHandlerThread = new HandlerThread("HandlerThread"); mHandlerThread.start(); Handler.Callback callback = new NetworkStatsService.HandlerCallback(mService); diff --git a/tools/genprotos.sh b/tools/genprotos.sh deleted file mode 100755 index f901c9f588b6..000000000000 --- a/tools/genprotos.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -# TODO This should not be needed. If you set a custom OUT_DIR or OUT_DIR_COMMON_BASE you can -# end up with a command that is extremely long, potentially going passed MAX_ARG_STRLEN due to -# the way sbox rewrites the command. See b/70221552. - -set -e - -location_aprotoc=$1 -location_protoc=$2 -location_soong_zip=$3 -genDir=$4 -depfile=$5 -in=$6 -out=$7 - -mkdir -p ${genDir}/${in} && \ - ${location_aprotoc} --plugin=${location_protoc} \ - --dependency_out=${depfile} \ - --javastream_out=${genDir}/${in} \ - -Iexternal/protobuf/src \ - -I . \ - ${in} && \ - ${location_soong_zip} -jar -o ${out} -C ${genDir}/${in} -D ${genDir}/${in} diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py index e883c6bed755..46105f4d66b0 100755 --- a/tools/hiddenapi/generate_hiddenapi_lists.py +++ b/tools/hiddenapi/generate_hiddenapi_lists.py @@ -241,8 +241,6 @@ class FlagsDict: flags = csv[1:] if (FLAG_PUBLIC_API in flags) or (FLAG_SYSTEM_API in flags): flags.append(FLAG_WHITELIST) - elif FLAG_TEST_API in flags: - flags.append(FLAG_GREYLIST) self._dict[csv[0]].update(flags) def assign_flag(self, flag, apis, source="<unknown>"): diff --git a/tools/hiddenapi/generate_hiddenapi_lists_test.py b/tools/hiddenapi/generate_hiddenapi_lists_test.py index 4dc880b107d3..55c3a7d718db 100755 --- a/tools/hiddenapi/generate_hiddenapi_lists_test.py +++ b/tools/hiddenapi/generate_hiddenapi_lists_test.py @@ -53,14 +53,22 @@ class TestHiddenapiListGeneration(unittest.TestCase): # Test new additions. flags.parse_and_merge_csv([ 'A,' + FLAG_GREYLIST, - 'B,' + FLAG_BLACKLIST + ',' + FLAG_GREYLIST_MAX_O ]) - self.assertEqual(flags.generate_csv(), - [ 'A,' + FLAG_GREYLIST, - 'B,' + FLAG_BLACKLIST + "," + FLAG_GREYLIST_MAX_O ]) + 'B,' + FLAG_BLACKLIST + ',' + FLAG_GREYLIST_MAX_O, + 'C,' + FLAG_SYSTEM_API + ',' + FLAG_WHITELIST, + 'D,' + FLAG_GREYLIST+ ',' + FLAG_TEST_API, + 'E,' + FLAG_BLACKLIST+ ',' + FLAG_TEST_API, + ]) + self.assertEqual(flags.generate_csv(), [ + 'A,' + FLAG_GREYLIST, + 'B,' + FLAG_BLACKLIST + "," + FLAG_GREYLIST_MAX_O, + 'C,' + FLAG_SYSTEM_API + ',' + FLAG_WHITELIST, + 'D,' + FLAG_GREYLIST+ ',' + FLAG_TEST_API, + 'E,' + FLAG_BLACKLIST+ ',' + FLAG_TEST_API, + ]) # Test unknown flag. with self.assertRaises(AssertionError): - flags.parse_and_merge_csv([ 'C,foo' ]) + flags.parse_and_merge_csv([ 'Z,foo' ]) def test_assign_flag(self): flags = FlagsDict() diff --git a/tools/processors/unsupportedappusage/Android.bp b/tools/processors/unsupportedappusage/Android.bp index 0e33fddcde07..1e96234543c8 100644 --- a/tools/processors/unsupportedappusage/Android.bp +++ b/tools/processors/unsupportedappusage/Android.bp @@ -1,11 +1,6 @@ -java_plugin { - name: "unsupportedappusage-annotation-processor", - processor_class: "android.processor.unsupportedappusage.UnsupportedAppUsageProcessor", - - java_resources: [ - "META-INF/**/*", - ], +java_library_host { + name: "unsupportedappusage-annotation-processor-lib", srcs: [ "src/**/*.java", ], @@ -22,6 +17,18 @@ java_plugin { "--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", ], }, +} + +java_plugin { + name: "unsupportedappusage-annotation-processor", + processor_class: "android.processor.unsupportedappusage.UnsupportedAppUsageProcessor", + + java_resources: [ + "META-INF/**/*", + ], + static_libs: [ + "unsupportedappusage-annotation-processor-lib" + ], use_tools_jar: true, } diff --git a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java index 5a5703ed520c..65fc733fa364 100644 --- a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java +++ b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java @@ -101,14 +101,20 @@ public class SignatureBuilder { private String getClassSignature(TypeElement clazz) { StringBuilder sb = new StringBuilder("L"); for (Element enclosing : getEnclosingElements(clazz)) { - if (enclosing.getKind() == PACKAGE) { - sb.append(((PackageElement) enclosing) - .getQualifiedName() - .toString() - .replace('.', '/')); - sb.append('/'); - } else { - sb.append(enclosing.getSimpleName()).append('$'); + switch (enclosing.getKind()) { + case MODULE: + // ignore this. + break; + case PACKAGE: + sb.append(((PackageElement) enclosing) + .getQualifiedName() + .toString() + .replace('.', '/')); + sb.append('/'); + break; + default: + sb.append(enclosing.getSimpleName()).append('$'); + break; } } diff --git a/tools/processors/unsupportedappusage/test/Android.bp b/tools/processors/unsupportedappusage/test/Android.bp new file mode 100644 index 000000000000..49ea3d4bbc96 --- /dev/null +++ b/tools/processors/unsupportedappusage/test/Android.bp @@ -0,0 +1,28 @@ +// Copyright (C) 2019 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. + +java_test_host { + name: "unsupportedappusage-processor-test", + + srcs: ["src/**/*.java"], + + static_libs: [ + "libjavac", + "unsupportedappusage-annotation-processor-lib", + "truth-host-prebuilt", + "mockito-host", + "junit-host", + "objenesis", + ], +} diff --git a/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/CsvReader.java b/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/CsvReader.java new file mode 100644 index 000000000000..23db99e81194 --- /dev/null +++ b/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/CsvReader.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.processor.unsupportedappusage; + +import com.google.common.base.Splitter; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CsvReader { + + private final Splitter mSplitter; + private final List<String> mColumns; + private final List<Map<String, String>> mContents; + + public CsvReader(InputStream in) throws IOException { + mSplitter = Splitter.on(","); + BufferedReader br = new BufferedReader(new InputStreamReader(in)); + mColumns = mSplitter.splitToList(br.readLine()); + mContents = new ArrayList<>(); + String line = br.readLine(); + while (line != null) { + List<String> contents = mSplitter.splitToList(line); + Map<String, String> contentMap = new HashMap<>(); + for (int i = 0; i < Math.min(contents.size(), mColumns.size()); ++i) { + contentMap.put(mColumns.get(i), contents.get(i)); + } + mContents.add(contentMap); + line = br.readLine(); + } + br.close(); + } + + public List<String> getColumns() { + return mColumns; + } + + public List<Map<String, String>> getContents() { + return mContents; + } +} diff --git a/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessorTest.java b/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessorTest.java new file mode 100644 index 000000000000..012e88f17924 --- /dev/null +++ b/tools/processors/unsupportedappusage/test/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessorTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.processor.unsupportedappusage; + +import static com.google.common.truth.Truth.assertThat; + +import com.android.javac.Javac; + +import com.google.common.base.Joiner; + +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.Map; + +public class UnsupportedAppUsageProcessorTest { + + private Javac mJavac; + + @Before + public void setup() throws IOException { + mJavac = new Javac(); + mJavac.addSource("dalvik.annotation.compat.UnsupportedAppUsage", Joiner.on('\n').join( + "package dalvik.annotation.compat;", + "public @interface UnsupportedAppUsage {", + " String expectedSignature() default \"\";\n", + " String someProperty() default \"\";", + "}")); + } + + private CsvReader compileAndReadCsv() throws IOException { + mJavac.compileWithAnnotationProcessor(new UnsupportedAppUsageProcessor()); + return new CsvReader( + mJavac.getOutputFile("unsupportedappusage/unsupportedappusage_index.csv")); + } + + @Test + public void testSignatureFormat() throws Exception { + mJavac.addSource("a.b.Class", Joiner.on('\n').join( + "package a.b;", + "import dalvik.annotation.compat.UnsupportedAppUsage;", + "public class Class {", + " @UnsupportedAppUsage", + " public void method() {}", + "}")); + assertThat(compileAndReadCsv().getContents().get(0)).containsEntry( + "signature", "La/b/Class;->method()V" + ); + } + + @Test + public void testSourcePosition() throws Exception { + mJavac.addSource("a.b.Class", Joiner.on('\n').join( + "package a.b;", // 1 + "import dalvik.annotation.compat.UnsupportedAppUsage;", // 2 + "public class Class {", // 3 + " @UnsupportedAppUsage", // 4 + " public void method() {}", // 5 + "}")); + Map<String, String> row = compileAndReadCsv().getContents().get(0); + assertThat(row).containsEntry("startline", "4"); + assertThat(row).containsEntry("startcol", "3"); + assertThat(row).containsEntry("endline", "4"); + assertThat(row).containsEntry("endcol", "23"); + } + + @Test + public void testAnnotationProperties() throws Exception { + mJavac.addSource("a.b.Class", Joiner.on('\n').join( + "package a.b;", // 1 + "import dalvik.annotation.compat.UnsupportedAppUsage;", // 2 + "public class Class {", // 3 + " @UnsupportedAppUsage(someProperty=\"value\")", // 4 + " public void method() {}", // 5 + "}")); + assertThat(compileAndReadCsv().getContents().get(0)).containsEntry( + "properties", "someProperty=%22value%22"); + } + + +} diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index d9c1bf22d477..68355c603914 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -3121,6 +3121,7 @@ public class WifiManager { * * @hide */ + @SystemApi public interface SoftApCallback { /** * Called when soft AP state changes. @@ -3149,11 +3150,11 @@ public class WifiManager { * @hide */ private class SoftApCallbackProxy extends ISoftApCallback.Stub { - private final Handler mHandler; + private final Executor mExecutor; private final SoftApCallback mCallback; - SoftApCallbackProxy(Looper looper, SoftApCallback callback) { - mHandler = new Handler(looper); + SoftApCallbackProxy(Executor executor, SoftApCallback callback) { + mExecutor = executor; mCallback = callback; } @@ -3164,7 +3165,8 @@ public class WifiManager { + ", failureReason=" + failureReason); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onStateChanged(state, failureReason); }); } @@ -3176,7 +3178,8 @@ public class WifiManager { + clients.size() + " clients"); } - mHandler.post(() -> { + Binder.clearCallingIdentity(); + mExecutor.execute(() -> { mCallback.onConnectedClientsChanged(clients); }); } @@ -3195,21 +3198,22 @@ public class WifiManager { * <p> * * @param callback Callback for soft AP events - * @param handler The Handler on whose thread to execute the callbacks of the {@code callback} - * object. If null, then the application's main thread will be used. + * @param executor The executor to execute the callbacks of the {@code executor} + * object. If null, then the application's main executor will be used. * * @hide */ + @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public void registerSoftApCallback(@NonNull SoftApCallback callback, - @Nullable Handler handler) { + @Nullable @CallbackExecutor Executor executor) { if (callback == null) throw new IllegalArgumentException("callback cannot be null"); - Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", handler=" + handler); + Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", executor=" + executor); - Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper(); + executor = (executor == null) ? mContext.getMainExecutor() : executor; Binder binder = new Binder(); try { - mService.registerSoftApCallback(binder, new SoftApCallbackProxy(looper, callback), + mService.registerSoftApCallback(binder, new SoftApCallbackProxy(executor, callback), callback.hashCode()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index e14919452ba7..cfdb6f1dd304 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -66,6 +66,7 @@ import android.net.wifi.WifiManager.SoftApCallback; import android.net.wifi.WifiManager.TrafficStateCallback; import android.os.Build; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.IBinder; import android.os.Message; import android.os.Messenger; @@ -685,7 +686,7 @@ public class WifiManagerTest { @Test public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() { try { - mWifiManager.registerSoftApCallback(null, mHandler); + mWifiManager.registerSoftApCallback(null, new HandlerExecutor(mHandler)); fail("expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } @@ -710,7 +711,7 @@ public class WifiManagerTest { public void registerSoftApCallbackUsesMainLooperOnNullArgumentForHandler() { when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); mWifiManager.registerSoftApCallback(mSoftApCallback, null); - verify(mContext).getMainLooper(); + verify(mContext).getMainExecutor(); } /** @@ -718,7 +719,7 @@ public class WifiManagerTest { */ @Test public void registerSoftApCallbackCallGoesToWifiServiceImpl() throws Exception { - mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), anyInt()); } @@ -729,7 +730,7 @@ public class WifiManagerTest { @Test public void unregisterSoftApCallbackCallGoesToWifiServiceImpl() throws Exception { ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), callbackIdentifier.capture()); @@ -744,7 +745,7 @@ public class WifiManagerTest { public void softApCallbackProxyCallsOnStateChanged() throws Exception { ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -760,7 +761,7 @@ public class WifiManagerTest { public void softApCallbackProxyCallsOnConnectedClientsChanged() throws Exception { ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -777,7 +778,7 @@ public class WifiManagerTest { public void softApCallbackProxyCallsOnMultipleUpdates() throws Exception { ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -801,7 +802,7 @@ public class WifiManagerTest { ArgumentCaptor.forClass(ISoftApCallback.Stub.class); TestLooper altLooper = new TestLooper(); Handler altHandler = new Handler(altLooper.getLooper()); - mWifiManager.registerSoftApCallback(mSoftApCallback, altHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(altHandler)); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -815,7 +816,7 @@ public class WifiManagerTest { */ @Test public void testCorrectLooperIsUsedForSoftApCallbackHandler() throws Exception { - mWifiManager.registerSoftApCallback(mSoftApCallback, mHandler); + mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); mLooper.dispatchAll(); verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), anyInt()); |