diff options
153 files changed, 5778 insertions, 2509 deletions
diff --git a/Android.bp b/Android.bp index 891ee91f7ed9..b8d8bc865077 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 { @@ -919,7 +895,10 @@ framework_docs_only_args = " -android -manifest $(location core/res/AndroidManif "-overview $(location core/java/overview.html) " + // Federate Support Library references against local API file. "-federate SupportLib https://developer.android.com " + - "-federationapi SupportLib $(location :current-support-api) " + "-federationapi SupportLib $(location :current-support-api) " + + // Federate Support Library references against local API file. + "-federate AndroidX https://developer.android.com " + + "-federationapi AndroidX $(location :current-androidx-api) " framework_docs_only_libs = [ "voip-common", @@ -998,7 +977,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, @@ -1038,6 +1016,7 @@ doc_defaults { "core/res/AndroidManifest.xml", "core/java/overview.html", ":current-support-api", + ":current-androidx-api", ], create_stubs: false, } @@ -1059,7 +1038,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 19fd711f1f44..c657756ba3e9 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 { @@ -5552,6 +5552,7 @@ package android.app { method @Deprecated public android.app.Notification.Builder setDefaults(int); method @NonNull public android.app.Notification.Builder setDeleteIntent(android.app.PendingIntent); method @NonNull public android.app.Notification.Builder setExtras(android.os.Bundle); + method @NonNull public android.app.Notification.Builder setFlag(int, boolean); method @NonNull public android.app.Notification.Builder setFullScreenIntent(android.app.PendingIntent, boolean); method @NonNull public android.app.Notification.Builder setGroup(String); method @NonNull public android.app.Notification.Builder setGroupAlertBehavior(int); @@ -9771,7 +9772,7 @@ package android.content { method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String); method public abstract void sendOrderedBroadcast(@RequiresPermission android.content.Intent, @Nullable String); method public abstract void sendOrderedBroadcast(@NonNull @RequiresPermission android.content.Intent, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle); - method public void sendOrderedBroadcast(@NonNull @RequiresPermission android.content.Intent, @Nullable String, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle); + method public void sendOrderedBroadcast(@NonNull android.content.Intent, @Nullable String, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle); method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public abstract void sendOrderedBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String, android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle); method @Deprecated @RequiresPermission(android.Manifest.permission.BROADCAST_STICKY) public abstract void sendStickyBroadcast(@RequiresPermission android.content.Intent); method @Deprecated @RequiresPermission(allOf={"android.permission.INTERACT_ACROSS_USERS", android.Manifest.permission.BROADCAST_STICKY}) public abstract void sendStickyBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle); @@ -29891,6 +29892,7 @@ package android.net.wifi { field public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0; // 0x0 field @Deprecated public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE"; field @Deprecated public static final String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE"; + field public static final String UNKNOWN_SSID = "<unknown ssid>"; field @Deprecated public static final int WIFI_MODE_FULL = 1; // 0x1 field public static final int WIFI_MODE_FULL_HIGH_PERF = 3; // 0x3 field public static final int WIFI_MODE_FULL_LOW_LATENCY = 4; // 0x4 @@ -34548,8 +34550,8 @@ package android.os { } public class Handler { - ctor public Handler(); - ctor public Handler(@Nullable android.os.Handler.Callback); + ctor @Deprecated public Handler(); + ctor @Deprecated public Handler(@Nullable android.os.Handler.Callback); ctor public Handler(@NonNull android.os.Looper); ctor public Handler(@NonNull android.os.Looper, @Nullable android.os.Handler.Callback); method @NonNull public static android.os.Handler createAsync(@NonNull android.os.Looper); @@ -43520,6 +43522,7 @@ package android.telecom { field public static final int LOCAL = 2; // 0x2 field public static final int MISSED = 5; // 0x5 field public static final int OTHER = 9; // 0x9 + field public static final String REASON_EMERGENCY_CALL_PLACED = "REASON_EMERGENCY_CALL_PLACED"; field public static final int REJECTED = 6; // 0x6 field public static final int REMOTE = 3; // 0x3 field public static final int RESTRICTED = 8; // 0x8 @@ -44048,6 +44051,7 @@ package android.telephony { field public static final String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL = "allow_add_call_during_video_call"; field public static final String KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL = "allow_emergency_numbers_in_call_log_bool"; field public static final String KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL = "allow_emergency_video_calls_bool"; + field public static final String KEY_ALLOW_HOLD_CALL_DURING_EMERGENCY_BOOL = "allow_hold_call_during_emergency_bool"; field public static final String KEY_ALLOW_LOCAL_DTMF_TONES_BOOL = "allow_local_dtmf_tones_bool"; field public static final String KEY_ALLOW_MERGE_WIFI_CALLS_WHEN_VOWIFI_OFF_BOOL = "allow_merge_wifi_calls_when_vowifi_off_bool"; field public static final String KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL = "allow_non_emergency_calls_in_ecm_bool"; @@ -44064,7 +44068,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"; 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 2a8fb6341da3..685238a7ba02 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -66,6 +66,7 @@ package android { field public static final String CRYPT_KEEPER = "android.permission.CRYPT_KEEPER"; field public static final String DEVICE_POWER = "android.permission.DEVICE_POWER"; field public static final String DISPATCH_PROVISIONING_MESSAGE = "android.permission.DISPATCH_PROVISIONING_MESSAGE"; + field public static final String ENTER_CAR_MODE_PRIORITIZED = "android.permission.ENTER_CAR_MODE_PRIORITIZED"; field public static final String FORCE_BACK = "android.permission.FORCE_BACK"; field public static final String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES"; field public static final String GET_APP_OPS_STATS = "android.permission.GET_APP_OPS_STATS"; @@ -74,6 +75,7 @@ package android { field public static final String GET_TOP_ACTIVITY_INFO = "android.permission.GET_TOP_ACTIVITY_INFO"; field public static final String GRANT_PROFILE_OWNER_DEVICE_IDS_ACCESS = "android.permission.GRANT_PROFILE_OWNER_DEVICE_IDS_ACCESS"; field public static final String GRANT_RUNTIME_PERMISSIONS = "android.permission.GRANT_RUNTIME_PERMISSIONS"; + field public static final String HANDLE_CAR_MODE_CHANGES = "android.permission.HANDLE_CAR_MODE_CHANGES"; field public static final String HARDWARE_TEST = "android.permission.HARDWARE_TEST"; field public static final String HDMI_CEC = "android.permission.HDMI_CEC"; field public static final String HIDE_NON_SYSTEM_OVERLAY_WINDOWS = "android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS"; @@ -602,6 +604,15 @@ package android.app { method public boolean isStatusBarExpansionDisabled(); } + public class UiModeManager { + method @RequiresPermission(android.Manifest.permission.ENTER_CAR_MODE_PRIORITIZED) public void enableCarMode(@IntRange(from=0) int, int); + field public static final String ACTION_ENTER_CAR_MODE_PRIORITIZED = "android.app.action.ENTER_CAR_MODE_PRIORITIZED"; + field public static final String ACTION_EXIT_CAR_MODE_PRIORITIZED = "android.app.action.EXIT_CAR_MODE_PRIORITIZED"; + field public static final int DEFAULT_PRIORITY = 0; // 0x0 + field public static final String EXTRA_CALLING_PACKAGE = "android.app.extra.CALLING_PACKAGE"; + field public static final String EXTRA_PRIORITY = "android.app.extra.PRIORITY"; + } + public final class Vr2dDisplayProperties implements android.os.Parcelable { ctor public Vr2dDisplayProperties(int, int, int); method public int describeContents(); @@ -1239,7 +1250,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(); @@ -1353,8 +1366,9 @@ package android.content { public abstract class Context { method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public boolean bindServiceAsUser(@RequiresPermission android.content.Intent, android.content.ServiceConnection, int, android.os.UserHandle); + method @NonNull public android.content.Context createContextAsUser(@NonNull android.os.UserHandle, int); method public abstract android.content.Context createCredentialProtectedStorageContext(); - method public android.content.Context createPackageContextAsUser(String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public android.content.Context createPackageContextAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException; method @Nullable public abstract java.io.File getPreloadsFileCache(); method public abstract boolean isCredentialProtectedStorage(); method public abstract void sendBroadcast(android.content.Intent, @Nullable String, @Nullable android.os.Bundle); @@ -1746,6 +1760,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; @@ -4705,7 +4720,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.NETWORK_SETTINGS") public void registerSoftApCallback(@Nullable java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.SoftApCallback); 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); @@ -5668,14 +5683,6 @@ package android.os.storage { } -package android.os.telephony { - - public class TelephonyRegistryManager { - method public void notifyCarrierNetworkChange(boolean); - } - -} - package android.permission { public final class PermissionControllerManager { @@ -6144,6 +6151,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"; } @@ -7315,6 +7326,21 @@ package android.telephony { method @NonNull public android.telephony.CarrierRestrictionRules.Builder setMultiSimPolicy(int); } + public class CbGeoUtils { + } + + public static interface CbGeoUtils.Geometry { + method public boolean contains(@NonNull android.telephony.CbGeoUtils.LatLng); + } + + public static class CbGeoUtils.LatLng { + ctor public CbGeoUtils.LatLng(double, double); + method public double distance(@NonNull android.telephony.CbGeoUtils.LatLng); + method @NonNull public android.telephony.CbGeoUtils.LatLng subtract(@NonNull android.telephony.CbGeoUtils.LatLng); + field public final double lat; + field public final double lng; + } + public abstract class CellBroadcastService extends android.app.Service { ctor public CellBroadcastService(); method @CallSuper @NonNull public android.os.IBinder onBind(@Nullable android.content.Intent); @@ -7738,6 +7764,7 @@ package android.telephony { field public static final int NUMBER_UNREACHABLE = 8; // 0x8 field public static final int OTASP_PROVISIONING_IN_PROCESS = 76; // 0x4c field public static final int OUTGOING_CANCELED = 44; // 0x2c + field public static final int OUTGOING_EMERGENCY_CALL_PLACED = 80; // 0x50 field public static final int OUTGOING_FAILURE = 43; // 0x2b field public static final int OUT_OF_NETWORK = 11; // 0xb field public static final int OUT_OF_SERVICE = 18; // 0x12 @@ -7752,6 +7779,14 @@ package android.telephony { field public static final int WIFI_LOST = 59; // 0x3b } + public final class ImsiEncryptionInfo implements android.os.Parcelable { + method public int describeContents(); + method @Nullable public String getKeyIdentifier(); + method @Nullable public java.security.PublicKey getPublicKey(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ImsiEncryptionInfo> CREATOR; + } + public final class LteVopsSupportInfo implements android.os.Parcelable { ctor public LteVopsSupportInfo(int, int); method public int describeContents(); @@ -8107,6 +8142,7 @@ package android.telephony { } public final class SmsCbLocation implements android.os.Parcelable { + ctor public SmsCbLocation(@NonNull String, int, int); method public int describeContents(); method public int getCid(); method public int getLac(); @@ -8118,7 +8154,7 @@ package android.telephony { } public final class SmsCbMessage implements android.os.Parcelable { - ctor public SmsCbMessage(int, int, int, @NonNull android.telephony.SmsCbLocation, int, @Nullable String, @Nullable String, int, @Nullable android.telephony.SmsCbEtwsInfo, @Nullable android.telephony.SmsCbCmasInfo, int); + ctor public SmsCbMessage(int, int, int, @NonNull android.telephony.SmsCbLocation, int, @Nullable String, @Nullable String, int, @Nullable android.telephony.SmsCbEtwsInfo, @Nullable android.telephony.SmsCbCmasInfo, int, @Nullable java.util.List<android.telephony.CbGeoUtils.Geometry>, long, int); method @NonNull public static android.telephony.SmsCbMessage createFromCursor(@NonNull android.database.Cursor); method public int describeContents(); method @Nullable public android.telephony.SmsCbCmasInfo getCmasWarningInfo(); @@ -8127,6 +8163,7 @@ package android.telephony { method public int getGeographicalScope(); method @Nullable public String getLanguageCode(); method @NonNull public android.telephony.SmsCbLocation getLocation(); + method public int getMaximumWaitingDuration(); method @Nullable public String getMessageBody(); method public int getMessageFormat(); method public int getMessagePriority(); @@ -8144,6 +8181,7 @@ package android.telephony { field public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0; // 0x0 field public static final int GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE = 2; // 0x2 field public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1; // 0x1 + field public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255; // 0xff field public static final int MESSAGE_FORMAT_3GPP = 1; // 0x1 field public static final int MESSAGE_FORMAT_3GPP2 = 2; // 0x2 field public static final int MESSAGE_PRIORITY_EMERGENCY = 3; // 0x3 @@ -8229,6 +8267,7 @@ package android.telephony { method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void enableVideoCalling(boolean); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getAidForAppType(int); method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int); + method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int); method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent); method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int); method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierRestrictionRules getCarrierRestrictionRules(); @@ -8278,13 +8317,14 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRadioOn(); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isTetherApnRequired(); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isTetheringApnRequired(); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isVideoCallingEnabled(); method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle); method public boolean needsOtaServiceProvisioning(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio(); method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig(); method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void resetSettings(); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>); @@ -8322,6 +8362,8 @@ package android.telephony { field public static final String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE"; field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL"; field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING"; + field public static final int KEY_TYPE_EPDG = 1; // 0x1 + field public static final int KEY_TYPE_WLAN = 2; // 0x2 field public static final long NETWORK_TYPE_BITMASK_1xRTT = 64L; // 0x40L field public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L field public static final long NETWORK_TYPE_BITMASK_EDGE = 2L; // 0x2L @@ -8362,6 +8404,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(); @@ -8894,7 +8945,7 @@ package android.telephony.ims { public class ImsMmTelManager implements android.telephony.ims.RegistrationManager { method @NonNull public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getFeatureState(@NonNull java.util.function.Consumer<java.lang.Integer>, @NonNull java.util.concurrent.Executor) throws android.telephony.ims.ImsException; + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getFeatureState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws android.telephony.ims.ImsException; method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiModeSetting(); diff --git a/api/test-current.txt b/api/test-current.txt index 1f310c33383c..92d89d40dff9 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -376,6 +376,7 @@ package android.app { } public class UiModeManager { + method @RequiresPermission("android.permission.ENTER_CAR_MODE_PRIORITIZED") public void enableCarMode(@IntRange(from=0) int, int); method public boolean isNightModeLocked(); method public boolean isUiModeLocked(); } @@ -639,7 +640,8 @@ package android.content { } public abstract class Context { - method public android.content.Context createPackageContextAsUser(String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException; + method @NonNull public android.content.Context createContextAsUser(@NonNull android.os.UserHandle, int); + method @NonNull public android.content.Context createPackageContextAsUser(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException; method public abstract android.view.Display getDisplay(); method public abstract int getDisplayId(); method public android.os.UserHandle getUser(); @@ -707,6 +709,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 +742,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; @@ -3228,7 +3232,7 @@ package android.telephony.ims { public class ImsMmTelManager implements android.telephony.ims.RegistrationManager { method @NonNull public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int); - method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getFeatureState(@NonNull java.util.function.Consumer<java.lang.Integer>, @NonNull java.util.concurrent.Executor) throws android.telephony.ims.ImsException; + method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getFeatureState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>) throws android.telephony.ims.ImsException; method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationState(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public void getRegistrationTransportType(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>); method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public int getVoWiFiModeSetting(); diff --git a/config/OWNERS b/config/OWNERS new file mode 100644 index 000000000000..53f80e698d83 --- /dev/null +++ b/config/OWNERS @@ -0,0 +1,5 @@ +# compat-team@ for changes to hiddenapi files +per-file hiddenapi-* = andreionea@google.com, atrost@google.com, mathewi@google.com, satayev@google.com + +# Escalations: +per-file hiddenapi-* = bdc@google.com, narayan@google.com
\ No newline at end of file diff --git a/config/hiddenapi-greylist-max-q.txt b/config/hiddenapi-greylist-max-q.txt new file mode 100644 index 000000000000..f4656044bb72 --- /dev/null +++ b/config/hiddenapi-greylist-max-q.txt @@ -0,0 +1,704 @@ +Landroid/R$styleable;->ActionBar:[I +Landroid/R$styleable;->ActionBar_background:I +Landroid/R$styleable;->ActionBar_backgroundSplit:I +Landroid/R$styleable;->ActionBar_backgroundStacked:I +Landroid/R$styleable;->ActionBar_divider:I +Landroid/R$styleable;->ActionBar_itemPadding:I +Landroid/R$styleable;->CalendarView:[I +Landroid/R$styleable;->CalendarView_dateTextAppearance:I +Landroid/R$styleable;->CalendarView_firstDayOfWeek:I +Landroid/R$styleable;->CalendarView_focusedMonthDateColor:I +Landroid/R$styleable;->CalendarView_selectedDateVerticalBar:I +Landroid/R$styleable;->CalendarView_selectedWeekBackgroundColor:I +Landroid/R$styleable;->CalendarView_shownWeekCount:I +Landroid/R$styleable;->CalendarView_showWeekNumber:I +Landroid/R$styleable;->CalendarView_unfocusedMonthDateColor:I +Landroid/R$styleable;->CalendarView_weekDayTextAppearance:I +Landroid/R$styleable;->CalendarView_weekNumberColor:I +Landroid/R$styleable;->CalendarView_weekSeparatorLineColor:I +Landroid/R$styleable;->CheckBoxPreference:[I +Landroid/R$styleable;->CheckedTextView:[I +Landroid/R$styleable;->CheckedTextView_checkMark:I +Landroid/R$styleable;->CompoundButton:[I +Landroid/R$styleable;->CompoundButton_button:I +Landroid/R$styleable;->ContactsDataKind:[I +Landroid/R$styleable;->DatePicker:[I +Landroid/R$styleable;->DialogPreference:[I +Landroid/R$styleable;->DrawableStates:[I +Landroid/R$styleable;->ExpandableListView:[I +Landroid/R$styleable;->FrameLayout_Layout:[I +Landroid/R$styleable;->HorizontalScrollView:[I +Landroid/R$styleable;->ImageView:[I +Landroid/R$styleable;->ImageView_adjustViewBounds:I +Landroid/R$styleable;->ImageView_baselineAlignBottom:I +Landroid/R$styleable;->ImageView_cropToPadding:I +Landroid/R$styleable;->ImageView_maxHeight:I +Landroid/R$styleable;->ImageView_maxWidth:I +Landroid/R$styleable;->ImageView_scaleType:I +Landroid/R$styleable;->ImageView_src:I +Landroid/R$styleable;->ImageView_tint:I +Landroid/R$styleable;->Keyboard:[I +Landroid/R$styleable;->Keyboard_horizontalGap:I +Landroid/R$styleable;->Keyboard_Key:[I +Landroid/R$styleable;->Keyboard_keyHeight:I +Landroid/R$styleable;->Keyboard_keyWidth:I +Landroid/R$styleable;->Keyboard_Key_codes:I +Landroid/R$styleable;->Keyboard_Key_iconPreview:I +Landroid/R$styleable;->Keyboard_Key_isModifier:I +Landroid/R$styleable;->Keyboard_Key_isRepeatable:I +Landroid/R$styleable;->Keyboard_Key_isSticky:I +Landroid/R$styleable;->Keyboard_Key_keyEdgeFlags:I +Landroid/R$styleable;->Keyboard_Key_keyIcon:I +Landroid/R$styleable;->Keyboard_Key_keyLabel:I +Landroid/R$styleable;->Keyboard_Key_keyOutputText:I +Landroid/R$styleable;->Keyboard_Key_popupCharacters:I +Landroid/R$styleable;->Keyboard_Key_popupKeyboard:I +Landroid/R$styleable;->Keyboard_Row:[I +Landroid/R$styleable;->Keyboard_Row_keyboardMode:I +Landroid/R$styleable;->Keyboard_Row_rowEdgeFlags:I +Landroid/R$styleable;->Keyboard_verticalGap:I +Landroid/R$styleable;->LinearLayout:[I +Landroid/R$styleable;->LinearLayout_baselineAligned:I +Landroid/R$styleable;->LinearLayout_baselineAlignedChildIndex:I +Landroid/R$styleable;->LinearLayout_divider:I +Landroid/R$styleable;->LinearLayout_dividerPadding:I +Landroid/R$styleable;->LinearLayout_gravity:I +Landroid/R$styleable;->LinearLayout_Layout:[I +Landroid/R$styleable;->LinearLayout_Layout_layout_gravity:I +Landroid/R$styleable;->LinearLayout_Layout_layout_height:I +Landroid/R$styleable;->LinearLayout_Layout_layout_weight:I +Landroid/R$styleable;->LinearLayout_Layout_layout_width:I +Landroid/R$styleable;->LinearLayout_measureWithLargestChild:I +Landroid/R$styleable;->LinearLayout_orientation:I +Landroid/R$styleable;->LinearLayout_showDividers:I +Landroid/R$styleable;->ListView:[I +Landroid/R$styleable;->ListView_divider:I +Landroid/R$styleable;->ListView_dividerHeight:I +Landroid/R$styleable;->LockPatternView:[I +Landroid/R$styleable;->NumberPicker:[I +Landroid/R$styleable;->NumberPicker_solidColor:I +Landroid/R$styleable;->PopupWindow:[I +Landroid/R$styleable;->ProgressBar:[I +Landroid/R$styleable;->ProgressBar_indeterminateDrawable:I +Landroid/R$styleable;->ProgressBar_indeterminateDuration:I +Landroid/R$styleable;->ProgressBar_maxHeight:I +Landroid/R$styleable;->ProgressBar_maxWidth:I +Landroid/R$styleable;->ProgressBar_minHeight:I +Landroid/R$styleable;->ProgressBar_minWidth:I +Landroid/R$styleable;->ProgressBar_progressDrawable:I +Landroid/R$styleable;->RingtonePreference:[I +Landroid/R$styleable;->ScrollView:[I +Landroid/R$styleable;->SearchView:[I +Landroid/R$styleable;->SeekBar:[I +Landroid/R$styleable;->SeekBar_thumb:I +Landroid/R$styleable;->SeekBar_thumbOffset:I +Landroid/R$styleable;->SlidingDrawer:[I +Landroid/R$styleable;->SlidingDrawer_allowSingleTap:I +Landroid/R$styleable;->SlidingDrawer_animateOnClick:I +Landroid/R$styleable;->SlidingDrawer_bottomOffset:I +Landroid/R$styleable;->SlidingDrawer_content:I +Landroid/R$styleable;->SlidingDrawer_handle:I +Landroid/R$styleable;->SlidingDrawer_orientation:I +Landroid/R$styleable;->SlidingDrawer_topOffset:I +Landroid/R$styleable;->Switch:[I +Landroid/R$styleable;->Switch_showText:I +Landroid/R$styleable;->Switch_splitTrack:I +Landroid/R$styleable;->Switch_switchMinWidth:I +Landroid/R$styleable;->Switch_switchPadding:I +Landroid/R$styleable;->Switch_switchTextAppearance:I +Landroid/R$styleable;->Switch_textOff:I +Landroid/R$styleable;->Switch_textOn:I +Landroid/R$styleable;->Switch_thumb:I +Landroid/R$styleable;->Switch_thumbTextPadding:I +Landroid/R$styleable;->Switch_track:I +Landroid/R$styleable;->TextAppearance:[I +Landroid/R$styleable;->TextAppearance_textAllCaps:I +Landroid/R$styleable;->TextAppearance_textColor:I +Landroid/R$styleable;->TextAppearance_textColorHighlight:I +Landroid/R$styleable;->TextAppearance_textColorHint:I +Landroid/R$styleable;->TextAppearance_textColorLink:I +Landroid/R$styleable;->TextAppearance_textSize:I +Landroid/R$styleable;->TextAppearance_textStyle:I +Landroid/R$styleable;->TextAppearance_typeface:I +Landroid/R$styleable;->TextView:[I +Landroid/R$styleable;->TextView_autoLink:I +Landroid/R$styleable;->TextView_autoText:I +Landroid/R$styleable;->TextView_bufferType:I +Landroid/R$styleable;->TextView_capitalize:I +Landroid/R$styleable;->TextView_cursorVisible:I +Landroid/R$styleable;->TextView_digits:I +Landroid/R$styleable;->TextView_drawableBottom:I +Landroid/R$styleable;->TextView_drawableEnd:I +Landroid/R$styleable;->TextView_drawableLeft:I +Landroid/R$styleable;->TextView_drawablePadding:I +Landroid/R$styleable;->TextView_drawableRight:I +Landroid/R$styleable;->TextView_drawableStart:I +Landroid/R$styleable;->TextView_drawableTop:I +Landroid/R$styleable;->TextView_editable:I +Landroid/R$styleable;->TextView_ellipsize:I +Landroid/R$styleable;->TextView_ems:I +Landroid/R$styleable;->TextView_enabled:I +Landroid/R$styleable;->TextView_freezesText:I +Landroid/R$styleable;->TextView_gravity:I +Landroid/R$styleable;->TextView_height:I +Landroid/R$styleable;->TextView_hint:I +Landroid/R$styleable;->TextView_imeActionId:I +Landroid/R$styleable;->TextView_imeActionLabel:I +Landroid/R$styleable;->TextView_imeOptions:I +Landroid/R$styleable;->TextView_includeFontPadding:I +Landroid/R$styleable;->TextView_inputMethod:I +Landroid/R$styleable;->TextView_inputType:I +Landroid/R$styleable;->TextView_lines:I +Landroid/R$styleable;->TextView_lineSpacingExtra:I +Landroid/R$styleable;->TextView_lineSpacingMultiplier:I +Landroid/R$styleable;->TextView_linksClickable:I +Landroid/R$styleable;->TextView_marqueeRepeatLimit:I +Landroid/R$styleable;->TextView_maxEms:I +Landroid/R$styleable;->TextView_maxHeight:I +Landroid/R$styleable;->TextView_maxLength:I +Landroid/R$styleable;->TextView_maxLines:I +Landroid/R$styleable;->TextView_maxWidth:I +Landroid/R$styleable;->TextView_minEms:I +Landroid/R$styleable;->TextView_minHeight:I +Landroid/R$styleable;->TextView_minLines:I +Landroid/R$styleable;->TextView_minWidth:I +Landroid/R$styleable;->TextView_numeric:I +Landroid/R$styleable;->TextView_password:I +Landroid/R$styleable;->TextView_phoneNumber:I +Landroid/R$styleable;->TextView_privateImeOptions:I +Landroid/R$styleable;->TextView_scrollHorizontally:I +Landroid/R$styleable;->TextView_selectAllOnFocus:I +Landroid/R$styleable;->TextView_shadowColor:I +Landroid/R$styleable;->TextView_shadowDx:I +Landroid/R$styleable;->TextView_shadowDy:I +Landroid/R$styleable;->TextView_shadowRadius:I +Landroid/R$styleable;->TextView_singleLine:I +Landroid/R$styleable;->TextView_text:I +Landroid/R$styleable;->TextView_textAllCaps:I +Landroid/R$styleable;->TextView_textAppearance:I +Landroid/R$styleable;->TextView_textColor:I +Landroid/R$styleable;->TextView_textColorHighlight:I +Landroid/R$styleable;->TextView_textColorHint:I +Landroid/R$styleable;->TextView_textColorLink:I +Landroid/R$styleable;->TextView_textCursorDrawable:I +Landroid/R$styleable;->TextView_textIsSelectable:I +Landroid/R$styleable;->TextView_textScaleX:I +Landroid/R$styleable;->TextView_textSelectHandle:I +Landroid/R$styleable;->TextView_textSelectHandleLeft:I +Landroid/R$styleable;->TextView_textSelectHandleRight:I +Landroid/R$styleable;->TextView_textSize:I +Landroid/R$styleable;->TextView_textStyle:I +Landroid/R$styleable;->TextView_typeface:I +Landroid/R$styleable;->TextView_width:I +Landroid/R$styleable;->Theme:[I +Landroid/R$styleable;->View:[I +Landroid/R$styleable;->ViewDrawableStates:[I +Landroid/R$styleable;->ViewGroup_Layout:[I +Landroid/R$styleable;->ViewGroup_Layout_layout_height:I +Landroid/R$styleable;->ViewGroup_Layout_layout_width:I +Landroid/R$styleable;->ViewGroup_MarginLayout:[I +Landroid/R$styleable;->ViewGroup_MarginLayout_layout_height:I +Landroid/R$styleable;->ViewGroup_MarginLayout_layout_margin:I +Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginBottom:I +Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginLeft:I +Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginRight:I +Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginTop:I +Landroid/R$styleable;->ViewGroup_MarginLayout_layout_width:I +Landroid/R$styleable;->View_alpha:I +Landroid/R$styleable;->View_background:I +Landroid/R$styleable;->View_clickable:I +Landroid/R$styleable;->View_contentDescription:I +Landroid/R$styleable;->View_drawingCacheQuality:I +Landroid/R$styleable;->View_duplicateParentState:I +Landroid/R$styleable;->View_fadingEdge:I +Landroid/R$styleable;->View_filterTouchesWhenObscured:I +Landroid/R$styleable;->View_fitsSystemWindows:I +Landroid/R$styleable;->View_focusable:I +Landroid/R$styleable;->View_focusableInTouchMode:I +Landroid/R$styleable;->View_hapticFeedbackEnabled:I +Landroid/R$styleable;->View_id:I +Landroid/R$styleable;->View_isScrollContainer:I +Landroid/R$styleable;->View_keepScreenOn:I +Landroid/R$styleable;->View_longClickable:I +Landroid/R$styleable;->View_minHeight:I +Landroid/R$styleable;->View_minWidth:I +Landroid/R$styleable;->View_nextFocusDown:I +Landroid/R$styleable;->View_nextFocusLeft:I +Landroid/R$styleable;->View_nextFocusRight:I +Landroid/R$styleable;->View_nextFocusUp:I +Landroid/R$styleable;->View_onClick:I +Landroid/R$styleable;->View_overScrollMode:I +Landroid/R$styleable;->View_padding:I +Landroid/R$styleable;->View_paddingBottom:I +Landroid/R$styleable;->View_paddingEnd:I +Landroid/R$styleable;->View_paddingLeft:I +Landroid/R$styleable;->View_paddingRight:I +Landroid/R$styleable;->View_paddingStart:I +Landroid/R$styleable;->View_paddingTop:I +Landroid/R$styleable;->View_rotation:I +Landroid/R$styleable;->View_rotationX:I +Landroid/R$styleable;->View_rotationY:I +Landroid/R$styleable;->View_saveEnabled:I +Landroid/R$styleable;->View_scaleX:I +Landroid/R$styleable;->View_scaleY:I +Landroid/R$styleable;->View_scrollbarDefaultDelayBeforeFade:I +Landroid/R$styleable;->View_scrollbarFadeDuration:I +Landroid/R$styleable;->View_scrollbars:I +Landroid/R$styleable;->View_scrollbarSize:I +Landroid/R$styleable;->View_scrollbarStyle:I +Landroid/R$styleable;->View_scrollbarThumbHorizontal:I +Landroid/R$styleable;->View_scrollbarThumbVertical:I +Landroid/R$styleable;->View_scrollbarTrackHorizontal:I +Landroid/R$styleable;->View_scrollbarTrackVertical:I +Landroid/R$styleable;->View_scrollX:I +Landroid/R$styleable;->View_scrollY:I +Landroid/R$styleable;->View_soundEffectsEnabled:I +Landroid/R$styleable;->View_tag:I +Landroid/R$styleable;->View_transformPivotX:I +Landroid/R$styleable;->View_transformPivotY:I +Landroid/R$styleable;->View_translationX:I +Landroid/R$styleable;->View_translationY:I +Landroid/R$styleable;->View_visibility:I +Landroid/R$styleable;->Window:[I +Landroid/R$styleable;->Window_windowBackground:I +Landroid/R$styleable;->Window_windowFrame:I +Lcom/android/internal/R$anim;->fade_in:I +Lcom/android/internal/R$array;->config_autoBrightnessLcdBacklightValues:I +Lcom/android/internal/R$array;->config_autoBrightnessLevels:I +Lcom/android/internal/R$array;->config_mobile_hotspot_provision_app:I +Lcom/android/internal/R$array;->config_sms_enabled_locking_shift_tables:I +Lcom/android/internal/R$array;->config_sms_enabled_single_shift_tables:I +Lcom/android/internal/R$array;->config_tether_bluetooth_regexs:I +Lcom/android/internal/R$array;->config_tether_upstream_types:I +Lcom/android/internal/R$array;->config_tether_usb_regexs:I +Lcom/android/internal/R$array;->config_tether_wifi_regexs:I +Lcom/android/internal/R$array;->maps_starting_lat_lng:I +Lcom/android/internal/R$array;->maps_starting_zoom:I +Lcom/android/internal/R$attr;->actionBarStyle:I +Lcom/android/internal/R$attr;->buttonStyle:I +Lcom/android/internal/R$attr;->description:I +Lcom/android/internal/R$attr;->editTextStyle:I +Lcom/android/internal/R$attr;->mapViewStyle:I +Lcom/android/internal/R$attr;->popupWindowStyle:I +Lcom/android/internal/R$attr;->state_above_anchor:I +Lcom/android/internal/R$attr;->state_focused:I +Lcom/android/internal/R$attr;->state_pressed:I +Lcom/android/internal/R$attr;->state_selected:I +Lcom/android/internal/R$attr;->switchStyle:I +Lcom/android/internal/R$attr;->text:I +Lcom/android/internal/R$attr;->title:I +Lcom/android/internal/R$attr;->webViewStyle:I +Lcom/android/internal/R$bool;-><init>()V +Lcom/android/internal/R$bool;->config_automatic_brightness_available:I +Lcom/android/internal/R$bool;->config_intrusiveNotificationLed:I +Lcom/android/internal/R$bool;->config_mms_content_disposition_support:I +Lcom/android/internal/R$bool;->config_showNavigationBar:I +Lcom/android/internal/R$dimen;-><init>()V +Lcom/android/internal/R$dimen;->item_touch_helper_max_drag_scroll_per_frame:I +Lcom/android/internal/R$dimen;->navigation_bar_height:I +Lcom/android/internal/R$dimen;->navigation_bar_height_landscape:I +Lcom/android/internal/R$dimen;->navigation_bar_width:I +Lcom/android/internal/R$dimen;->status_bar_height:I +Lcom/android/internal/R$dimen;->toast_y_offset:I +Lcom/android/internal/R$drawable;->btn_check_off:I +Lcom/android/internal/R$drawable;->compass_arrow:I +Lcom/android/internal/R$drawable;->compass_base:I +Lcom/android/internal/R$drawable;->ic_maps_indicator_current_position_anim:I +Lcom/android/internal/R$drawable;->ic_menu_close_clear_cancel:I +Lcom/android/internal/R$drawable;->loading_tile_android:I +Lcom/android/internal/R$drawable;->maps_google_logo:I +Lcom/android/internal/R$drawable;->no_tile_256:I +Lcom/android/internal/R$drawable;->reticle:I +Lcom/android/internal/R$drawable;->stat_sys_download:I +Lcom/android/internal/R$fraction;->config_autoBrightnessAdjustmentMaxGamma:I +Lcom/android/internal/R$id;->account_name:I +Lcom/android/internal/R$id;->account_type:I +Lcom/android/internal/R$id;->alertTitle:I +Lcom/android/internal/R$id;->allow_button:I +Lcom/android/internal/R$id;->amPm:I +Lcom/android/internal/R$id;->authtoken_type:I +Lcom/android/internal/R$id;->background:I +Lcom/android/internal/R$id;->back_button:I +Lcom/android/internal/R$id;->body:I +Lcom/android/internal/R$id;->buttonPanel:I +Lcom/android/internal/R$id;->camera:I +Lcom/android/internal/R$id;->cancel:I +Lcom/android/internal/R$id;->clip_children_set_tag:I +Lcom/android/internal/R$id;->clip_children_tag:I +Lcom/android/internal/R$id;->clip_to_padding_tag:I +Lcom/android/internal/R$id;->closeButton:I +Lcom/android/internal/R$id;->content:I +Lcom/android/internal/R$id;->contentPanel:I +Lcom/android/internal/R$id;->custom:I +Lcom/android/internal/R$id;->customPanel:I +Lcom/android/internal/R$id;->datePicker:I +Lcom/android/internal/R$id;->day:I +Lcom/android/internal/R$id;->deny_button:I +Lcom/android/internal/R$id;->description:I +Lcom/android/internal/R$id;->edit:I +Lcom/android/internal/R$id;->edittext_container:I +Lcom/android/internal/R$id;->find_next:I +Lcom/android/internal/R$id;->find_prev:I +Lcom/android/internal/R$id;->icon:I +Lcom/android/internal/R$id;->keyboard:I +Lcom/android/internal/R$id;->keyboardView:I +Lcom/android/internal/R$id;->line1:I +Lcom/android/internal/R$id;->list_item:I +Lcom/android/internal/R$id;->matches:I +Lcom/android/internal/R$id;->mediacontroller_progress:I +Lcom/android/internal/R$id;->media_actions:I +Lcom/android/internal/R$id;->message:I +Lcom/android/internal/R$id;->minute:I +Lcom/android/internal/R$id;->month:I +Lcom/android/internal/R$id;->name:I +Lcom/android/internal/R$id;->notification_header:I +Lcom/android/internal/R$id;->ok:I +Lcom/android/internal/R$id;->overlay:I +Lcom/android/internal/R$id;->packages_list:I +Lcom/android/internal/R$id;->package_label:I +Lcom/android/internal/R$id;->parentPanel:I +Lcom/android/internal/R$id;->pause:I +Lcom/android/internal/R$id;->pending_intent_tag:I +Lcom/android/internal/R$id;->progress:I +Lcom/android/internal/R$id;->redo:I +Lcom/android/internal/R$id;->remote_input_tag:I +Lcom/android/internal/R$id;->right_icon:I +Lcom/android/internal/R$id;->search_src_text:I +Lcom/android/internal/R$id;->share:I +Lcom/android/internal/R$id;->shortcut:I +Lcom/android/internal/R$id;->status_bar_latest_event_content:I +Lcom/android/internal/R$id;->tabcontent:I +Lcom/android/internal/R$id;->tabs:I +Lcom/android/internal/R$id;->text1:I +Lcom/android/internal/R$id;->text2:I +Lcom/android/internal/R$id;->text:I +Lcom/android/internal/R$id;->time:I +Lcom/android/internal/R$id;->timePicker:I +Lcom/android/internal/R$id;->time_current:I +Lcom/android/internal/R$id;->title:I +Lcom/android/internal/R$id;->titleDivider:I +Lcom/android/internal/R$id;->titleDividerTop:I +Lcom/android/internal/R$id;->title_container:I +Lcom/android/internal/R$id;->title_template:I +Lcom/android/internal/R$id;->topPanel:I +Lcom/android/internal/R$id;->up:I +Lcom/android/internal/R$id;->year:I +Lcom/android/internal/R$id;->zoomControls:I +Lcom/android/internal/R$id;->zoomMagnify:I +Lcom/android/internal/R$integer;->config_screenBrightnessDim:I +Lcom/android/internal/R$integer;->config_screenBrightnessSettingMaximum:I +Lcom/android/internal/R$integer;->config_screenBrightnessSettingMinimum:I +Lcom/android/internal/R$integer;->config_toastDefaultGravity:I +Lcom/android/internal/R$interpolator;->accelerate_cubic:I +Lcom/android/internal/R$interpolator;->decelerate_cubic:I +Lcom/android/internal/R$layout;->notification_template_material_base:I +Lcom/android/internal/R$layout;->preference_header_item:I +Lcom/android/internal/R$layout;->screen_title:I +Lcom/android/internal/R$layout;->select_dialog:I +Lcom/android/internal/R$layout;->select_dialog_multichoice:I +Lcom/android/internal/R$layout;->select_dialog_singlechoice:I +Lcom/android/internal/R$layout;->webview_find:I +Lcom/android/internal/R$layout;->zoom_magnify:I +Lcom/android/internal/R$plurals;->matches_found:I +Lcom/android/internal/R$raw;->loaderror:I +Lcom/android/internal/R$raw;->nodomain:I +Lcom/android/internal/R$string;->byteShort:I +Lcom/android/internal/R$string;->cancel:I +Lcom/android/internal/R$string;->enable_explore_by_touch_warning_title:I +Lcom/android/internal/R$string;->gigabyteShort:I +Lcom/android/internal/R$string;->kilobyteShort:I +Lcom/android/internal/R$string;->map:I +Lcom/android/internal/R$string;->megabyteShort:I +Lcom/android/internal/R$string;->notification_title:I +Lcom/android/internal/R$string;->no_matches:I +Lcom/android/internal/R$string;->ok:I +Lcom/android/internal/R$string;->petabyteShort:I +Lcom/android/internal/R$string;->redo:I +Lcom/android/internal/R$string;->share:I +Lcom/android/internal/R$string;->terabyteShort:I +Lcom/android/internal/R$string;->whichApplication:I +Lcom/android/internal/R$style;->Animation_DropDownDown:I +Lcom/android/internal/R$style;->Animation_DropDownUp:I +Lcom/android/internal/R$style;->Animation_PopupWindow:I +Lcom/android/internal/R$style;->Theme:I +Lcom/android/internal/R$style;->Theme_Dialog_Alert:I +Lcom/android/internal/R$style;->Theme_Holo_Light:I +Lcom/android/internal/R$style;->Theme_Light:I +Lcom/android/internal/R$styleable;-><init>()V +Lcom/android/internal/R$styleable;->AbsListView:[I +Lcom/android/internal/R$styleable;->AbsListView_cacheColorHint:I +Lcom/android/internal/R$styleable;->AbsListView_choiceMode:I +Lcom/android/internal/R$styleable;->AbsListView_drawSelectorOnTop:I +Lcom/android/internal/R$styleable;->AbsListView_fastScrollAlwaysVisible:I +Lcom/android/internal/R$styleable;->AbsListView_fastScrollEnabled:I +Lcom/android/internal/R$styleable;->AbsListView_listSelector:I +Lcom/android/internal/R$styleable;->AbsListView_scrollingCache:I +Lcom/android/internal/R$styleable;->AbsListView_smoothScrollbar:I +Lcom/android/internal/R$styleable;->AbsListView_stackFromBottom:I +Lcom/android/internal/R$styleable;->AbsListView_textFilterEnabled:I +Lcom/android/internal/R$styleable;->AbsListView_transcriptMode:I +Lcom/android/internal/R$styleable;->AbsSpinner:[I +Lcom/android/internal/R$styleable;->AccountAuthenticator:[I +Lcom/android/internal/R$styleable;->AccountAuthenticator_accountPreferences:I +Lcom/android/internal/R$styleable;->AccountAuthenticator_accountType:I +Lcom/android/internal/R$styleable;->AccountAuthenticator_customTokens:I +Lcom/android/internal/R$styleable;->AccountAuthenticator_icon:I +Lcom/android/internal/R$styleable;->AccountAuthenticator_label:I +Lcom/android/internal/R$styleable;->AccountAuthenticator_smallIcon:I +Lcom/android/internal/R$styleable;->ActionMode:[I +Lcom/android/internal/R$styleable;->AdapterViewAnimator:[I +Lcom/android/internal/R$styleable;->AdapterViewFlipper:[I +Lcom/android/internal/R$styleable;->AlertDialog:[I +Lcom/android/internal/R$styleable;->AnalogClock:[I +Lcom/android/internal/R$styleable;->AndroidManifest:[I +Lcom/android/internal/R$styleable;->AndroidManifestActivity:[I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_allowTaskReparenting:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_configChanges:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_description:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_enabled:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_excludeFromRecents:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_exported:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_hardwareAccelerated:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_icon:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_immersive:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_label:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_launchMode:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_logo:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_name:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_noHistory:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_permission:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_process:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_screenOrientation:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_taskAffinity:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_theme:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_uiOptions:I +Lcom/android/internal/R$styleable;->AndroidManifestActivity_windowSoftInputMode:I +Lcom/android/internal/R$styleable;->AndroidManifestApplication:[I +Lcom/android/internal/R$styleable;->AndroidManifestApplication_enabled:I +Lcom/android/internal/R$styleable;->AndroidManifestApplication_hardwareAccelerated:I +Lcom/android/internal/R$styleable;->AndroidManifestApplication_label:I +Lcom/android/internal/R$styleable;->AndroidManifestApplication_largeHeap:I +Lcom/android/internal/R$styleable;->AndroidManifestApplication_name:I +Lcom/android/internal/R$styleable;->AndroidManifestApplication_permission:I +Lcom/android/internal/R$styleable;->AndroidManifestApplication_process:I +Lcom/android/internal/R$styleable;->AndroidManifestApplication_supportsRtl:I +Lcom/android/internal/R$styleable;->AndroidManifestApplication_theme:I +Lcom/android/internal/R$styleable;->AndroidManifestApplication_uiOptions:I +Lcom/android/internal/R$styleable;->AndroidManifestData:[I +Lcom/android/internal/R$styleable;->AndroidManifestIntentFilter:[I +Lcom/android/internal/R$styleable;->AndroidManifestIntentFilter_priority:I +Lcom/android/internal/R$styleable;->AndroidManifestMetaData:[I +Lcom/android/internal/R$styleable;->AndroidManifestMetaData_name:I +Lcom/android/internal/R$styleable;->AndroidManifestMetaData_resource:I +Lcom/android/internal/R$styleable;->AndroidManifestMetaData_value:I +Lcom/android/internal/R$styleable;->AndroidManifestPackageVerifier:[I +Lcom/android/internal/R$styleable;->AndroidManifestProvider:[I +Lcom/android/internal/R$styleable;->AndroidManifestService:[I +Lcom/android/internal/R$styleable;->AndroidManifestService_enabled:I +Lcom/android/internal/R$styleable;->AndroidManifestService_exported:I +Lcom/android/internal/R$styleable;->AndroidManifestService_name:I +Lcom/android/internal/R$styleable;->AndroidManifestService_permission:I +Lcom/android/internal/R$styleable;->AndroidManifestService_process:I +Lcom/android/internal/R$styleable;->AndroidManifestUsesLibrary:[I +Lcom/android/internal/R$styleable;->AndroidManifestUsesPermission:[I +Lcom/android/internal/R$styleable;->AndroidManifestUsesPermission_name:I +Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk:[I +Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk_minSdkVersion:I +Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk_targetSdkVersion:I +Lcom/android/internal/R$styleable;->AndroidManifest_installLocation:I +Lcom/android/internal/R$styleable;->AndroidManifest_sharedUserId:I +Lcom/android/internal/R$styleable;->AndroidManifest_versionCode:I +Lcom/android/internal/R$styleable;->AndroidManifest_versionName:I +Lcom/android/internal/R$styleable;->AutoCompleteTextView:[I +Lcom/android/internal/R$styleable;->CheckBoxPreference:[I +Lcom/android/internal/R$styleable;->CheckBoxPreference_disableDependentsState:I +Lcom/android/internal/R$styleable;->CheckBoxPreference_summaryOff:I +Lcom/android/internal/R$styleable;->CheckBoxPreference_summaryOn:I +Lcom/android/internal/R$styleable;->CheckedTextView:[I +Lcom/android/internal/R$styleable;->CheckedTextView_checked:I +Lcom/android/internal/R$styleable;->CheckedTextView_checkMark:I +Lcom/android/internal/R$styleable;->CompoundButton:[I +Lcom/android/internal/R$styleable;->CompoundButton_button:I +Lcom/android/internal/R$styleable;->CompoundButton_checked:I +Lcom/android/internal/R$styleable;->ContactsDataKind:[I +Lcom/android/internal/R$styleable;->DatePicker:[I +Lcom/android/internal/R$styleable;->DialogPreference:[I +Lcom/android/internal/R$styleable;->DialogPreference_dialogTitle:I +Lcom/android/internal/R$styleable;->Dream:[I +Lcom/android/internal/R$styleable;->EdgeEffect:[I +Lcom/android/internal/R$styleable;->EdgeEffect_colorEdgeEffect:I +Lcom/android/internal/R$styleable;->FastScroll:[I +Lcom/android/internal/R$styleable;->FrameLayout:[I +Lcom/android/internal/R$styleable;->FrameLayout_Layout:[I +Lcom/android/internal/R$styleable;->Gallery:[I +Lcom/android/internal/R$styleable;->GridView:[I +Lcom/android/internal/R$styleable;->IconMenuView:[I +Lcom/android/internal/R$styleable;->ImageView:[I +Lcom/android/internal/R$styleable;->ImageView_scaleType:I +Lcom/android/internal/R$styleable;->ImageView_src:I +Lcom/android/internal/R$styleable;->Keyboard:[I +Lcom/android/internal/R$styleable;->KeyboardView:[I +Lcom/android/internal/R$styleable;->Keyboard_Key:[I +Lcom/android/internal/R$styleable;->Keyboard_Row:[I +Lcom/android/internal/R$styleable;->ListPreference:[I +Lcom/android/internal/R$styleable;->ListPreference_entries:I +Lcom/android/internal/R$styleable;->ListView:[I +Lcom/android/internal/R$styleable;->ListView_divider:I +Lcom/android/internal/R$styleable;->ListView_dividerHeight:I +Lcom/android/internal/R$styleable;->ListView_entries:I +Lcom/android/internal/R$styleable;->ListView_footerDividersEnabled:I +Lcom/android/internal/R$styleable;->ListView_headerDividersEnabled:I +Lcom/android/internal/R$styleable;->ListView_overScrollFooter:I +Lcom/android/internal/R$styleable;->ListView_overScrollHeader:I +Lcom/android/internal/R$styleable;->MapView:[I +Lcom/android/internal/R$styleable;->MapView_apiKey:I +Lcom/android/internal/R$styleable;->MenuGroup:[I +Lcom/android/internal/R$styleable;->MenuItem:[I +Lcom/android/internal/R$styleable;->NumberPicker:[I +Lcom/android/internal/R$styleable;->PopupWindow:[I +Lcom/android/internal/R$styleable;->PopupWindow_popupAnimationStyle:I +Lcom/android/internal/R$styleable;->PopupWindow_popupBackground:I +Lcom/android/internal/R$styleable;->Preference:[I +Lcom/android/internal/R$styleable;->PreferenceGroup:[I +Lcom/android/internal/R$styleable;->PreferenceGroup_orderingFromXml:I +Lcom/android/internal/R$styleable;->Preference_defaultValue:I +Lcom/android/internal/R$styleable;->Preference_dependency:I +Lcom/android/internal/R$styleable;->Preference_enabled:I +Lcom/android/internal/R$styleable;->Preference_fragment:I +Lcom/android/internal/R$styleable;->Preference_icon:I +Lcom/android/internal/R$styleable;->Preference_key:I +Lcom/android/internal/R$styleable;->Preference_layout:I +Lcom/android/internal/R$styleable;->Preference_order:I +Lcom/android/internal/R$styleable;->Preference_persistent:I +Lcom/android/internal/R$styleable;->Preference_selectable:I +Lcom/android/internal/R$styleable;->Preference_shouldDisableView:I +Lcom/android/internal/R$styleable;->Preference_summary:I +Lcom/android/internal/R$styleable;->Preference_title:I +Lcom/android/internal/R$styleable;->Preference_widgetLayout:I +Lcom/android/internal/R$styleable;->ProgressBar:[I +Lcom/android/internal/R$styleable;->QuickContactBadge:[I +Lcom/android/internal/R$styleable;->RingtonePreference:[I +Lcom/android/internal/R$styleable;->ScrollView:[I +Lcom/android/internal/R$styleable;->ScrollView_fillViewport:I +Lcom/android/internal/R$styleable;->SelectionModeDrawables:[I +Lcom/android/internal/R$styleable;->Switch:[I +Lcom/android/internal/R$styleable;->SwitchPreference:[I +Lcom/android/internal/R$styleable;->SyncAdapter:[I +Lcom/android/internal/R$styleable;->SyncAdapter_accountType:I +Lcom/android/internal/R$styleable;->SyncAdapter_allowParallelSyncs:I +Lcom/android/internal/R$styleable;->SyncAdapter_contentAuthority:I +Lcom/android/internal/R$styleable;->SyncAdapter_isAlwaysSyncable:I +Lcom/android/internal/R$styleable;->SyncAdapter_settingsActivity:I +Lcom/android/internal/R$styleable;->SyncAdapter_supportsUploading:I +Lcom/android/internal/R$styleable;->SyncAdapter_userVisible:I +Lcom/android/internal/R$styleable;->TabWidget:[I +Lcom/android/internal/R$styleable;->TextAppearance:[I +Lcom/android/internal/R$styleable;->TextAppearance_fontFamily:I +Lcom/android/internal/R$styleable;->TextAppearance_textAllCaps:I +Lcom/android/internal/R$styleable;->TextAppearance_textColor:I +Lcom/android/internal/R$styleable;->TextAppearance_textColorHighlight:I +Lcom/android/internal/R$styleable;->TextAppearance_textColorHint:I +Lcom/android/internal/R$styleable;->TextAppearance_textColorLink:I +Lcom/android/internal/R$styleable;->TextAppearance_textSize:I +Lcom/android/internal/R$styleable;->TextAppearance_textStyle:I +Lcom/android/internal/R$styleable;->TextAppearance_typeface:I +Lcom/android/internal/R$styleable;->TextClock:[I +Lcom/android/internal/R$styleable;->TextView:[I +Lcom/android/internal/R$styleable;->TextViewAppearance:[I +Lcom/android/internal/R$styleable;->TextViewAppearance_textAppearance:I +Lcom/android/internal/R$styleable;->TextView_autoLink:I +Lcom/android/internal/R$styleable;->TextView_autoText:I +Lcom/android/internal/R$styleable;->TextView_bufferType:I +Lcom/android/internal/R$styleable;->TextView_capitalize:I +Lcom/android/internal/R$styleable;->TextView_cursorVisible:I +Lcom/android/internal/R$styleable;->TextView_digits:I +Lcom/android/internal/R$styleable;->TextView_drawableBottom:I +Lcom/android/internal/R$styleable;->TextView_drawableEnd:I +Lcom/android/internal/R$styleable;->TextView_drawableLeft:I +Lcom/android/internal/R$styleable;->TextView_drawablePadding:I +Lcom/android/internal/R$styleable;->TextView_drawableRight:I +Lcom/android/internal/R$styleable;->TextView_drawableStart:I +Lcom/android/internal/R$styleable;->TextView_drawableTop:I +Lcom/android/internal/R$styleable;->TextView_editable:I +Lcom/android/internal/R$styleable;->TextView_editorExtras:I +Lcom/android/internal/R$styleable;->TextView_ellipsize:I +Lcom/android/internal/R$styleable;->TextView_ems:I +Lcom/android/internal/R$styleable;->TextView_enabled:I +Lcom/android/internal/R$styleable;->TextView_freezesText:I +Lcom/android/internal/R$styleable;->TextView_gravity:I +Lcom/android/internal/R$styleable;->TextView_height:I +Lcom/android/internal/R$styleable;->TextView_hint:I +Lcom/android/internal/R$styleable;->TextView_imeActionId:I +Lcom/android/internal/R$styleable;->TextView_imeActionLabel:I +Lcom/android/internal/R$styleable;->TextView_imeOptions:I +Lcom/android/internal/R$styleable;->TextView_includeFontPadding:I +Lcom/android/internal/R$styleable;->TextView_inputMethod:I +Lcom/android/internal/R$styleable;->TextView_inputType:I +Lcom/android/internal/R$styleable;->TextView_lines:I +Lcom/android/internal/R$styleable;->TextView_lineSpacingExtra:I +Lcom/android/internal/R$styleable;->TextView_lineSpacingMultiplier:I +Lcom/android/internal/R$styleable;->TextView_linksClickable:I +Lcom/android/internal/R$styleable;->TextView_marqueeRepeatLimit:I +Lcom/android/internal/R$styleable;->TextView_maxEms:I +Lcom/android/internal/R$styleable;->TextView_maxHeight:I +Lcom/android/internal/R$styleable;->TextView_maxLength:I +Lcom/android/internal/R$styleable;->TextView_maxLines:I +Lcom/android/internal/R$styleable;->TextView_maxWidth:I +Lcom/android/internal/R$styleable;->TextView_minEms:I +Lcom/android/internal/R$styleable;->TextView_minHeight:I +Lcom/android/internal/R$styleable;->TextView_minLines:I +Lcom/android/internal/R$styleable;->TextView_minWidth:I +Lcom/android/internal/R$styleable;->TextView_numeric:I +Lcom/android/internal/R$styleable;->TextView_password:I +Lcom/android/internal/R$styleable;->TextView_phoneNumber:I +Lcom/android/internal/R$styleable;->TextView_privateImeOptions:I +Lcom/android/internal/R$styleable;->TextView_scrollHorizontally:I +Lcom/android/internal/R$styleable;->TextView_selectAllOnFocus:I +Lcom/android/internal/R$styleable;->TextView_shadowColor:I +Lcom/android/internal/R$styleable;->TextView_shadowDx:I +Lcom/android/internal/R$styleable;->TextView_shadowDy:I +Lcom/android/internal/R$styleable;->TextView_shadowRadius:I +Lcom/android/internal/R$styleable;->TextView_singleLine:I +Lcom/android/internal/R$styleable;->TextView_text:I +Lcom/android/internal/R$styleable;->TextView_textAllCaps:I +Lcom/android/internal/R$styleable;->TextView_textAppearance:I +Lcom/android/internal/R$styleable;->TextView_textColor:I +Lcom/android/internal/R$styleable;->TextView_textColorHighlight:I +Lcom/android/internal/R$styleable;->TextView_textColorHint:I +Lcom/android/internal/R$styleable;->TextView_textColorLink:I +Lcom/android/internal/R$styleable;->TextView_textCursorDrawable:I +Lcom/android/internal/R$styleable;->TextView_textEditSuggestionItemLayout:I +Lcom/android/internal/R$styleable;->TextView_textIsSelectable:I +Lcom/android/internal/R$styleable;->TextView_textScaleX:I +Lcom/android/internal/R$styleable;->TextView_textSelectHandle:I +Lcom/android/internal/R$styleable;->TextView_textSelectHandleLeft:I +Lcom/android/internal/R$styleable;->TextView_textSelectHandleRight:I +Lcom/android/internal/R$styleable;->TextView_textSize:I +Lcom/android/internal/R$styleable;->TextView_textStyle:I +Lcom/android/internal/R$styleable;->TextView_typeface:I +Lcom/android/internal/R$styleable;->TextView_width:I +Lcom/android/internal/R$styleable;->Theme:[I +Lcom/android/internal/R$styleable;->TwoLineListItem:[I +Lcom/android/internal/R$styleable;->View:[I +Lcom/android/internal/R$styleable;->ViewAnimator:[I +Lcom/android/internal/R$styleable;->ViewFlipper:[I +Lcom/android/internal/R$styleable;->ViewGroup_Layout:[I +Lcom/android/internal/R$styleable;->ViewGroup_Layout_layout_height:I +Lcom/android/internal/R$styleable;->ViewGroup_Layout_layout_width:I +Lcom/android/internal/R$styleable;->ViewStub:[I +Lcom/android/internal/R$styleable;->ViewStub_inflatedId:I +Lcom/android/internal/R$styleable;->ViewStub_layout:I +Lcom/android/internal/R$styleable;->View_background:I +Lcom/android/internal/R$styleable;->View_clickable:I +Lcom/android/internal/R$styleable;->View_focusable:I +Lcom/android/internal/R$styleable;->View_id:I +Lcom/android/internal/R$styleable;->View_longClickable:I +Lcom/android/internal/R$styleable;->WallpaperPreviewInfo:[I +Lcom/android/internal/R$styleable;->Window:[I +Lcom/android/internal/R$styleable;->Window_windowActionBarFullscreenDecorLayout:I +Lcom/android/internal/R$styleable;->Window_windowBackground:I +Lcom/android/internal/R$styleable;->Window_windowFullscreen:I +Lcom/android/internal/R$styleable;->Window_windowIsFloating:I +Lcom/android/internal/R$styleable;->Window_windowIsTranslucent:I +Lcom/android/internal/R$styleable;->Window_windowShowWallpaper:I +Lcom/android/internal/R$xml;->power_profile:I diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt index 2d3394be1ad0..52caa421201f 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -238,270 +238,6 @@ Landroid/os/IVibratorService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os Landroid/os/storage/IObbActionListener$Stub;-><init>()V Landroid/os/storage/IStorageManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/os/storage/IStorageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IStorageManager; -Landroid/R$styleable;->ActionBar:[I -Landroid/R$styleable;->ActionBar_background:I -Landroid/R$styleable;->ActionBar_backgroundSplit:I -Landroid/R$styleable;->ActionBar_backgroundStacked:I -Landroid/R$styleable;->ActionBar_divider:I -Landroid/R$styleable;->ActionBar_itemPadding:I -Landroid/R$styleable;->CalendarView:[I -Landroid/R$styleable;->CalendarView_dateTextAppearance:I -Landroid/R$styleable;->CalendarView_firstDayOfWeek:I -Landroid/R$styleable;->CalendarView_focusedMonthDateColor:I -Landroid/R$styleable;->CalendarView_selectedDateVerticalBar:I -Landroid/R$styleable;->CalendarView_selectedWeekBackgroundColor:I -Landroid/R$styleable;->CalendarView_shownWeekCount:I -Landroid/R$styleable;->CalendarView_showWeekNumber:I -Landroid/R$styleable;->CalendarView_unfocusedMonthDateColor:I -Landroid/R$styleable;->CalendarView_weekDayTextAppearance:I -Landroid/R$styleable;->CalendarView_weekNumberColor:I -Landroid/R$styleable;->CalendarView_weekSeparatorLineColor:I -Landroid/R$styleable;->CheckBoxPreference:[I -Landroid/R$styleable;->CheckedTextView:[I -Landroid/R$styleable;->CheckedTextView_checkMark:I -Landroid/R$styleable;->CompoundButton:[I -Landroid/R$styleable;->CompoundButton_button:I -Landroid/R$styleable;->ContactsDataKind:[I -Landroid/R$styleable;->DatePicker:[I -Landroid/R$styleable;->DialogPreference:[I -Landroid/R$styleable;->DrawableStates:[I -Landroid/R$styleable;->ExpandableListView:[I -Landroid/R$styleable;->FrameLayout_Layout:[I -Landroid/R$styleable;->HorizontalScrollView:[I -Landroid/R$styleable;->ImageView:[I -Landroid/R$styleable;->ImageView_adjustViewBounds:I -Landroid/R$styleable;->ImageView_baselineAlignBottom:I -Landroid/R$styleable;->ImageView_cropToPadding:I -Landroid/R$styleable;->ImageView_maxHeight:I -Landroid/R$styleable;->ImageView_maxWidth:I -Landroid/R$styleable;->ImageView_scaleType:I -Landroid/R$styleable;->ImageView_src:I -Landroid/R$styleable;->ImageView_tint:I -Landroid/R$styleable;->Keyboard:[I -Landroid/R$styleable;->Keyboard_horizontalGap:I -Landroid/R$styleable;->Keyboard_Key:[I -Landroid/R$styleable;->Keyboard_keyHeight:I -Landroid/R$styleable;->Keyboard_keyWidth:I -Landroid/R$styleable;->Keyboard_Key_codes:I -Landroid/R$styleable;->Keyboard_Key_iconPreview:I -Landroid/R$styleable;->Keyboard_Key_isModifier:I -Landroid/R$styleable;->Keyboard_Key_isRepeatable:I -Landroid/R$styleable;->Keyboard_Key_isSticky:I -Landroid/R$styleable;->Keyboard_Key_keyEdgeFlags:I -Landroid/R$styleable;->Keyboard_Key_keyIcon:I -Landroid/R$styleable;->Keyboard_Key_keyLabel:I -Landroid/R$styleable;->Keyboard_Key_keyOutputText:I -Landroid/R$styleable;->Keyboard_Key_popupCharacters:I -Landroid/R$styleable;->Keyboard_Key_popupKeyboard:I -Landroid/R$styleable;->Keyboard_Row:[I -Landroid/R$styleable;->Keyboard_Row_keyboardMode:I -Landroid/R$styleable;->Keyboard_Row_rowEdgeFlags:I -Landroid/R$styleable;->Keyboard_verticalGap:I -Landroid/R$styleable;->LinearLayout:[I -Landroid/R$styleable;->LinearLayout_baselineAligned:I -Landroid/R$styleable;->LinearLayout_baselineAlignedChildIndex:I -Landroid/R$styleable;->LinearLayout_divider:I -Landroid/R$styleable;->LinearLayout_dividerPadding:I -Landroid/R$styleable;->LinearLayout_gravity:I -Landroid/R$styleable;->LinearLayout_Layout:[I -Landroid/R$styleable;->LinearLayout_Layout_layout_gravity:I -Landroid/R$styleable;->LinearLayout_Layout_layout_height:I -Landroid/R$styleable;->LinearLayout_Layout_layout_weight:I -Landroid/R$styleable;->LinearLayout_Layout_layout_width:I -Landroid/R$styleable;->LinearLayout_measureWithLargestChild:I -Landroid/R$styleable;->LinearLayout_orientation:I -Landroid/R$styleable;->LinearLayout_showDividers:I -Landroid/R$styleable;->ListView:[I -Landroid/R$styleable;->ListView_divider:I -Landroid/R$styleable;->ListView_dividerHeight:I -Landroid/R$styleable;->LockPatternView:[I -Landroid/R$styleable;->NumberPicker:[I -Landroid/R$styleable;->NumberPicker_solidColor:I -Landroid/R$styleable;->PopupWindow:[I -Landroid/R$styleable;->ProgressBar:[I -Landroid/R$styleable;->ProgressBar_indeterminateDrawable:I -Landroid/R$styleable;->ProgressBar_indeterminateDuration:I -Landroid/R$styleable;->ProgressBar_maxHeight:I -Landroid/R$styleable;->ProgressBar_maxWidth:I -Landroid/R$styleable;->ProgressBar_minHeight:I -Landroid/R$styleable;->ProgressBar_minWidth:I -Landroid/R$styleable;->ProgressBar_progressDrawable:I -Landroid/R$styleable;->RingtonePreference:[I -Landroid/R$styleable;->ScrollView:[I -Landroid/R$styleable;->SearchView:[I -Landroid/R$styleable;->SeekBar:[I -Landroid/R$styleable;->SeekBar_thumb:I -Landroid/R$styleable;->SeekBar_thumbOffset:I -Landroid/R$styleable;->SlidingDrawer:[I -Landroid/R$styleable;->SlidingDrawer_allowSingleTap:I -Landroid/R$styleable;->SlidingDrawer_animateOnClick:I -Landroid/R$styleable;->SlidingDrawer_bottomOffset:I -Landroid/R$styleable;->SlidingDrawer_content:I -Landroid/R$styleable;->SlidingDrawer_handle:I -Landroid/R$styleable;->SlidingDrawer_orientation:I -Landroid/R$styleable;->SlidingDrawer_topOffset:I -Landroid/R$styleable;->Switch:[I -Landroid/R$styleable;->Switch_showText:I -Landroid/R$styleable;->Switch_splitTrack:I -Landroid/R$styleable;->Switch_switchMinWidth:I -Landroid/R$styleable;->Switch_switchPadding:I -Landroid/R$styleable;->Switch_switchTextAppearance:I -Landroid/R$styleable;->Switch_textOff:I -Landroid/R$styleable;->Switch_textOn:I -Landroid/R$styleable;->Switch_thumb:I -Landroid/R$styleable;->Switch_thumbTextPadding:I -Landroid/R$styleable;->Switch_track:I -Landroid/R$styleable;->TextAppearance:[I -Landroid/R$styleable;->TextAppearance_textAllCaps:I -Landroid/R$styleable;->TextAppearance_textColor:I -Landroid/R$styleable;->TextAppearance_textColorHighlight:I -Landroid/R$styleable;->TextAppearance_textColorHint:I -Landroid/R$styleable;->TextAppearance_textColorLink:I -Landroid/R$styleable;->TextAppearance_textSize:I -Landroid/R$styleable;->TextAppearance_textStyle:I -Landroid/R$styleable;->TextAppearance_typeface:I -Landroid/R$styleable;->TextView:[I -Landroid/R$styleable;->TextView_autoLink:I -Landroid/R$styleable;->TextView_autoText:I -Landroid/R$styleable;->TextView_bufferType:I -Landroid/R$styleable;->TextView_capitalize:I -Landroid/R$styleable;->TextView_cursorVisible:I -Landroid/R$styleable;->TextView_digits:I -Landroid/R$styleable;->TextView_drawableBottom:I -Landroid/R$styleable;->TextView_drawableEnd:I -Landroid/R$styleable;->TextView_drawableLeft:I -Landroid/R$styleable;->TextView_drawablePadding:I -Landroid/R$styleable;->TextView_drawableRight:I -Landroid/R$styleable;->TextView_drawableStart:I -Landroid/R$styleable;->TextView_drawableTop:I -Landroid/R$styleable;->TextView_editable:I -Landroid/R$styleable;->TextView_ellipsize:I -Landroid/R$styleable;->TextView_ems:I -Landroid/R$styleable;->TextView_enabled:I -Landroid/R$styleable;->TextView_freezesText:I -Landroid/R$styleable;->TextView_gravity:I -Landroid/R$styleable;->TextView_height:I -Landroid/R$styleable;->TextView_hint:I -Landroid/R$styleable;->TextView_imeActionId:I -Landroid/R$styleable;->TextView_imeActionLabel:I -Landroid/R$styleable;->TextView_imeOptions:I -Landroid/R$styleable;->TextView_includeFontPadding:I -Landroid/R$styleable;->TextView_inputMethod:I -Landroid/R$styleable;->TextView_inputType:I -Landroid/R$styleable;->TextView_lines:I -Landroid/R$styleable;->TextView_lineSpacingExtra:I -Landroid/R$styleable;->TextView_lineSpacingMultiplier:I -Landroid/R$styleable;->TextView_linksClickable:I -Landroid/R$styleable;->TextView_marqueeRepeatLimit:I -Landroid/R$styleable;->TextView_maxEms:I -Landroid/R$styleable;->TextView_maxHeight:I -Landroid/R$styleable;->TextView_maxLength:I -Landroid/R$styleable;->TextView_maxLines:I -Landroid/R$styleable;->TextView_maxWidth:I -Landroid/R$styleable;->TextView_minEms:I -Landroid/R$styleable;->TextView_minHeight:I -Landroid/R$styleable;->TextView_minLines:I -Landroid/R$styleable;->TextView_minWidth:I -Landroid/R$styleable;->TextView_numeric:I -Landroid/R$styleable;->TextView_password:I -Landroid/R$styleable;->TextView_phoneNumber:I -Landroid/R$styleable;->TextView_privateImeOptions:I -Landroid/R$styleable;->TextView_scrollHorizontally:I -Landroid/R$styleable;->TextView_selectAllOnFocus:I -Landroid/R$styleable;->TextView_shadowColor:I -Landroid/R$styleable;->TextView_shadowDx:I -Landroid/R$styleable;->TextView_shadowDy:I -Landroid/R$styleable;->TextView_shadowRadius:I -Landroid/R$styleable;->TextView_singleLine:I -Landroid/R$styleable;->TextView_text:I -Landroid/R$styleable;->TextView_textAllCaps:I -Landroid/R$styleable;->TextView_textAppearance:I -Landroid/R$styleable;->TextView_textColor:I -Landroid/R$styleable;->TextView_textColorHighlight:I -Landroid/R$styleable;->TextView_textColorHint:I -Landroid/R$styleable;->TextView_textColorLink:I -Landroid/R$styleable;->TextView_textCursorDrawable:I -Landroid/R$styleable;->TextView_textIsSelectable:I -Landroid/R$styleable;->TextView_textScaleX:I -Landroid/R$styleable;->TextView_textSelectHandle:I -Landroid/R$styleable;->TextView_textSelectHandleLeft:I -Landroid/R$styleable;->TextView_textSelectHandleRight:I -Landroid/R$styleable;->TextView_textSize:I -Landroid/R$styleable;->TextView_textStyle:I -Landroid/R$styleable;->TextView_typeface:I -Landroid/R$styleable;->TextView_width:I -Landroid/R$styleable;->Theme:[I -Landroid/R$styleable;->View:[I -Landroid/R$styleable;->ViewDrawableStates:[I -Landroid/R$styleable;->ViewGroup_Layout:[I -Landroid/R$styleable;->ViewGroup_Layout_layout_height:I -Landroid/R$styleable;->ViewGroup_Layout_layout_width:I -Landroid/R$styleable;->ViewGroup_MarginLayout:[I -Landroid/R$styleable;->ViewGroup_MarginLayout_layout_height:I -Landroid/R$styleable;->ViewGroup_MarginLayout_layout_margin:I -Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginBottom:I -Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginLeft:I -Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginRight:I -Landroid/R$styleable;->ViewGroup_MarginLayout_layout_marginTop:I -Landroid/R$styleable;->ViewGroup_MarginLayout_layout_width:I -Landroid/R$styleable;->View_alpha:I -Landroid/R$styleable;->View_background:I -Landroid/R$styleable;->View_clickable:I -Landroid/R$styleable;->View_contentDescription:I -Landroid/R$styleable;->View_drawingCacheQuality:I -Landroid/R$styleable;->View_duplicateParentState:I -Landroid/R$styleable;->View_fadingEdge:I -Landroid/R$styleable;->View_filterTouchesWhenObscured:I -Landroid/R$styleable;->View_fitsSystemWindows:I -Landroid/R$styleable;->View_focusable:I -Landroid/R$styleable;->View_focusableInTouchMode:I -Landroid/R$styleable;->View_hapticFeedbackEnabled:I -Landroid/R$styleable;->View_id:I -Landroid/R$styleable;->View_isScrollContainer:I -Landroid/R$styleable;->View_keepScreenOn:I -Landroid/R$styleable;->View_longClickable:I -Landroid/R$styleable;->View_minHeight:I -Landroid/R$styleable;->View_minWidth:I -Landroid/R$styleable;->View_nextFocusDown:I -Landroid/R$styleable;->View_nextFocusLeft:I -Landroid/R$styleable;->View_nextFocusRight:I -Landroid/R$styleable;->View_nextFocusUp:I -Landroid/R$styleable;->View_onClick:I -Landroid/R$styleable;->View_overScrollMode:I -Landroid/R$styleable;->View_padding:I -Landroid/R$styleable;->View_paddingBottom:I -Landroid/R$styleable;->View_paddingEnd:I -Landroid/R$styleable;->View_paddingLeft:I -Landroid/R$styleable;->View_paddingRight:I -Landroid/R$styleable;->View_paddingStart:I -Landroid/R$styleable;->View_paddingTop:I -Landroid/R$styleable;->View_rotation:I -Landroid/R$styleable;->View_rotationX:I -Landroid/R$styleable;->View_rotationY:I -Landroid/R$styleable;->View_saveEnabled:I -Landroid/R$styleable;->View_scaleX:I -Landroid/R$styleable;->View_scaleY:I -Landroid/R$styleable;->View_scrollbarDefaultDelayBeforeFade:I -Landroid/R$styleable;->View_scrollbarFadeDuration:I -Landroid/R$styleable;->View_scrollbars:I -Landroid/R$styleable;->View_scrollbarSize:I -Landroid/R$styleable;->View_scrollbarStyle:I -Landroid/R$styleable;->View_scrollbarThumbHorizontal:I -Landroid/R$styleable;->View_scrollbarThumbVertical:I -Landroid/R$styleable;->View_scrollbarTrackHorizontal:I -Landroid/R$styleable;->View_scrollbarTrackVertical:I -Landroid/R$styleable;->View_scrollX:I -Landroid/R$styleable;->View_scrollY:I -Landroid/R$styleable;->View_soundEffectsEnabled:I -Landroid/R$styleable;->View_tag:I -Landroid/R$styleable;->View_transformPivotX:I -Landroid/R$styleable;->View_transformPivotY:I -Landroid/R$styleable;->View_translationX:I -Landroid/R$styleable;->View_translationY:I -Landroid/R$styleable;->View_visibility:I -Landroid/R$styleable;->Window:[I -Landroid/R$styleable;->Window_windowBackground:I -Landroid/R$styleable;->Window_windowFrame:I Landroid/security/IKeyChainService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/security/IKeyChainService; Landroid/security/keystore/IKeystoreService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/security/keystore/IKeystoreService; Landroid/service/dreams/IDreamManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/dreams/IDreamManager; @@ -589,446 +325,6 @@ Lcom/android/internal/location/ILocationProviderManager$Stub;->asInterface(Landr Lcom/android/internal/os/IDropBoxManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/os/IDropBoxManagerService; Lcom/android/internal/policy/IKeyguardService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardService; Lcom/android/internal/policy/IKeyguardStateCallback$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardStateCallback; -Lcom/android/internal/R$anim;->fade_in:I -Lcom/android/internal/R$array;->config_autoBrightnessLcdBacklightValues:I -Lcom/android/internal/R$array;->config_autoBrightnessLevels:I -Lcom/android/internal/R$array;->config_mobile_hotspot_provision_app:I -Lcom/android/internal/R$array;->config_sms_enabled_locking_shift_tables:I -Lcom/android/internal/R$array;->config_sms_enabled_single_shift_tables:I -Lcom/android/internal/R$array;->config_tether_bluetooth_regexs:I -Lcom/android/internal/R$array;->config_tether_upstream_types:I -Lcom/android/internal/R$array;->config_tether_usb_regexs:I -Lcom/android/internal/R$array;->config_tether_wifi_regexs:I -Lcom/android/internal/R$array;->maps_starting_lat_lng:I -Lcom/android/internal/R$array;->maps_starting_zoom:I -Lcom/android/internal/R$attr;->actionBarStyle:I -Lcom/android/internal/R$attr;->buttonStyle:I -Lcom/android/internal/R$attr;->description:I -Lcom/android/internal/R$attr;->editTextStyle:I -Lcom/android/internal/R$attr;->mapViewStyle:I -Lcom/android/internal/R$attr;->popupWindowStyle:I -Lcom/android/internal/R$attr;->state_above_anchor:I -Lcom/android/internal/R$attr;->state_focused:I -Lcom/android/internal/R$attr;->state_pressed:I -Lcom/android/internal/R$attr;->state_selected:I -Lcom/android/internal/R$attr;->switchStyle:I -Lcom/android/internal/R$attr;->text:I -Lcom/android/internal/R$attr;->title:I -Lcom/android/internal/R$attr;->webViewStyle:I -Lcom/android/internal/R$bool;-><init>()V -Lcom/android/internal/R$bool;->config_automatic_brightness_available:I -Lcom/android/internal/R$bool;->config_intrusiveNotificationLed:I -Lcom/android/internal/R$bool;->config_mms_content_disposition_support:I -Lcom/android/internal/R$bool;->config_showNavigationBar:I -Lcom/android/internal/R$dimen;-><init>()V -Lcom/android/internal/R$dimen;->item_touch_helper_max_drag_scroll_per_frame:I -Lcom/android/internal/R$dimen;->navigation_bar_height:I -Lcom/android/internal/R$dimen;->navigation_bar_height_landscape:I -Lcom/android/internal/R$dimen;->navigation_bar_width:I -Lcom/android/internal/R$dimen;->status_bar_height:I -Lcom/android/internal/R$dimen;->toast_y_offset:I -Lcom/android/internal/R$drawable;->btn_check_off:I -Lcom/android/internal/R$drawable;->compass_arrow:I -Lcom/android/internal/R$drawable;->compass_base:I -Lcom/android/internal/R$drawable;->ic_maps_indicator_current_position_anim:I -Lcom/android/internal/R$drawable;->ic_menu_close_clear_cancel:I -Lcom/android/internal/R$drawable;->loading_tile_android:I -Lcom/android/internal/R$drawable;->maps_google_logo:I -Lcom/android/internal/R$drawable;->no_tile_256:I -Lcom/android/internal/R$drawable;->reticle:I -Lcom/android/internal/R$drawable;->stat_sys_download:I -Lcom/android/internal/R$fraction;->config_autoBrightnessAdjustmentMaxGamma:I -Lcom/android/internal/R$id;->account_name:I -Lcom/android/internal/R$id;->account_type:I -Lcom/android/internal/R$id;->alertTitle:I -Lcom/android/internal/R$id;->allow_button:I -Lcom/android/internal/R$id;->amPm:I -Lcom/android/internal/R$id;->authtoken_type:I -Lcom/android/internal/R$id;->background:I -Lcom/android/internal/R$id;->back_button:I -Lcom/android/internal/R$id;->body:I -Lcom/android/internal/R$id;->buttonPanel:I -Lcom/android/internal/R$id;->camera:I -Lcom/android/internal/R$id;->cancel:I -Lcom/android/internal/R$id;->clip_children_set_tag:I -Lcom/android/internal/R$id;->clip_children_tag:I -Lcom/android/internal/R$id;->clip_to_padding_tag:I -Lcom/android/internal/R$id;->closeButton:I -Lcom/android/internal/R$id;->content:I -Lcom/android/internal/R$id;->contentPanel:I -Lcom/android/internal/R$id;->custom:I -Lcom/android/internal/R$id;->customPanel:I -Lcom/android/internal/R$id;->datePicker:I -Lcom/android/internal/R$id;->day:I -Lcom/android/internal/R$id;->deny_button:I -Lcom/android/internal/R$id;->description:I -Lcom/android/internal/R$id;->edit:I -Lcom/android/internal/R$id;->edittext_container:I -Lcom/android/internal/R$id;->find_next:I -Lcom/android/internal/R$id;->find_prev:I -Lcom/android/internal/R$id;->icon:I -Lcom/android/internal/R$id;->keyboard:I -Lcom/android/internal/R$id;->keyboardView:I -Lcom/android/internal/R$id;->line1:I -Lcom/android/internal/R$id;->list_item:I -Lcom/android/internal/R$id;->matches:I -Lcom/android/internal/R$id;->mediacontroller_progress:I -Lcom/android/internal/R$id;->media_actions:I -Lcom/android/internal/R$id;->message:I -Lcom/android/internal/R$id;->minute:I -Lcom/android/internal/R$id;->month:I -Lcom/android/internal/R$id;->name:I -Lcom/android/internal/R$id;->notification_header:I -Lcom/android/internal/R$id;->ok:I -Lcom/android/internal/R$id;->overlay:I -Lcom/android/internal/R$id;->packages_list:I -Lcom/android/internal/R$id;->package_label:I -Lcom/android/internal/R$id;->parentPanel:I -Lcom/android/internal/R$id;->pause:I -Lcom/android/internal/R$id;->pending_intent_tag:I -Lcom/android/internal/R$id;->progress:I -Lcom/android/internal/R$id;->redo:I -Lcom/android/internal/R$id;->remote_input_tag:I -Lcom/android/internal/R$id;->right_icon:I -Lcom/android/internal/R$id;->search_src_text:I -Lcom/android/internal/R$id;->share:I -Lcom/android/internal/R$id;->shortcut:I -Lcom/android/internal/R$id;->status_bar_latest_event_content:I -Lcom/android/internal/R$id;->tabcontent:I -Lcom/android/internal/R$id;->tabs:I -Lcom/android/internal/R$id;->text1:I -Lcom/android/internal/R$id;->text2:I -Lcom/android/internal/R$id;->text:I -Lcom/android/internal/R$id;->time:I -Lcom/android/internal/R$id;->timePicker:I -Lcom/android/internal/R$id;->time_current:I -Lcom/android/internal/R$id;->title:I -Lcom/android/internal/R$id;->titleDivider:I -Lcom/android/internal/R$id;->titleDividerTop:I -Lcom/android/internal/R$id;->title_container:I -Lcom/android/internal/R$id;->title_template:I -Lcom/android/internal/R$id;->topPanel:I -Lcom/android/internal/R$id;->up:I -Lcom/android/internal/R$id;->year:I -Lcom/android/internal/R$id;->zoomControls:I -Lcom/android/internal/R$id;->zoomMagnify:I -Lcom/android/internal/R$integer;->config_screenBrightnessDim:I -Lcom/android/internal/R$integer;->config_screenBrightnessSettingMaximum:I -Lcom/android/internal/R$integer;->config_screenBrightnessSettingMinimum:I -Lcom/android/internal/R$integer;->config_toastDefaultGravity:I -Lcom/android/internal/R$interpolator;->accelerate_cubic:I -Lcom/android/internal/R$interpolator;->decelerate_cubic:I -Lcom/android/internal/R$layout;->notification_template_material_base:I -Lcom/android/internal/R$layout;->preference_header_item:I -Lcom/android/internal/R$layout;->screen_title:I -Lcom/android/internal/R$layout;->select_dialog:I -Lcom/android/internal/R$layout;->select_dialog_multichoice:I -Lcom/android/internal/R$layout;->select_dialog_singlechoice:I -Lcom/android/internal/R$layout;->webview_find:I -Lcom/android/internal/R$layout;->zoom_magnify:I -Lcom/android/internal/R$plurals;->matches_found:I -Lcom/android/internal/R$raw;->loaderror:I -Lcom/android/internal/R$raw;->nodomain:I -Lcom/android/internal/R$string;->byteShort:I -Lcom/android/internal/R$string;->cancel:I -Lcom/android/internal/R$string;->enable_explore_by_touch_warning_title:I -Lcom/android/internal/R$string;->gigabyteShort:I -Lcom/android/internal/R$string;->kilobyteShort:I -Lcom/android/internal/R$string;->map:I -Lcom/android/internal/R$string;->megabyteShort:I -Lcom/android/internal/R$string;->notification_title:I -Lcom/android/internal/R$string;->no_matches:I -Lcom/android/internal/R$string;->ok:I -Lcom/android/internal/R$string;->petabyteShort:I -Lcom/android/internal/R$string;->redo:I -Lcom/android/internal/R$string;->share:I -Lcom/android/internal/R$string;->terabyteShort:I -Lcom/android/internal/R$string;->whichApplication:I -Lcom/android/internal/R$style;->Animation_DropDownDown:I -Lcom/android/internal/R$style;->Animation_DropDownUp:I -Lcom/android/internal/R$style;->Animation_PopupWindow:I -Lcom/android/internal/R$style;->Theme:I -Lcom/android/internal/R$style;->Theme_Dialog_Alert:I -Lcom/android/internal/R$style;->Theme_Holo_Light:I -Lcom/android/internal/R$style;->Theme_Light:I -Lcom/android/internal/R$styleable;-><init>()V -Lcom/android/internal/R$styleable;->AbsListView:[I -Lcom/android/internal/R$styleable;->AbsListView_cacheColorHint:I -Lcom/android/internal/R$styleable;->AbsListView_choiceMode:I -Lcom/android/internal/R$styleable;->AbsListView_drawSelectorOnTop:I -Lcom/android/internal/R$styleable;->AbsListView_fastScrollAlwaysVisible:I -Lcom/android/internal/R$styleable;->AbsListView_fastScrollEnabled:I -Lcom/android/internal/R$styleable;->AbsListView_listSelector:I -Lcom/android/internal/R$styleable;->AbsListView_scrollingCache:I -Lcom/android/internal/R$styleable;->AbsListView_smoothScrollbar:I -Lcom/android/internal/R$styleable;->AbsListView_stackFromBottom:I -Lcom/android/internal/R$styleable;->AbsListView_textFilterEnabled:I -Lcom/android/internal/R$styleable;->AbsListView_transcriptMode:I -Lcom/android/internal/R$styleable;->AbsSpinner:[I -Lcom/android/internal/R$styleable;->AccountAuthenticator:[I -Lcom/android/internal/R$styleable;->AccountAuthenticator_accountPreferences:I -Lcom/android/internal/R$styleable;->AccountAuthenticator_accountType:I -Lcom/android/internal/R$styleable;->AccountAuthenticator_customTokens:I -Lcom/android/internal/R$styleable;->AccountAuthenticator_icon:I -Lcom/android/internal/R$styleable;->AccountAuthenticator_label:I -Lcom/android/internal/R$styleable;->AccountAuthenticator_smallIcon:I -Lcom/android/internal/R$styleable;->ActionMode:[I -Lcom/android/internal/R$styleable;->AdapterViewAnimator:[I -Lcom/android/internal/R$styleable;->AdapterViewFlipper:[I -Lcom/android/internal/R$styleable;->AlertDialog:[I -Lcom/android/internal/R$styleable;->AnalogClock:[I -Lcom/android/internal/R$styleable;->AndroidManifest:[I -Lcom/android/internal/R$styleable;->AndroidManifestActivity:[I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_allowTaskReparenting:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_configChanges:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_description:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_enabled:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_excludeFromRecents:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_exported:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_hardwareAccelerated:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_icon:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_immersive:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_label:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_launchMode:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_logo:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_name:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_noHistory:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_permission:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_process:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_screenOrientation:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_taskAffinity:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_theme:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_uiOptions:I -Lcom/android/internal/R$styleable;->AndroidManifestActivity_windowSoftInputMode:I -Lcom/android/internal/R$styleable;->AndroidManifestApplication:[I -Lcom/android/internal/R$styleable;->AndroidManifestApplication_enabled:I -Lcom/android/internal/R$styleable;->AndroidManifestApplication_hardwareAccelerated:I -Lcom/android/internal/R$styleable;->AndroidManifestApplication_label:I -Lcom/android/internal/R$styleable;->AndroidManifestApplication_largeHeap:I -Lcom/android/internal/R$styleable;->AndroidManifestApplication_name:I -Lcom/android/internal/R$styleable;->AndroidManifestApplication_permission:I -Lcom/android/internal/R$styleable;->AndroidManifestApplication_process:I -Lcom/android/internal/R$styleable;->AndroidManifestApplication_supportsRtl:I -Lcom/android/internal/R$styleable;->AndroidManifestApplication_theme:I -Lcom/android/internal/R$styleable;->AndroidManifestApplication_uiOptions:I -Lcom/android/internal/R$styleable;->AndroidManifestData:[I -Lcom/android/internal/R$styleable;->AndroidManifestIntentFilter:[I -Lcom/android/internal/R$styleable;->AndroidManifestIntentFilter_priority:I -Lcom/android/internal/R$styleable;->AndroidManifestMetaData:[I -Lcom/android/internal/R$styleable;->AndroidManifestMetaData_name:I -Lcom/android/internal/R$styleable;->AndroidManifestMetaData_resource:I -Lcom/android/internal/R$styleable;->AndroidManifestMetaData_value:I -Lcom/android/internal/R$styleable;->AndroidManifestPackageVerifier:[I -Lcom/android/internal/R$styleable;->AndroidManifestProvider:[I -Lcom/android/internal/R$styleable;->AndroidManifestService:[I -Lcom/android/internal/R$styleable;->AndroidManifestService_enabled:I -Lcom/android/internal/R$styleable;->AndroidManifestService_exported:I -Lcom/android/internal/R$styleable;->AndroidManifestService_name:I -Lcom/android/internal/R$styleable;->AndroidManifestService_permission:I -Lcom/android/internal/R$styleable;->AndroidManifestService_process:I -Lcom/android/internal/R$styleable;->AndroidManifestUsesLibrary:[I -Lcom/android/internal/R$styleable;->AndroidManifestUsesPermission:[I -Lcom/android/internal/R$styleable;->AndroidManifestUsesPermission_name:I -Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk:[I -Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk_minSdkVersion:I -Lcom/android/internal/R$styleable;->AndroidManifestUsesSdk_targetSdkVersion:I -Lcom/android/internal/R$styleable;->AndroidManifest_installLocation:I -Lcom/android/internal/R$styleable;->AndroidManifest_sharedUserId:I -Lcom/android/internal/R$styleable;->AndroidManifest_versionCode:I -Lcom/android/internal/R$styleable;->AndroidManifest_versionName:I -Lcom/android/internal/R$styleable;->AutoCompleteTextView:[I -Lcom/android/internal/R$styleable;->CheckBoxPreference:[I -Lcom/android/internal/R$styleable;->CheckBoxPreference_disableDependentsState:I -Lcom/android/internal/R$styleable;->CheckBoxPreference_summaryOff:I -Lcom/android/internal/R$styleable;->CheckBoxPreference_summaryOn:I -Lcom/android/internal/R$styleable;->CheckedTextView:[I -Lcom/android/internal/R$styleable;->CheckedTextView_checked:I -Lcom/android/internal/R$styleable;->CheckedTextView_checkMark:I -Lcom/android/internal/R$styleable;->CompoundButton:[I -Lcom/android/internal/R$styleable;->CompoundButton_button:I -Lcom/android/internal/R$styleable;->CompoundButton_checked:I -Lcom/android/internal/R$styleable;->ContactsDataKind:[I -Lcom/android/internal/R$styleable;->DatePicker:[I -Lcom/android/internal/R$styleable;->DialogPreference:[I -Lcom/android/internal/R$styleable;->DialogPreference_dialogTitle:I -Lcom/android/internal/R$styleable;->Dream:[I -Lcom/android/internal/R$styleable;->EdgeEffect:[I -Lcom/android/internal/R$styleable;->EdgeEffect_colorEdgeEffect:I -Lcom/android/internal/R$styleable;->FastScroll:[I -Lcom/android/internal/R$styleable;->FrameLayout:[I -Lcom/android/internal/R$styleable;->FrameLayout_Layout:[I -Lcom/android/internal/R$styleable;->Gallery:[I -Lcom/android/internal/R$styleable;->GridView:[I -Lcom/android/internal/R$styleable;->IconMenuView:[I -Lcom/android/internal/R$styleable;->ImageView:[I -Lcom/android/internal/R$styleable;->ImageView_scaleType:I -Lcom/android/internal/R$styleable;->ImageView_src:I -Lcom/android/internal/R$styleable;->Keyboard:[I -Lcom/android/internal/R$styleable;->KeyboardView:[I -Lcom/android/internal/R$styleable;->Keyboard_Key:[I -Lcom/android/internal/R$styleable;->Keyboard_Row:[I -Lcom/android/internal/R$styleable;->ListPreference:[I -Lcom/android/internal/R$styleable;->ListPreference_entries:I -Lcom/android/internal/R$styleable;->ListView:[I -Lcom/android/internal/R$styleable;->ListView_divider:I -Lcom/android/internal/R$styleable;->ListView_dividerHeight:I -Lcom/android/internal/R$styleable;->ListView_entries:I -Lcom/android/internal/R$styleable;->ListView_footerDividersEnabled:I -Lcom/android/internal/R$styleable;->ListView_headerDividersEnabled:I -Lcom/android/internal/R$styleable;->ListView_overScrollFooter:I -Lcom/android/internal/R$styleable;->ListView_overScrollHeader:I -Lcom/android/internal/R$styleable;->MapView:[I -Lcom/android/internal/R$styleable;->MapView_apiKey:I -Lcom/android/internal/R$styleable;->MenuGroup:[I -Lcom/android/internal/R$styleable;->MenuItem:[I -Lcom/android/internal/R$styleable;->NumberPicker:[I -Lcom/android/internal/R$styleable;->PopupWindow:[I -Lcom/android/internal/R$styleable;->PopupWindow_popupAnimationStyle:I -Lcom/android/internal/R$styleable;->PopupWindow_popupBackground:I -Lcom/android/internal/R$styleable;->Preference:[I -Lcom/android/internal/R$styleable;->PreferenceGroup:[I -Lcom/android/internal/R$styleable;->PreferenceGroup_orderingFromXml:I -Lcom/android/internal/R$styleable;->Preference_defaultValue:I -Lcom/android/internal/R$styleable;->Preference_dependency:I -Lcom/android/internal/R$styleable;->Preference_enabled:I -Lcom/android/internal/R$styleable;->Preference_fragment:I -Lcom/android/internal/R$styleable;->Preference_icon:I -Lcom/android/internal/R$styleable;->Preference_key:I -Lcom/android/internal/R$styleable;->Preference_layout:I -Lcom/android/internal/R$styleable;->Preference_order:I -Lcom/android/internal/R$styleable;->Preference_persistent:I -Lcom/android/internal/R$styleable;->Preference_selectable:I -Lcom/android/internal/R$styleable;->Preference_shouldDisableView:I -Lcom/android/internal/R$styleable;->Preference_summary:I -Lcom/android/internal/R$styleable;->Preference_title:I -Lcom/android/internal/R$styleable;->Preference_widgetLayout:I -Lcom/android/internal/R$styleable;->ProgressBar:[I -Lcom/android/internal/R$styleable;->QuickContactBadge:[I -Lcom/android/internal/R$styleable;->RingtonePreference:[I -Lcom/android/internal/R$styleable;->ScrollView:[I -Lcom/android/internal/R$styleable;->ScrollView_fillViewport:I -Lcom/android/internal/R$styleable;->SelectionModeDrawables:[I -Lcom/android/internal/R$styleable;->Switch:[I -Lcom/android/internal/R$styleable;->SwitchPreference:[I -Lcom/android/internal/R$styleable;->SyncAdapter:[I -Lcom/android/internal/R$styleable;->SyncAdapter_accountType:I -Lcom/android/internal/R$styleable;->SyncAdapter_allowParallelSyncs:I -Lcom/android/internal/R$styleable;->SyncAdapter_contentAuthority:I -Lcom/android/internal/R$styleable;->SyncAdapter_isAlwaysSyncable:I -Lcom/android/internal/R$styleable;->SyncAdapter_settingsActivity:I -Lcom/android/internal/R$styleable;->SyncAdapter_supportsUploading:I -Lcom/android/internal/R$styleable;->SyncAdapter_userVisible:I -Lcom/android/internal/R$styleable;->TabWidget:[I -Lcom/android/internal/R$styleable;->TextAppearance:[I -Lcom/android/internal/R$styleable;->TextAppearance_fontFamily:I -Lcom/android/internal/R$styleable;->TextAppearance_textAllCaps:I -Lcom/android/internal/R$styleable;->TextAppearance_textColor:I -Lcom/android/internal/R$styleable;->TextAppearance_textColorHighlight:I -Lcom/android/internal/R$styleable;->TextAppearance_textColorHint:I -Lcom/android/internal/R$styleable;->TextAppearance_textColorLink:I -Lcom/android/internal/R$styleable;->TextAppearance_textSize:I -Lcom/android/internal/R$styleable;->TextAppearance_textStyle:I -Lcom/android/internal/R$styleable;->TextAppearance_typeface:I -Lcom/android/internal/R$styleable;->TextClock:[I -Lcom/android/internal/R$styleable;->TextView:[I -Lcom/android/internal/R$styleable;->TextViewAppearance:[I -Lcom/android/internal/R$styleable;->TextViewAppearance_textAppearance:I -Lcom/android/internal/R$styleable;->TextView_autoLink:I -Lcom/android/internal/R$styleable;->TextView_autoText:I -Lcom/android/internal/R$styleable;->TextView_bufferType:I -Lcom/android/internal/R$styleable;->TextView_capitalize:I -Lcom/android/internal/R$styleable;->TextView_cursorVisible:I -Lcom/android/internal/R$styleable;->TextView_digits:I -Lcom/android/internal/R$styleable;->TextView_drawableBottom:I -Lcom/android/internal/R$styleable;->TextView_drawableEnd:I -Lcom/android/internal/R$styleable;->TextView_drawableLeft:I -Lcom/android/internal/R$styleable;->TextView_drawablePadding:I -Lcom/android/internal/R$styleable;->TextView_drawableRight:I -Lcom/android/internal/R$styleable;->TextView_drawableStart:I -Lcom/android/internal/R$styleable;->TextView_drawableTop:I -Lcom/android/internal/R$styleable;->TextView_editable:I -Lcom/android/internal/R$styleable;->TextView_editorExtras:I -Lcom/android/internal/R$styleable;->TextView_ellipsize:I -Lcom/android/internal/R$styleable;->TextView_ems:I -Lcom/android/internal/R$styleable;->TextView_enabled:I -Lcom/android/internal/R$styleable;->TextView_freezesText:I -Lcom/android/internal/R$styleable;->TextView_gravity:I -Lcom/android/internal/R$styleable;->TextView_height:I -Lcom/android/internal/R$styleable;->TextView_hint:I -Lcom/android/internal/R$styleable;->TextView_imeActionId:I -Lcom/android/internal/R$styleable;->TextView_imeActionLabel:I -Lcom/android/internal/R$styleable;->TextView_imeOptions:I -Lcom/android/internal/R$styleable;->TextView_includeFontPadding:I -Lcom/android/internal/R$styleable;->TextView_inputMethod:I -Lcom/android/internal/R$styleable;->TextView_inputType:I -Lcom/android/internal/R$styleable;->TextView_lines:I -Lcom/android/internal/R$styleable;->TextView_lineSpacingExtra:I -Lcom/android/internal/R$styleable;->TextView_lineSpacingMultiplier:I -Lcom/android/internal/R$styleable;->TextView_linksClickable:I -Lcom/android/internal/R$styleable;->TextView_marqueeRepeatLimit:I -Lcom/android/internal/R$styleable;->TextView_maxEms:I -Lcom/android/internal/R$styleable;->TextView_maxHeight:I -Lcom/android/internal/R$styleable;->TextView_maxLength:I -Lcom/android/internal/R$styleable;->TextView_maxLines:I -Lcom/android/internal/R$styleable;->TextView_maxWidth:I -Lcom/android/internal/R$styleable;->TextView_minEms:I -Lcom/android/internal/R$styleable;->TextView_minHeight:I -Lcom/android/internal/R$styleable;->TextView_minLines:I -Lcom/android/internal/R$styleable;->TextView_minWidth:I -Lcom/android/internal/R$styleable;->TextView_numeric:I -Lcom/android/internal/R$styleable;->TextView_password:I -Lcom/android/internal/R$styleable;->TextView_phoneNumber:I -Lcom/android/internal/R$styleable;->TextView_privateImeOptions:I -Lcom/android/internal/R$styleable;->TextView_scrollHorizontally:I -Lcom/android/internal/R$styleable;->TextView_selectAllOnFocus:I -Lcom/android/internal/R$styleable;->TextView_shadowColor:I -Lcom/android/internal/R$styleable;->TextView_shadowDx:I -Lcom/android/internal/R$styleable;->TextView_shadowDy:I -Lcom/android/internal/R$styleable;->TextView_shadowRadius:I -Lcom/android/internal/R$styleable;->TextView_singleLine:I -Lcom/android/internal/R$styleable;->TextView_text:I -Lcom/android/internal/R$styleable;->TextView_textAllCaps:I -Lcom/android/internal/R$styleable;->TextView_textAppearance:I -Lcom/android/internal/R$styleable;->TextView_textColor:I -Lcom/android/internal/R$styleable;->TextView_textColorHighlight:I -Lcom/android/internal/R$styleable;->TextView_textColorHint:I -Lcom/android/internal/R$styleable;->TextView_textColorLink:I -Lcom/android/internal/R$styleable;->TextView_textCursorDrawable:I -Lcom/android/internal/R$styleable;->TextView_textEditSuggestionItemLayout:I -Lcom/android/internal/R$styleable;->TextView_textIsSelectable:I -Lcom/android/internal/R$styleable;->TextView_textScaleX:I -Lcom/android/internal/R$styleable;->TextView_textSelectHandle:I -Lcom/android/internal/R$styleable;->TextView_textSelectHandleLeft:I -Lcom/android/internal/R$styleable;->TextView_textSelectHandleRight:I -Lcom/android/internal/R$styleable;->TextView_textSize:I -Lcom/android/internal/R$styleable;->TextView_textStyle:I -Lcom/android/internal/R$styleable;->TextView_typeface:I -Lcom/android/internal/R$styleable;->TextView_width:I -Lcom/android/internal/R$styleable;->Theme:[I -Lcom/android/internal/R$styleable;->TwoLineListItem:[I -Lcom/android/internal/R$styleable;->View:[I -Lcom/android/internal/R$styleable;->ViewAnimator:[I -Lcom/android/internal/R$styleable;->ViewFlipper:[I -Lcom/android/internal/R$styleable;->ViewGroup_Layout:[I -Lcom/android/internal/R$styleable;->ViewGroup_Layout_layout_height:I -Lcom/android/internal/R$styleable;->ViewGroup_Layout_layout_width:I -Lcom/android/internal/R$styleable;->ViewStub:[I -Lcom/android/internal/R$styleable;->ViewStub_inflatedId:I -Lcom/android/internal/R$styleable;->ViewStub_layout:I -Lcom/android/internal/R$styleable;->View_background:I -Lcom/android/internal/R$styleable;->View_clickable:I -Lcom/android/internal/R$styleable;->View_focusable:I -Lcom/android/internal/R$styleable;->View_id:I -Lcom/android/internal/R$styleable;->View_longClickable:I -Lcom/android/internal/R$styleable;->WallpaperPreviewInfo:[I -Lcom/android/internal/R$styleable;->Window:[I -Lcom/android/internal/R$styleable;->Window_windowActionBarFullscreenDecorLayout:I -Lcom/android/internal/R$styleable;->Window_windowBackground:I -Lcom/android/internal/R$styleable;->Window_windowFullscreen:I -Lcom/android/internal/R$styleable;->Window_windowIsFloating:I -Lcom/android/internal/R$styleable;->Window_windowIsTranslucent:I -Lcom/android/internal/R$styleable;->Window_windowShowWallpaper:I -Lcom/android/internal/R$xml;->power_profile:I Lcom/android/internal/statusbar/IStatusBar$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/statusbar/IStatusBar; Lcom/android/internal/statusbar/IStatusBarService$Stub;-><init>()V Lcom/android/internal/statusbar/IStatusBarService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/statusbar/IStatusBarService; 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/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/ContextImpl.java b/core/java/android/app/ContextImpl.java index 9902f6aa0fe3..794ffcb83078 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -2224,6 +2224,15 @@ class ContextImpl extends Context { } @Override + public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) { + try { + return createPackageContextAsUser(getPackageName(), flags, user); + } catch (NameNotFoundException e) { + throw new IllegalStateException("Own package not found: package=" + getPackageName()); + } + } + + @Override public Context createContextForSplit(String splitName) throws NameNotFoundException { if (!mPackageInfo.getApplicationInfo().requestsIsolatedSplitLoading()) { // All Splits are always loaded. diff --git a/core/java/android/app/IUiModeManager.aidl b/core/java/android/app/IUiModeManager.aidl index f2c9f615c03f..a3e0845af0ce 100644 --- a/core/java/android/app/IUiModeManager.aidl +++ b/core/java/android/app/IUiModeManager.aidl @@ -25,7 +25,7 @@ interface IUiModeManager { * Enables the car mode. Only the system can do this. * @hide */ - void enableCarMode(int flags); + void enableCarMode(int flags, int priority, String callingPackage); /** * Disables the car mode. @@ -34,6 +34,12 @@ interface IUiModeManager { void disableCarMode(int flags); /** + * Disables car mode (the original version is marked unsupported app usage so cannot be changed + * for the time being). + */ + void disableCarModeByCallingPackage(int flags, String callingPackage); + + /** * Return the current running mode. */ int getCurrentModeType(); diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index ceadd8510e44..47f0cf846c17 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -628,6 +628,13 @@ public class Notification implements Parcelable */ public static final int FLAG_BUBBLE = 0x00001000; + /** @hide */ + @IntDef({FLAG_SHOW_LIGHTS, FLAG_ONGOING_EVENT, FLAG_INSISTENT, FLAG_ONLY_ALERT_ONCE, + FLAG_AUTO_CANCEL, FLAG_NO_CLEAR, FLAG_FOREGROUND_SERVICE, FLAG_HIGH_PRIORITY, + FLAG_LOCAL_ONLY, FLAG_GROUP_SUMMARY, FLAG_AUTOGROUP_SUMMARY, FLAG_BUBBLE}) + @Retention(RetentionPolicy.SOURCE) + public @interface NotificationFlags{}; + public int flags; /** @hide */ @@ -4537,10 +4544,15 @@ public class Notification implements Parcelable } /** - * @hide + * Set the value for a notification flag + * + * @param mask Bit mask of the flag + * @param value Status (on/off) of the flag + * + * @return The same Builder. */ @NonNull - public Builder setFlag(int mask, boolean value) { + public Builder setFlag(@NotificationFlags int mask, boolean value) { if (value) { mN.flags |= mask; } else { 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 46a128a2cd01..29cb3c1f131b 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; @@ -611,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, @@ -653,7 +653,7 @@ final class SystemServiceRegistry { new CachedServiceFetcher<UiModeManager>() { @Override public UiModeManager createService(ContextImpl ctx) throws ServiceNotFoundException { - return new UiModeManager(); + return new UiModeManager(ctx.getOuterContext()); }}); registerService(Context.USB_SERVICE, UsbManager.class, diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java index 46316e1a254b..83247875c8a5 100644 --- a/core/java/android/app/UiModeManager.java +++ b/core/java/android/app/UiModeManager.java @@ -17,6 +17,10 @@ package android.app; import android.annotation.IntDef; +import android.annotation.IntRange; +import android.annotation.Nullable; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; @@ -68,6 +72,25 @@ public class UiModeManager { * of the broadcast to {@link Activity#RESULT_CANCELED}. */ public static String ACTION_ENTER_CAR_MODE = "android.app.action.ENTER_CAR_MODE"; + + /** + * Broadcast sent when the device's UI has switched to car mode, either by being placed in a car + * dock or explicit action of the user. + * <p> + * In addition to the behavior for {@link #ACTION_ENTER_CAR_MODE}, this broadcast includes the + * package name of the app which requested to enter car mode in the + * {@link #EXTRA_CALLING_PACKAGE}. If an app requested to enter car mode using + * {@link #enableCarMode(int, int)} and specified a priority this will be specified in the + * {@link #EXTRA_PRIORITY}. + * + * This is primarily intended to be received by other components of the Android OS. + * <p> + * Receiver requires permission: {@link android.Manifest.permission.HANDLE_CAR_MODE_CHANGES} + * @hide + */ + @SystemApi + public static final String ACTION_ENTER_CAR_MODE_PRIORITIZED = + "android.app.action.ENTER_CAR_MODE_PRIORITIZED"; /** * Broadcast sent when the device's UI has switch away from car mode back @@ -75,6 +98,28 @@ public class UiModeManager { * when the user exits car mode. */ public static String ACTION_EXIT_CAR_MODE = "android.app.action.EXIT_CAR_MODE"; + + /** + * Broadcast sent when the device's UI has switched away from car mode back to normal mode. + * Typically used by a car mode app, to dismiss itself when the user exits car mode. + * <p> + * In addition to the behavior for {@link #ACTION_EXIT_CAR_MODE}, this broadcast includes the + * package name of the app which requested to exit car mode in {@link #EXTRA_CALLING_PACKAGE}. + * If an app requested to enter car mode using {@link #enableCarMode(int, int)} and specified a + * priority this will be specified in the {@link #EXTRA_PRIORITY} when exiting car mode. + * <p> + * If {@link #DISABLE_CAR_MODE_ALL_PRIORITIES} is used when disabling car mode (i.e. this is + * initiated by the user via the persistent car mode notification), this broadcast is sent once + * for each priority level for which car mode is being disabled. + * <p> + * This is primarily intended to be received by other components of the Android OS. + * <p> + * Receiver requires permission: {@link android.Manifest.permission.HANDLE_CAR_MODE_CHANGES} + * @hide + */ + @SystemApi + public static final String ACTION_EXIT_CAR_MODE_PRIORITIZED = + "android.app.action.EXIT_CAR_MODE_PRIORITIZED"; /** * Broadcast sent when the device's UI has switched to desk mode, @@ -97,6 +142,24 @@ public class UiModeManager { */ public static String ACTION_EXIT_DESK_MODE = "android.app.action.EXIT_DESK_MODE"; + /** + * String extra used with {@link #ACTION_ENTER_CAR_MODE_PRIORITIZED} and + * {@link #ACTION_EXIT_CAR_MODE_PRIORITIZED} to indicate the package name of the app which + * requested to enter or exit car mode. + * @hide + */ + @SystemApi + public static final String EXTRA_CALLING_PACKAGE = "android.app.extra.CALLING_PACKAGE"; + + /** + * Integer extra used with {@link #ACTION_ENTER_CAR_MODE_PRIORITIZED} and + * {@link #ACTION_EXIT_CAR_MODE_PRIORITIZED} to indicate the priority level at which car mode + * is being disabled. + * @hide + */ + @SystemApi + public static final String EXTRA_PRIORITY = "android.app.extra.PRIORITY"; + /** @hide */ @IntDef(prefix = { "MODE_" }, value = { MODE_NIGHT_AUTO, @@ -126,10 +189,21 @@ public class UiModeManager { private IUiModeManager mService; + /** + * Context required for getting the opPackageName of API caller; maybe be {@code null} if the + * old constructor marked with UnSupportedAppUsage is used. + */ + private @Nullable Context mContext; + @UnsupportedAppUsage /*package*/ UiModeManager() throws ServiceNotFoundException { + this(null /* context */); + } + + /*package*/ UiModeManager(Context context) throws ServiceNotFoundException { mService = IUiModeManager.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.UI_MODE_SERVICE)); + mContext = context; } /** @@ -152,6 +226,14 @@ public class UiModeManager { */ public static final int ENABLE_CAR_MODE_ALLOW_SLEEP = 0x0002; + /** @hide */ + @IntDef(prefix = { "ENABLE_CAR_MODE_" }, value = { + ENABLE_CAR_MODE_GO_CAR_HOME, + ENABLE_CAR_MODE_ALLOW_SLEEP + }) + @Retention(RetentionPolicy.SOURCE) + public @interface EnableCarMode {} + /** * Force device into car mode, like it had been placed in the car dock. * This will cause the device to switch to the car home UI as part of @@ -159,9 +241,54 @@ public class UiModeManager { * @param flags Must be 0. */ public void enableCarMode(int flags) { + enableCarMode(DEFAULT_PRIORITY, flags); + } + + /** + * Force device into car mode, like it had been placed in the car dock. This will cause the + * device to switch to the car home UI as part of the mode switch. + * <p> + * An app may request to enter car mode when the system is already in car mode. The app may + * specify a "priority" when entering car mode. The device will remain in car mode + * (i.e. {@link #getCurrentModeType()} is {@link Configuration#UI_MODE_TYPE_CAR}) as long as + * there is a priority level at which car mode have been enabled. For example assume app A + * enters car mode at priority level 100, and then app B enters car mode at the default priority + * (0). If app A exits car mode, the device will remain in car mode until app B exits car mode. + * <p> + * Specifying a priority level when entering car mode is important in cases where multiple apps + * on a device implement a car-mode {@link android.telecom.InCallService} (see + * {@link android.telecom.TelecomManager#METADATA_IN_CALL_SERVICE_CAR_MODE_UI}). The + * {@link android.telecom.InCallService} associated with the highest priority app which entered + * car mode will be bound to by Telecom and provided with information about ongoing calls on + * the device. + * <p> + * System apps holding the required permission can enable car mode when the app determines the + * correct conditions exist for that app to be in car mode. The device maker should ensure that + * where multiple apps exist on the device which can potentially enter car mode, appropriate + * priorities are used to ensure that calls delivered by the + * {@link android.telecom.InCallService} API are delivered to the highest priority app. + * If app A and app B can both potentially enable car mode, and it is desired that app B is the + * one which should receive call information, the priority for app B should be higher than the + * one for app A. + * <p> + * When an app uses a priority to enable car mode, they can disable car mode at the specified + * priority level using {@link #disableCarMode(int)}. An app may only enable car mode at a + * single priority. + * <p> + * Public apps are assumed to enter/exit car mode at {@link #DEFAULT_PRIORITY}. + * + * @param priority The declared priority for the caller. + * @param flags Car mode flags. + * @hide + */ + @SystemApi + @TestApi + @RequiresPermission(android.Manifest.permission.ENTER_CAR_MODE_PRIORITIZED) + public void enableCarMode(@IntRange(from = 0) int priority, @EnableCarMode int flags) { if (mService != null) { try { - mService.enableCarMode(flags); + mService.enableCarMode(flags, priority, + mContext == null ? null : mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -176,15 +303,44 @@ public class UiModeManager { * being in car mode). */ public static final int DISABLE_CAR_MODE_GO_HOME = 0x0001; + + /** + * Flag for use with {@link #disableCarMode(int)}: Disables car mode at ALL priority levels. + * Primarily intended for use from {@link com.android.internal.app.DisableCarModeActivity} to + * provide the user with a means to exit car mode at all priority levels. + * @hide + */ + public static final int DISABLE_CAR_MODE_ALL_PRIORITIES = 0x0002; + + /** @hide */ + @IntDef(prefix = { "DISABLE_CAR_MODE_" }, value = { + DISABLE_CAR_MODE_GO_HOME + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DisableCarMode {} + + /** + * The default priority used for entering car mode. + * <p> + * Callers of the {@link UiModeManager#enableCarMode(int)} priority will be assigned the + * default priority. + * <p> + * System apps can specify a priority other than the default priority when using + * {@link UiModeManager#enableCarMode(int, int)} to enable car mode. + * @hide + */ + @SystemApi + public static final int DEFAULT_PRIORITY = 0; /** * Turn off special mode if currently in car mode. - * @param flags May be 0 or {@link #DISABLE_CAR_MODE_GO_HOME}. + * @param flags One of the disable car mode flags. */ - public void disableCarMode(int flags) { + public void disableCarMode(@DisableCarMode int flags) { if (mService != null) { try { - mService.disableCarMode(flags); + mService.disableCarModeByCallingPackage(flags, + mContext == null ? null : mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } 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/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/content/Context.java b/core/java/android/content/Context.java index a3b918d095e0..4b22166a9688 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; @@ -2423,10 +2424,10 @@ public abstract class Context { * * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle) */ - public void sendOrderedBroadcast(@RequiresPermission @NonNull Intent intent, - @Nullable String receiverPermission, @Nullable String receiverAppOp, - @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler, - int initialCode, @Nullable String initialData, @Nullable Bundle initialExtras) { + public void sendOrderedBroadcast(@NonNull Intent intent, @Nullable String receiverPermission, + @Nullable String receiverAppOp, @Nullable BroadcastReceiver resultReceiver, + @Nullable Handler scheduler, int initialCode, @Nullable String initialData, + @Nullable Bundle initialExtras) { throw new RuntimeException("Not implemented. Must override in a subclass."); } @@ -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 @@ -5255,8 +5256,9 @@ public abstract class Context { */ @SystemApi @TestApi + @NonNull public Context createPackageContextAsUser( - String packageName, @CreatePackageOptions int flags, UserHandle user) + @NonNull String packageName, @CreatePackageOptions int flags, @NonNull UserHandle user) throws PackageManager.NameNotFoundException { if (Build.IS_ENG) { throw new IllegalStateException("createPackageContextAsUser not overridden!"); @@ -5265,6 +5267,23 @@ public abstract class Context { } /** + * Similar to {@link #createPackageContext(String, int)}, but for the own package with a + * different {@link UserHandle}. For example, {@link #getContentResolver()} + * will open any {@link Uri} as the given user. + * + * @hide + */ + @SystemApi + @TestApi + @NonNull + public Context createContextAsUser(@NonNull UserHandle user, @CreatePackageOptions int flags) { + if (Build.IS_ENG) { + throw new IllegalStateException("createContextAsUser not overridden!"); + } + return this; + } + + /** * Creates a context given an {@link android.content.pm.ApplicationInfo}. * * @hide diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 2b1b8eb183ab..428aadb5c3f6 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -898,6 +898,12 @@ public class ContextWrapper extends Context { /** @hide */ @Override + public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) { + return mBase.createContextAsUser(user, flags); + } + + /** @hide */ + @Override @UnsupportedAppUsage public Context createApplicationContext(ApplicationInfo application, int flags) throws PackageManager.NameNotFoundException { 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..30a3bd4d0738 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 {} @@ -413,6 +415,17 @@ public abstract class PackageManagerInternal { @ResolveInfoFlags int flags, int filterCallingUid, int userId); /** + * Retrieve all activities that can be performed for the given intent. + * @param filterCallingUid The results will be filtered in the context of this UID instead + * of the calling UID. + * @see PackageManager#queryIntentActivities(Intent, int) + */ + public abstract List<ResolveInfo> queryIntentActivities( + Intent intent, @Nullable String resolvedType, @ResolveInfoFlags int flags, + int filterCallingUid, int userId); + + + /** * Retrieve all services that can be performed for the given intent. * @see PackageManager#queryIntentServices(Intent, int) */ @@ -715,10 +728,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/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 75af41cb2b54..56bacf29ac73 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -52,13 +52,12 @@ import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.provider.Settings; import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; import android.util.ArrayMap; import android.util.Log; import android.util.SparseIntArray; import com.android.internal.annotations.GuardedBy; -import com.android.internal.telephony.ITelephony; -import com.android.internal.telephony.PhoneConstants; import com.android.internal.util.Preconditions; import com.android.internal.util.Protocol; @@ -711,6 +710,12 @@ public class ConnectivityManager { @Deprecated public static final int TYPE_TEST = 18; // TODO: Remove this once NetworkTypes are unused. + // Deprecated constants for return values of startUsingNetworkFeature. They used to live + // in com.android.internal.telephony.PhoneConstants until they were made inaccessible. + private static final int DEPRECATED_PHONE_CONSTANT_APN_ALREADY_ACTIVE = 0; + private static final int DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED = 1; + private static final int DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED = 3; + /** {@hide} */ public static final int MAX_RADIO_TYPE = TYPE_TEST; @@ -1407,7 +1412,7 @@ public class ConnectivityManager { if (netCap == null) { Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " + feature); - return PhoneConstants.APN_REQUEST_FAILED; + return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED; } NetworkRequest request = null; @@ -1417,9 +1422,9 @@ public class ConnectivityManager { Log.d(TAG, "renewing startUsingNetworkFeature request " + l.networkRequest); renewRequestLocked(l); if (l.currentNetwork != null) { - return PhoneConstants.APN_ALREADY_ACTIVE; + return DEPRECATED_PHONE_CONSTANT_APN_ALREADY_ACTIVE; } else { - return PhoneConstants.APN_REQUEST_STARTED; + return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED; } } @@ -1427,10 +1432,10 @@ public class ConnectivityManager { } if (request != null) { Log.d(TAG, "starting startUsingNetworkFeature for request " + request); - return PhoneConstants.APN_REQUEST_STARTED; + return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_STARTED; } else { Log.d(TAG, " request Failed"); - return PhoneConstants.APN_REQUEST_FAILED; + return DEPRECATED_PHONE_CONSTANT_APN_REQUEST_FAILED; } } @@ -2149,19 +2154,14 @@ public class ConnectivityManager { @Deprecated @UnsupportedAppUsage public boolean getMobileDataEnabled() { - IBinder b = ServiceManager.getService(Context.TELEPHONY_SERVICE); - if (b != null) { - try { - ITelephony it = ITelephony.Stub.asInterface(b); - int subId = SubscriptionManager.getDefaultDataSubscriptionId(); - Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId); - boolean retVal = it.isUserDataEnabled(subId); - Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId - + " retVal=" + retVal); - return retVal; - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + TelephonyManager tm = mContext.getSystemService(TelephonyManager.class); + if (tm != null) { + int subId = SubscriptionManager.getDefaultDataSubscriptionId(); + Log.d("ConnectivityManager", "getMobileDataEnabled()+ subId=" + subId); + boolean retVal = tm.createForSubscriptionId(subId).isDataEnabled(); + Log.d("ConnectivityManager", "getMobileDataEnabled()- subId=" + subId + + " retVal=" + retVal); + return retVal; } Log.d("ConnectivityManager", "getMobileDataEnabled()- remote exception retVal=false"); return false; diff --git a/core/java/android/net/NetworkKey.java b/core/java/android/net/NetworkKey.java index a101da7b4b9c..04cb877305b9 100644 --- a/core/java/android/net/NetworkKey.java +++ b/core/java/android/net/NetworkKey.java @@ -21,7 +21,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.wifi.ScanResult; import android.net.wifi.WifiInfo; -import android.net.wifi.WifiSsid; +import android.net.wifi.WifiManager; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -69,22 +69,25 @@ public class NetworkKey implements Parcelable { */ @Nullable public static NetworkKey createFromScanResult(@Nullable ScanResult result) { - if (result != null && result.wifiSsid != null) { - final String ssid = result.wifiSsid.toString(); - final String bssid = result.BSSID; - if (!TextUtils.isEmpty(ssid) && !ssid.equals(WifiSsid.NONE) - && !TextUtils.isEmpty(bssid)) { - WifiKey wifiKey; - try { - wifiKey = new WifiKey(String.format("\"%s\"", ssid), bssid); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Unable to create WifiKey.", e); - return null; - } - return new NetworkKey(wifiKey); - } + if (result == null) { + return null; + } + final String ssid = result.SSID; + if (TextUtils.isEmpty(ssid) || ssid.equals(WifiManager.UNKNOWN_SSID)) { + return null; + } + final String bssid = result.BSSID; + if (TextUtils.isEmpty(bssid)) { + return null; + } + + try { + final WifiKey wifiKey = new WifiKey(String.format("\"%s\"", ssid), bssid); + return new NetworkKey(wifiKey); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Unable to create WifiKey.", e); + return null; } - return null; } /** @@ -100,7 +103,7 @@ public class NetworkKey implements Parcelable { if (wifiInfo != null) { final String ssid = wifiInfo.getSSID(); final String bssid = wifiInfo.getBSSID(); - if (!TextUtils.isEmpty(ssid) && !ssid.equals(WifiSsid.NONE) + if (!TextUtils.isEmpty(ssid) && !ssid.equals(WifiManager.UNKNOWN_SSID) && !TextUtils.isEmpty(bssid)) { WifiKey wifiKey; try { 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/Handler.java b/core/java/android/os/Handler.java index 9af9edae9a3f..a99bdabee137 100644 --- a/core/java/android/os/Handler.java +++ b/core/java/android/os/Handler.java @@ -28,15 +28,14 @@ import java.lang.reflect.Modifier; * A Handler allows you to send and process {@link Message} and Runnable * objects associated with a thread's {@link MessageQueue}. Each Handler * instance is associated with a single thread and that thread's message - * queue. When you create a new Handler, it is bound to the thread / - * message queue of the thread that is creating it -- from that point on, - * it will deliver messages and runnables to that message queue and execute - * them as they come out of the message queue. - * + * queue. When you create a new Handler it is bound to a {@link Looper}. + * It will deliver messages and runnables to that Looper's message + * queue and execute them on that Looper's thread. + * * <p>There are two main uses for a Handler: (1) to schedule messages and * runnables to be executed at some point in the future; and (2) to enqueue * an action to be performed on a different thread than your own. - * + * * <p>Scheduling messages is accomplished with the * {@link #post}, {@link #postAtTime(Runnable, long)}, * {@link #postDelayed}, {@link #sendEmptyMessage}, @@ -114,7 +113,18 @@ public class Handler { * * If this thread does not have a looper, this handler won't be able to receive messages * so an exception is thrown. + * + * @deprecated Implicitly choosing a Looper during Handler construction can lead to bugs + * where operations are silently lost (if the Handler is not expecting new tasks and quits), + * crashes (if a handler is sometimes created on a thread without a Looper active), or race + * conditions, where the thread a handler is associated with is not what the author + * anticipated. Instead, use an {@link java.util.concurrent.Executor} or specify the Looper + * explicitly, using {@link Looper#getMainLooper}, {link android.view.View#getHandler}, or + * similar. If the implicit thread local behavior is required for compatibility, use + * {@code new Handler(Looper.myLooper())} to make it clear to readers. + * */ + @Deprecated public Handler() { this(null, false); } @@ -128,7 +138,17 @@ public class Handler { * so an exception is thrown. * * @param callback The callback interface in which to handle messages, or null. - */ + * + * @deprecated Implicitly choosing a Looper during Handler construction can lead to bugs + * where operations are silently lost (if the Handler is not expecting new tasks and quits), + * crashes (if a handler is sometimes created on a thread without a Looper active), or race + * conditions, where the thread a handler is associated with is not what the author + * anticipated. Instead, use an {@link java.util.concurrent.Executor} or specify the Looper + * explicitly, using {@link Looper#getMainLooper}, {link android.view.View#getHandler}, or + * similar. If the implicit thread local behavior is required for compatibility, use + * {@code new Handler(Looper.myLooper(), callback)} to make it clear to readers. + */ + @Deprecated public Handler(@Nullable Callback callback) { this(callback, false); } diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java index 8b0ffe155fc3..f08e1ff16999 100644 --- a/core/java/android/os/SystemProperties.java +++ b/core/java/android/os/SystemProperties.java @@ -26,6 +26,9 @@ import android.util.MutableInt; import com.android.internal.annotations.GuardedBy; +import dalvik.annotation.optimization.CriticalNative; +import dalvik.annotation.optimization.FastNative; + import libcore.util.HexEncoding; import java.nio.charset.StandardCharsets; @@ -93,18 +96,43 @@ public class SystemProperties { } } + // The one-argument version of native_get used to be a regular native function. Nowadays, + // we use the two-argument form of native_get all the time, but we can't just delete the + // one-argument overload: apps use it via reflection, as the UnsupportedAppUsage annotation + // indicates. Let's just live with having a Java function with a very unusual name. @UnsupportedAppUsage - private static native String native_get(String key); + private static String native_get(String key) { + return native_get(key, ""); + } + + @FastNative @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private static native String native_get(String key, String def); + @FastNative @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private static native int native_get_int(String key, int def); + @FastNative @UnsupportedAppUsage private static native long native_get_long(String key, long def); + @FastNative @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private static native boolean native_get_boolean(String key, boolean def); + + @FastNative + private static native long native_find(String name); + @FastNative + private static native String native_get(long handle); + @CriticalNative + private static native int native_get_int(long handle, int def); + @CriticalNative + private static native long native_get_long(long handle, long def); + @CriticalNative + private static native boolean native_get_boolean(long handle, boolean def); + + // _NOT_ FastNative: native_set performs IPC and can block @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private static native void native_set(String key, String def); + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private static native void native_add_change_callback(); private static native void native_report_sysprop_change(); @@ -229,25 +257,27 @@ public class SystemProperties { @SuppressWarnings("unused") // Called from native code. private static void callChangeCallbacks() { + ArrayList<Runnable> callbacks = null; synchronized (sChangeCallbacks) { //Log.i("foo", "Calling " + sChangeCallbacks.size() + " change callbacks!"); if (sChangeCallbacks.size() == 0) { return; } - ArrayList<Runnable> callbacks = new ArrayList<Runnable>(sChangeCallbacks); - final long token = Binder.clearCallingIdentity(); - try { - for (int i = 0; i < callbacks.size(); i++) { - try { - callbacks.get(i).run(); - } catch (Throwable t) { - Log.wtf(TAG, "Exception in SystemProperties change callback", t); - // Ignore and try to go on. - } + callbacks = new ArrayList<Runnable>(sChangeCallbacks); + } + final long token = Binder.clearCallingIdentity(); + try { + for (int i = 0; i < callbacks.size(); i++) { + try { + callbacks.get(i).run(); + } catch (Throwable t) { + // Ignore and try to go on. Don't use wtf here: that + // will cause the process to exit on some builds and break tests. + Log.e(TAG, "Exception in SystemProperties change callback", t); } - } finally { - Binder.restoreCallingIdentity(token); } + } finally { + Binder.restoreCallingIdentity(token); } } @@ -284,4 +314,60 @@ public class SystemProperties { @UnsupportedAppUsage private SystemProperties() { } + + /** + * Look up a property location by name. + * @name name of the property + * @return property handle or {@code null} if property isn't set + * @hide + */ + @Nullable public static Handle find(@NonNull String name) { + long nativeHandle = native_find(name); + if (nativeHandle == 0) { + return null; + } + return new Handle(nativeHandle); + } + + /** + * Handle to a pre-located property. Looking up a property handle in advance allows + * for optimal repeated lookup of a single property. + * @hide + */ + public static final class Handle { + + private final long mNativeHandle; + + /** + * @return Value of the property + */ + @NonNull public String get() { + return native_get(mNativeHandle); + } + /** + * @param def default value + * @return value or {@code def} on parse error + */ + public int getInt(int def) { + return native_get_int(mNativeHandle, def); + } + /** + * @param def default value + * @return value or {@code def} on parse error + */ + public long getLong(long def) { + return native_get_long(mNativeHandle, def); + } + /** + * @param def default value + * @return value or {@code def} on parse error + */ + public boolean getBoolean(boolean def) { + return native_get_boolean(mNativeHandle, def); + } + + private Handle(long nativeHandle) { + mNativeHandle = nativeHandle; + } + } } diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java index 82a3c4015f70..391f3a2fd135 100644 --- a/core/java/android/provider/CallLog.java +++ b/core/java/android/provider/CallLog.java @@ -43,8 +43,6 @@ import android.telephony.PhoneNumberUtils; import android.text.TextUtils; import android.util.Log; -import com.android.internal.telephony.PhoneConstants; - import java.util.List; /** @@ -610,7 +608,7 @@ public class CallLog { * if the contact is unknown. * @param context the context used to get the ContentResolver * @param number the phone number to be added to the calls db - * @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which + * @param presentation enum value from TelecomManager.PRESENTATION_xxx, which * is set by the network and denotes the number presenting rules for * "allowed", "payphone", "restricted" or "unknown" * @param callType enumerated values for "incoming", "outgoing", or "missed" @@ -645,7 +643,7 @@ public class CallLog { * @param number the phone number to be added to the calls db * @param viaNumber the secondary number that the incoming call received with. If the * call was received with the SIM assigned number, then this field must be ''. - * @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which + * @param presentation enum value from TelecomManager.PRESENTATION_xxx, which * is set by the network and denotes the number presenting rules for * "allowed", "payphone", "restricted" or "unknown" * @param callType enumerated values for "incoming", "outgoing", or "missed" @@ -686,7 +684,7 @@ public class CallLog { * if it was outgoing. Otherwise it is ''. * @param viaNumber the secondary number that the incoming call received with. If the * call was received with the SIM assigned number, then this field must be ''. - * @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which + * @param presentation enum value from TelecomManager.PRESENTATION_xxx, which * is set by the network and denotes the number presenting rules for * "allowed", "payphone", "restricted" or "unknown" * @param callType enumerated values for "incoming", "outgoing", or "missed" @@ -1048,22 +1046,22 @@ public class CallLog { /** * Remap network specified number presentation types - * PhoneConstants.PRESENTATION_xxx to calllog number presentation types + * TelecomManager.PRESENTATION_xxx to calllog number presentation types * Calls.PRESENTATION_xxx, in order to insulate the persistent calllog * from any future radio changes. * If the number field is empty set the presentation type to Unknown. */ private static int getLogNumberPresentation(String number, int presentation) { - if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) { + if (presentation == TelecomManager.PRESENTATION_RESTRICTED) { return presentation; } - if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) { + if (presentation == TelecomManager.PRESENTATION_PAYPHONE) { return presentation; } if (TextUtils.isEmpty(number) - || presentation == PhoneConstants.PRESENTATION_UNKNOWN) { + || presentation == TelecomManager.PRESENTATION_UNKNOWN) { return PRESENTATION_UNKNOWN; } 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/telephony/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index e5bfb4dfb7b4..a65c8fdf50c9 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; @@ -184,7 +184,8 @@ public class PhoneStateListener { public static final int LISTEN_CELL_INFO = 0x00000400; /** - * Listen for {@link PreciseCallState.State} of ringing, background and foreground calls. + * Listen for {@link android.telephony.Annotation.PreciseCallStates} of ringing, + * background and foreground calls. * * @hide */ diff --git a/telephony/java/android/telephony/Rlog.java b/core/java/android/telephony/Rlog.java index cdab2dc54dd2..cdab2dc54dd2 100644 --- a/telephony/java/android/telephony/Rlog.java +++ b/core/java/android/telephony/Rlog.java diff --git a/core/java/android/os/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index b67409988da0..5c427309e823 100644 --- a/core/java/android/os/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -13,21 +13,29 @@ * 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; import android.telephony.Annotation.ApnType; import android.telephony.Annotation.CallState; import android.telephony.Annotation.DataActivityType; import android.telephony.Annotation.DataFailureCause; import android.telephony.Annotation.DataState; import android.telephony.Annotation.NetworkType; +import android.telephony.Annotation.PreciseCallStates; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SimActivationState; import android.telephony.Annotation.SrvccState; @@ -35,14 +43,20 @@ import android.telephony.CallQuality; import android.telephony.CellInfo; import android.telephony.DisconnectCause; import android.telephony.PhoneCapability; -import android.telephony.PreciseCallState.State; import android.telephony.ServiceState; 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 +73,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 +100,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 +236,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 } @@ -466,8 +623,10 @@ public class TelephonyRegistryManager { * * @hide */ - public void notifyPreciseCallState(int subId, int slotIndex, @State int ringCallPreciseState, - @State int foregroundCallPreciseState, @State int backgroundCallPreciseState) { + public void notifyPreciseCallState(int subId, int slotIndex, + @PreciseCallStates int ringCallPreciseState, + @PreciseCallStates int foregroundCallPreciseState, + @PreciseCallStates int backgroundCallPreciseState) { try { sRegistry.notifyPreciseCallState(slotIndex, subId, ringCallPreciseState, foregroundCallPreciseState, backgroundCallPreciseState); @@ -545,4 +704,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/DisableCarModeActivity.java b/core/java/com/android/internal/app/DisableCarModeActivity.java index 7943c613b357..d44312b716ba 100644 --- a/core/java/com/android/internal/app/DisableCarModeActivity.java +++ b/core/java/com/android/internal/app/DisableCarModeActivity.java @@ -33,7 +33,9 @@ public class DisableCarModeActivity extends Activity { try { IUiModeManager uiModeManager = IUiModeManager.Stub.asInterface( ServiceManager.getService("uimode")); - uiModeManager.disableCarMode(UiModeManager.DISABLE_CAR_MODE_GO_HOME); + uiModeManager.disableCarModeByCallingPackage(UiModeManager.DISABLE_CAR_MODE_GO_HOME + | UiModeManager.DISABLE_CAR_MODE_ALL_PRIORITIES, + getOpPackageName()); } catch (RemoteException e) { Log.e(TAG, "Failed to disable car mode", e); } diff --git a/core/java/com/android/internal/app/LocaleHelper.java b/core/java/com/android/internal/app/LocaleHelper.java index aef4dbf41d35..e3d07aaa8fe8 100644 --- a/core/java/com/android/internal/app/LocaleHelper.java +++ b/core/java/com/android/internal/app/LocaleHelper.java @@ -208,7 +208,7 @@ public class LocaleHelper { * @return the maximized Locale instance. */ public static Locale addLikelySubtags(Locale locale) { - return libcore.icu.ICU.addLikelySubtags(locale); + return ULocale.addLikelySubtags(ULocale.forLocale(locale)).toLocale(); } /** 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/android_os_SystemProperties.cpp b/core/jni/android_os_SystemProperties.cpp index 87f498a710c1..7f8bec6ce507 100644 --- a/core/jni/android_os_SystemProperties.cpp +++ b/core/jni/android_os_SystemProperties.cpp @@ -17,9 +17,13 @@ #define LOG_TAG "SysPropJNI" +#include <utility> +#include <optional> + #include "android-base/logging.h" +#include "android-base/parsebool.h" +#include "android-base/parseint.h" #include "android-base/properties.h" -#include "cutils/properties.h" #include "utils/misc.h" #include <utils/Log.h> #include "jni.h" @@ -28,86 +32,171 @@ #include <nativehelper/ScopedPrimitiveArray.h> #include <nativehelper/ScopedUtfChars.h> -namespace android -{ +#if defined(__BIONIC__) +# include <sys/system_properties.h> +#else +struct prop_info; +#endif +namespace android { namespace { -template <typename T, typename Handler> -T ConvertKeyAndForward(JNIEnv *env, jstring keyJ, T defJ, Handler handler) { - std::string key; - { - // Scope the String access. If the handler can throw an exception, - // releasing the string characters late would trigger an abort. - ScopedUtfChars key_utf(env, keyJ); - if (key_utf.c_str() == nullptr) { - return defJ; - } - key = key_utf.c_str(); // This will make a copy, but we can't avoid - // with the existing interface in - // android::base. - } - return handler(key, defJ); -} +using android::base::ParseBoolResult; -jstring SystemProperties_getSS(JNIEnv *env, jclass clazz, jstring keyJ, - jstring defJ) +template<typename Functor> +void ReadProperty(const prop_info* prop, Functor&& functor) { - // Using ConvertKeyAndForward is sub-optimal for copying the key string, - // but improves reuse and reasoning over code. - auto handler = [&](const std::string& key, jstring defJ) { - std::string prop_val = android::base::GetProperty(key, ""); - if (!prop_val.empty()) { - return env->NewStringUTF(prop_val.c_str()); - }; - if (defJ != nullptr) { - return defJ; - } - // This function is specified to never return null (or have an - // exception pending). - return env->NewStringUTF(""); +#if defined(__BIONIC__) + auto thunk = [](void* cookie, + const char* /*name*/, + const char* value, + uint32_t /*serial*/) { + std::forward<Functor>(*static_cast<Functor*>(cookie))(value); }; - return ConvertKeyAndForward(env, keyJ, defJ, handler); + __system_property_read_callback(prop, thunk, &functor); +#else + LOG(FATAL) << "fast property access supported only on device"; +#endif } -jstring SystemProperties_getS(JNIEnv *env, jclass clazz, jstring keyJ) +template<typename Functor> +void ReadProperty(JNIEnv* env, jstring keyJ, Functor&& functor) { - return SystemProperties_getSS(env, clazz, keyJ, nullptr); + ScopedUtfChars key(env, keyJ); + if (!key.c_str()) { + return; + } +#if defined(__BIONIC__) + const prop_info* prop = __system_property_find(key.c_str()); + if (!prop) { + return; + } + ReadProperty(prop, std::forward<Functor>(functor)); +#else + std::forward<Functor>(functor)( + android::base::GetProperty(key.c_str(), "").c_str()); +#endif +} + +jstring SystemProperties_getSS(JNIEnv* env, jclass clazz, jstring keyJ, + jstring defJ) +{ + jstring ret = defJ; + ReadProperty(env, keyJ, [&](const char* value) { + if (value[0]) { + ret = env->NewStringUTF(value); + } + }); + if (ret == nullptr && !env->ExceptionCheck()) { + ret = env->NewStringUTF(""); // Legacy behavior + } + return ret; } template <typename T> T SystemProperties_get_integral(JNIEnv *env, jclass, jstring keyJ, T defJ) { - auto handler = [](const std::string& key, T defV) { - return android::base::GetIntProperty<T>(key, defV); - }; - return ConvertKeyAndForward(env, keyJ, defJ, handler); + T ret = defJ; + ReadProperty(env, keyJ, [&](const char* value) { + android::base::ParseInt<T>(value, &ret); + }); + return ret; +} + +static jboolean jbooleanFromParseBoolResult(ParseBoolResult parseResult, jboolean defJ) { + jboolean ret; + switch (parseResult) { + case ParseBoolResult::kError: + ret = defJ; + break; + case ParseBoolResult::kFalse: + ret = JNI_FALSE; + break; + case ParseBoolResult::kTrue: + ret = JNI_TRUE; + break; + } + return ret; } jboolean SystemProperties_get_boolean(JNIEnv *env, jclass, jstring keyJ, jboolean defJ) { - auto handler = [](const std::string& key, jboolean defV) -> jboolean { - bool result = android::base::GetBoolProperty(key, defV); - return result ? JNI_TRUE : JNI_FALSE; - }; - return ConvertKeyAndForward(env, keyJ, defJ, handler); + ParseBoolResult parseResult; + ReadProperty(env, keyJ, [&](const char* value) { + parseResult = android::base::ParseBool(value); + }); + return jbooleanFromParseBoolResult(parseResult, defJ); +} + +jlong SystemProperties_find(JNIEnv* env, jclass, jstring keyJ) +{ +#if defined(__BIONIC__) + ScopedUtfChars key(env, keyJ); + if (!key.c_str()) { + return 0; + } + const prop_info* prop = __system_property_find(key.c_str()); + return reinterpret_cast<jlong>(prop); +#else + LOG(FATAL) << "fast property access supported only on device"; + __builtin_unreachable(); // Silence warning +#endif +} + +jstring SystemProperties_getH(JNIEnv* env, jclass clazz, jlong propJ) +{ + jstring ret; + auto prop = reinterpret_cast<const prop_info*>(propJ); + ReadProperty(prop, [&](const char* value) { + ret = env->NewStringUTF(value); + }); + return ret; +} + +template <typename T> +T SystemProperties_get_integralH(CRITICAL_JNI_PARAMS_COMMA jlong propJ, T defJ) +{ + T ret = defJ; + auto prop = reinterpret_cast<const prop_info*>(propJ); + ReadProperty(prop, [&](const char* value) { + android::base::ParseInt<T>(value, &ret); + }); + return ret; +} + +jboolean SystemProperties_get_booleanH(CRITICAL_JNI_PARAMS_COMMA jlong propJ, jboolean defJ) +{ + ParseBoolResult parseResult; + auto prop = reinterpret_cast<const prop_info*>(propJ); + ReadProperty(prop, [&](const char* value) { + parseResult = android::base::ParseBool(value); + }); + return jbooleanFromParseBoolResult(parseResult, defJ); } void SystemProperties_set(JNIEnv *env, jobject clazz, jstring keyJ, jstring valJ) { - auto handler = [&](const std::string& key, bool) { - std::string val; - if (valJ != nullptr) { - ScopedUtfChars key_utf(env, valJ); - val = key_utf.c_str(); + ScopedUtfChars key(env, keyJ); + if (!key.c_str()) { + return; + } + std::optional<ScopedUtfChars> value; + if (valJ != nullptr) { + value.emplace(env, valJ); + if (!value->c_str()) { + return; } - return android::base::SetProperty(key, val); - }; - if (!ConvertKeyAndForward(env, keyJ, true, handler)) { - // Must have been a failure in SetProperty. + } + bool success; +#if defined(__BIONIC__) + success = !__system_property_set(key.c_str(), value ? value->c_str() : ""); +#else + success = android::base::SetProperty(key.c_str(), value ? value->c_str() : ""); +#endif + if (!success) { jniThrowException(env, "java/lang/RuntimeException", "failed to set system property (check logcat for reason)"); } @@ -157,8 +246,6 @@ void SystemProperties_report_sysprop_change(JNIEnv /**env*/, jobject /*clazz*/) int register_android_os_SystemProperties(JNIEnv *env) { const JNINativeMethod method_table[] = { - { "native_get", "(Ljava/lang/String;)Ljava/lang/String;", - (void*) SystemProperties_getS }, { "native_get", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", (void*) SystemProperties_getSS }, @@ -168,6 +255,18 @@ int register_android_os_SystemProperties(JNIEnv *env) (void*) SystemProperties_get_integral<jlong> }, { "native_get_boolean", "(Ljava/lang/String;Z)Z", (void*) SystemProperties_get_boolean }, + { "native_find", + "(Ljava/lang/String;)J", + (void*) SystemProperties_find }, + { "native_get", + "(J)Ljava/lang/String;", + (void*) SystemProperties_getH }, + { "native_get_int", "(JI)I", + (void*) SystemProperties_get_integralH<jint> }, + { "native_get_long", "(JJ)J", + (void*) SystemProperties_get_integralH<jlong> }, + { "native_get_boolean", "(JZ)Z", + (void*) SystemProperties_get_booleanH }, { "native_set", "(Ljava/lang/String;Ljava/lang/String;)V", (void*) SystemProperties_set }, { "native_add_change_callback", "()V", @@ -179,4 +278,4 @@ int register_android_os_SystemProperties(JNIEnv *env) method_table, NELEM(method_table)); } -}; +} // namespace android 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 b8c6cf64f9db..216b87f89b90 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -108,6 +108,8 @@ <protected-broadcast android:name="android.app.action.ENTER_CAR_MODE" /> <protected-broadcast android:name="android.app.action.EXIT_CAR_MODE" /> + <protected-broadcast android:name="android.app.action.ENTER_CAR_MODE_PRIVILEGED" /> + <protected-broadcast android:name="android.app.action.EXIT_CAR_MODE_PRIVILEGED" /> <protected-broadcast android:name="android.app.action.ENTER_DESK_MODE" /> <protected-broadcast android:name="android.app.action.EXIT_DESK_MODE" /> <protected-broadcast android:name="android.app.action.NEXT_ALARM_CLOCK_CHANGED" /> @@ -1626,7 +1628,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 +2148,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 +2174,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 +2958,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 +3738,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 +3773,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. @@ -4339,6 +4341,21 @@ it will be ignored. @hide --> <permission android:name="android.permission.MODIFY_DAY_NIGHT_MODE" + android:protectionLevel="signature|privileged" /> + + <!-- @SystemApi Allows entering or exiting car mode using a specified priority. + This permission is required to use UiModeManager while specifying a priority for the calling + app. A device manufacturer uses this permission to prioritize the apps which can + potentially request to enter car-mode on a device to help establish the correct behavior + where multiple such apps are active at the same time. + @hide --> + <permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED" + android:protectionLevel="signature|privileged" /> + + <!-- @SystemApi Required to receive ACTION_ENTER_CAR_MODE_PRIVILEGED or + ACTION_EXIT_CAR_MODE_PRIVILEGED. + @hide --> + <permission android:name="android.permission.HANDLE_CAR_MODE_CHANGES" android:protectionLevel="signature|privileged" /> <!-- The system process is explicitly the only one allowed to launch the @@ -4392,13 +4409,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..4b4baa9c1584 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -529,7 +529,7 @@ - TYPE_ETHERNET (9) is prepended to this list, and - - the return value of TelephonyManager.isTetherApnRequired() + - the return value of TelephonyManager.isTetheringApnRequired() determines how the array is further modified: * TRUE (DUN REQUIRED). @@ -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/core/tests/coretests/src/android/net/NetworkKeyTest.java b/core/tests/coretests/src/android/net/NetworkKeyTest.java index 0f1c71d7c601..c6c0b46d0505 100644 --- a/core/tests/coretests/src/android/net/NetworkKeyTest.java +++ b/core/tests/coretests/src/android/net/NetworkKeyTest.java @@ -22,7 +22,7 @@ import static org.mockito.Mockito.when; import android.net.wifi.ScanResult; import android.net.wifi.WifiInfo; -import android.net.wifi.WifiSsid; +import android.net.wifi.WifiManager; import androidx.test.runner.AndroidJUnit4; @@ -65,7 +65,7 @@ public class NetworkKeyTest { @Test public void createFromWifi_noneSsid() throws Exception { - when(mWifiInfo.getSSID()).thenReturn(WifiSsid.NONE); + when(mWifiInfo.getSSID()).thenReturn(WifiManager.UNKNOWN_SSID); when(mWifiInfo.getBSSID()).thenReturn(VALID_BSSID); assertNull(NetworkKey.createFromWifiInfo(mWifiInfo)); } @@ -106,7 +106,7 @@ public class NetworkKeyTest { } @Test - public void createFromScanResult_nullWifiSsid() { + public void createFromScanResult_nullSsid() { ScanResult scanResult = new ScanResult(); scanResult.BSSID = VALID_BSSID; @@ -114,18 +114,18 @@ public class NetworkKeyTest { } @Test - public void createFromScanResult_emptyWifiSsid() { + public void createFromScanResult_emptySsid() { ScanResult scanResult = new ScanResult(); - scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(""); + scanResult.SSID = ""; scanResult.BSSID = VALID_BSSID; assertNull(NetworkKey.createFromScanResult(scanResult)); } @Test - public void createFromScanResult_noneWifiSsid() { + public void createFromScanResult_noneSsid() { ScanResult scanResult = new ScanResult(); - scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(WifiSsid.NONE); + scanResult.SSID = WifiManager.UNKNOWN_SSID; scanResult.BSSID = VALID_BSSID; assertNull(NetworkKey.createFromScanResult(scanResult)); @@ -134,7 +134,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_nullBssid() { ScanResult scanResult = new ScanResult(); - scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(VALID_UNQUOTED_SSID); + scanResult.SSID = VALID_UNQUOTED_SSID; assertNull(NetworkKey.createFromScanResult(scanResult)); } @@ -142,7 +142,7 @@ public class NetworkKeyTest { @Test public void createFromScanResult_emptyBssid() { ScanResult scanResult = new ScanResult(); - scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(VALID_UNQUOTED_SSID); + scanResult.SSID = VALID_UNQUOTED_SSID; scanResult.BSSID = ""; assertNull(NetworkKey.createFromScanResult(scanResult)); @@ -151,16 +151,16 @@ public class NetworkKeyTest { @Test public void createFromScanResult_invalidBssid() { ScanResult scanResult = new ScanResult(); - scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(VALID_UNQUOTED_SSID); + scanResult.SSID = VALID_UNQUOTED_SSID; scanResult.BSSID = INVALID_BSSID; assertNull(NetworkKey.createFromScanResult(scanResult)); } @Test - public void createFromScanResult_validWifiSsid() { + public void createFromScanResult_validSsid() { ScanResult scanResult = new ScanResult(); - scanResult.wifiSsid = WifiSsid.createFromAsciiEncoded(VALID_UNQUOTED_SSID); + scanResult.SSID = VALID_UNQUOTED_SSID; scanResult.BSSID = VALID_BSSID; NetworkKey expected = new NetworkKey(new WifiKey(VALID_SSID, VALID_BSSID)); diff --git a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java index 928351e7de8c..b48ac3347093 100644 --- a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java +++ b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java @@ -93,6 +93,27 @@ public class SystemPropertiesTest extends TestCase { } @SmallTest + private static void testHandle() throws Exception { + String value; + SystemProperties.Handle handle = SystemProperties.find("doesnotexist_2341431"); + assertNull(handle); + SystemProperties.set(KEY, "abc"); + handle = SystemProperties.find(KEY); + assertNotNull(handle); + value = handle.get(); + assertEquals("abc", value); + SystemProperties.set(KEY, "blarg"); + value = handle.get(); + assertEquals("blarg", value); + SystemProperties.set(KEY, "1"); + assertEquals(1, handle.getInt(-1)); + assertEquals(1, handle.getLong(-1)); + assertEquals(true, handle.getBoolean(false)); + SystemProperties.set(KEY, ""); + assertEquals(12345, handle.getInt(12345)); + } + + @SmallTest public void testIntegralProperties() throws Exception { testInt("", 123, 123); testInt("", 0, 0); diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 80f3cc68221f..9064abf6ba36 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -238,6 +238,7 @@ applications that come with the platform <permission name="android.permission.BIND_CONNECTION_SERVICE"/> <permission name="android.permission.BIND_INCALL_SERVICE"/> <permission name="android.permission.CALL_PRIVILEGED"/> + <permission name="android.permission.HANDLE_CAR_MODE_CHANGES"/> <permission name="android.permission.INTERACT_ACROSS_USERS"/> <permission name="android.permission.MANAGE_USERS"/> <permission name="android.permission.MANAGE_ROLE_HOLDERS"/> @@ -328,6 +329,8 @@ applications that come with the platform <permission name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" /> <!-- Permission required to test ExplicitHealthCheckServiceImpl. --> <permission name="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"/> + <!-- Permission required for UiModeManager cts test. --> + <permission name="android.permission.ENTER_CAR_MODE_PRIORITIZED"/> </privapp-permissions> <privapp-permissions package="com.android.statementservice"> diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index 646aa13664c4..c0a04220cfe7 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -348,16 +348,6 @@ public class KeyStore { return list(prefix, UID_SELF); } - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - public boolean reset() { - try { - return mBinder.reset() == NO_ERROR; - } catch (RemoteException e) { - Log.w(TAG, "Cannot connect to keystore", e); - return false; - } - } - /** * Attempt to lock the keystore for {@code user}. * @@ -922,15 +912,26 @@ public class KeyStore { } } - public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] signature, - byte[] entropy) { + /** + * Android KeyStore finish operation. + * + * @param token Authentication token. + * @param arguments Keymaster arguments + * @param input Optional additional input data. + * @param signature Optional signature to be verified. + * @param entropy Optional additional entropy + * @return OperationResult that will indicate success or error of the operation. + */ + public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] input, + byte[] signature, byte[] entropy) { OperationPromise promise = new OperationPromise(); try { mBinder.asBinder().linkToDeath(promise, 0); arguments = arguments != null ? arguments : new KeymasterArguments(); entropy = entropy != null ? entropy : new byte[0]; + input = input != null ? input : new byte[0]; signature = signature != null ? signature : new byte[0]; - int errorCode = mBinder.finish(promise, token, arguments, signature, entropy); + int errorCode = mBinder.finish(promise, token, arguments, input, signature, entropy); if (errorCode == NO_ERROR) { return promise.getFuture().get(); } else { @@ -948,7 +949,7 @@ public class KeyStore { } public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] signature) { - return finish(token, arguments, signature, null); + return finish(token, arguments, null, signature, null); } private class KeystoreResultPromise diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java index 441ee660b53a..c6515efd2c61 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java @@ -432,7 +432,7 @@ abstract class AndroidKeyStoreAuthenticatedAESCipherSpi extends AndroidKeyStoreC } @Override - public OperationResult finish(byte[] signature, byte[] additionalEntropy) { + public OperationResult finish(byte[] input, byte[] signature, byte[] additionalEntropy) { if ((additionalEntropy != null) && (additionalEntropy.length > 0)) { throw new ProviderException("AAD stream does not support additional entropy"); } diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java index 3dc884eb38ad..17aacb9756aa 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java @@ -210,13 +210,9 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { } } if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { - if (mKeySizeBits < 64) { + if (mKeySizeBits < 64 || mKeySizeBits > 512) { throw new InvalidAlgorithmParameterException( - "HMAC key size must be at least 64 bits."); - } - if (mKeySizeBits > 512 && spec.isStrongBoxBacked()) { - throw new InvalidAlgorithmParameterException( - "StrongBox HMAC key size must be smaller than 512 bits."); + "HMAC key sizes must be within 64-512 bits, inclusive."); } // JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm diff --git a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java index e0304787142d..75bea26aecef 100644 --- a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java +++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java @@ -62,7 +62,7 @@ class KeyStoreCryptoOperationChunkedStreamer implements KeyStoreCryptoOperationS * Returns the result of the KeyStore {@code finish} operation or null if keystore couldn't * be reached. */ - OperationResult finish(byte[] siganture, byte[] additionalEntropy); + OperationResult finish(byte[] input, byte[] siganture, byte[] additionalEntropy); } // Binder buffer is about 1MB, but it's shared between all active transactions of the process. @@ -217,7 +217,8 @@ class KeyStoreCryptoOperationChunkedStreamer implements KeyStoreCryptoOperationS byte[] output = update(input, inputOffset, inputLength); output = ArrayUtils.concat(output, flush()); - OperationResult opResult = mKeyStoreStream.finish(signature, additionalEntropy); + OperationResult opResult = mKeyStoreStream.finish(EmptyArray.BYTE, signature, + additionalEntropy); if (opResult == null) { throw new KeyStoreConnectException(); } else if (opResult.resultCode != KeyStore.NO_ERROR) { @@ -334,8 +335,8 @@ class KeyStoreCryptoOperationChunkedStreamer implements KeyStoreCryptoOperationS } @Override - public OperationResult finish(byte[] signature, byte[] additionalEntropy) { - return mKeyStore.finish(mOperationToken, null, signature, additionalEntropy); + public OperationResult finish(byte[] input, byte[] signature, byte[] additionalEntropy) { + return mKeyStore.finish(mOperationToken, null, input, signature, additionalEntropy); } } } 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/media/jni/android_media_MediaDataSource.cpp b/media/jni/android_media_MediaDataSource.cpp index 8c38d887f82b..84a0e0d032d9 100644 --- a/media/jni/android_media_MediaDataSource.cpp +++ b/media/jni/android_media_MediaDataSource.cpp @@ -26,7 +26,6 @@ #include <nativehelper/JNIHelp.h> #include <binder/MemoryDealer.h> -#include <drm/drm_framework_common.h> #include <media/stagefright/foundation/ADebug.h> #include <nativehelper/ScopedLocalRef.h> @@ -160,8 +159,4 @@ String8 JMediaDataSource::toString() { return String8::format("JMediaDataSource(pid %d, uid %d)", getpid(), getuid()); } -sp<DecryptHandle> JMediaDataSource::DrmInitialization(const char * /* mime */) { - return NULL; -} - } // namespace android diff --git a/media/jni/android_media_MediaDataSource.h b/media/jni/android_media_MediaDataSource.h index 39405d2db579..378baf433fed 100644 --- a/media/jni/android_media_MediaDataSource.h +++ b/media/jni/android_media_MediaDataSource.h @@ -47,7 +47,6 @@ public: virtual void close(); virtual uint32_t getFlags(); virtual String8 toString(); - virtual sp<DecryptHandle> DrmInitialization(const char *mime); private: // Protect all member variables with mLock because this object will be 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/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/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/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 047ac5984fe3..13fc881624ec 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -207,6 +207,9 @@ <!-- Permission required for CTS test - CrossProfileAppsHostSideTest --> <uses-permission android:name="android.permission.INTERACT_ACROSS_PROFILES"/> + <!-- Permission requried for CTS test - UiModeManagerTest --> + <uses-permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED"/> + <application android:label="@string/app_label" android:theme="@android:style/Theme.DeviceDefault.DayNight" android:defaultToDeviceProtectedStorage="true" 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 f73ca1c36005..236f17e76e0d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java @@ -110,8 +110,7 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof mCallbacks.add(callback); if (mWifiManager != null) { if (mCallbacks.size() == 1) { - mWifiManager.registerSoftApCallback(this, - new HandlerExecutor(mMainHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mMainHandler), this); } else { // mWifiManager#registerSoftApCallback triggers a call to // onConnectedClientsChanged on the Main Handler. In order to always update @@ -120,6 +119,7 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof mMainHandler.post(() -> callback.onHotspotChanged(isHotspotEnabled(), mNumConnectedDevices)); + } } } 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 7496e3ade351..631c580a490d 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 @@ -70,11 +70,11 @@ public class HotspotControllerImplTest extends SysuiTestCase { mContext.addMockSystemService(WifiManager.class, mWifiManager); doAnswer((InvocationOnMock invocation) -> { - ((WifiManager.SoftApCallback) invocation.getArgument(0)) + ((WifiManager.SoftApCallback) invocation.getArgument(1)) .onConnectedClientsChanged(new ArrayList<>()); return null; - }).when(mWifiManager).registerSoftApCallback(any(WifiManager.SoftApCallback.class), - any(Executor.class)); + }).when(mWifiManager).registerSoftApCallback(any(Executor.class), + any(WifiManager.SoftApCallback.class)); mController = new HotspotControllerImpl(mContext, new Handler(mLooper.getLooper())); } @@ -84,7 +84,7 @@ public class HotspotControllerImplTest extends SysuiTestCase { mController.addCallback(mCallback1); mController.addCallback(mCallback2); - verify(mWifiManager, times(1)).registerSoftApCallback(eq(mController), any()); + verify(mWifiManager, times(1)).registerSoftApCallback(any(), eq(mController)); } @Test diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java index cf0e3b2ddda7..ca9b1681bacc 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java @@ -251,7 +251,7 @@ public class TetheringConfiguration { /** Check whether dun is required. */ public static boolean checkDunRequired(Context ctx, int id) { final TelephonyManager tm = (TelephonyManager) ctx.getSystemService(TELEPHONY_SERVICE); - return (tm != null) ? tm.isTetherApnRequired(id) : false; + return (tm != null) ? tm.isTetheringApnRequired(id) : false; } private static Collection<Integer> getUpstreamIfaceTypes(Resources res, boolean dunRequired) { diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java index 9c65c0deed07..30bff3560955 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java +++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java @@ -145,7 +145,7 @@ public class TetheringConfigurationTest { @Test public void testDunFromTelephonyManagerMeansDun() { - when(mTelephonyManager.isTetherApnRequired(anyInt())).thenReturn(true); + when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(true); final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI); final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration( @@ -169,7 +169,7 @@ public class TetheringConfigurationTest { @Test public void testDunNotRequiredFromTelephonyManagerMeansNoDun() { - when(mTelephonyManager.isTetherApnRequired(anyInt())).thenReturn(false); + when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(false); final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI); final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration( @@ -212,7 +212,7 @@ public class TetheringConfigurationTest { @Test public void testNoDefinedUpstreamTypesAddsEthernet() { when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(new int[]{}); - when(mTelephonyManager.isTetherApnRequired(anyInt())).thenReturn(false); + when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(false); final TetheringConfiguration cfg = new TetheringConfiguration( mMockContext, mLog, INVALID_SUBSCRIPTION_ID); @@ -235,7 +235,7 @@ public class TetheringConfigurationTest { public void testDefinedUpstreamTypesSansEthernetAddsEthernet() { when(mResources.getIntArray(config_tether_upstream_types)).thenReturn( new int[]{TYPE_WIFI, TYPE_MOBILE_HIPRI}); - when(mTelephonyManager.isTetherApnRequired(anyInt())).thenReturn(false); + when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(false); final TetheringConfiguration cfg = new TetheringConfiguration( mMockContext, mLog, INVALID_SUBSCRIPTION_ID); @@ -253,7 +253,7 @@ public class TetheringConfigurationTest { public void testDefinedUpstreamTypesWithEthernetDoesNotAddEthernet() { when(mResources.getIntArray(config_tether_upstream_types)) .thenReturn(new int[]{TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_HIPRI}); - when(mTelephonyManager.isTetherApnRequired(anyInt())).thenReturn(false); + when(mTelephonyManager.isTetheringApnRequired(anyInt())).thenReturn(false); final TetheringConfiguration cfg = new TetheringConfiguration( mMockContext, mLog, INVALID_SUBSCRIPTION_ID); diff --git a/services/core/Android.bp b/services/core/Android.bp index a05c2cc31e40..084a74724ad8 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -32,6 +32,7 @@ java_library_static { "android.hardware.power-V1.0-java", "android.hardware.tv.cec-V1.0-java", "app-compat-annotations", + "vintf-vibrator-java", ], required: [ @@ -50,7 +51,6 @@ java_library_static { "android.hardware.biometrics.fingerprint-V2.1-java", "android.hardware.oemlock-V1.0-java", "android.hardware.tetheroffload.control-V1.0-java", - "android.hardware.vibrator-V1.4-java", "android.hardware.configstore-V1.0-java", "android.hardware.contexthub-V1.0-java", "android.hidl.manager-V1.2-java", diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 81eb4b355a21..a75d5d696bd0 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -146,6 +146,7 @@ import android.security.Credentials; import android.security.KeyStore; import android.telephony.TelephonyManager; import android.text.TextUtils; +import android.util.ArrayMap; import android.util.ArraySet; import android.util.LocalLog; import android.util.Log; @@ -3050,7 +3051,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } private void handleAsyncChannelHalfConnect(Message msg) { - AsyncChannel ac = (AsyncChannel) msg.obj; + ensureRunningOnConnectivityServiceThread(); + final AsyncChannel ac = (AsyncChannel) msg.obj; if (mNetworkFactoryInfos.containsKey(msg.replyTo)) { if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { if (VDBG) log("NetworkFactory connected"); @@ -3060,7 +3062,8 @@ public class ConnectivityService extends IConnectivityManager.Stub // A network factory has connected. Send it all current NetworkRequests. for (NetworkRequestInfo nri : mNetworkRequests.values()) { if (nri.request.isListen()) continue; - NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId); + ensureRunningOnConnectivityServiceThread(); + NetworkAgentInfo nai = nri.mSatisfier; final int score; final int serial; if (nai != null) { @@ -3116,6 +3119,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // ConnectivityService, free its interfaces and clean up. // Must be called on the Handler thread. private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) { + ensureRunningOnConnectivityServiceThread(); if (DBG) { log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests()); } @@ -3162,14 +3166,17 @@ public class ConnectivityService extends IConnectivityManager.Stub // Remove all previously satisfied requests. for (int i = 0; i < nai.numNetworkRequests(); i++) { NetworkRequest request = nai.requestAt(i); - NetworkAgentInfo currentNetwork = getNetworkForRequest(request.requestId); + final NetworkRequestInfo nri = mNetworkRequests.get(request); + ensureRunningOnConnectivityServiceThread(); + final NetworkAgentInfo currentNetwork = nri.mSatisfier; if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) { - clearNetworkForRequest(request.requestId); + nri.mSatisfier = null; sendUpdatedScoreToFactories(request, null); } } nai.clearLingerState(); if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) { + mDefaultNetworkNai = null; updateDataActivityTracking(null /* newNetwork */, nai); notifyLockdownVpn(nai); ensureNetworkTransitionWakelock(nai.name()); @@ -3253,6 +3260,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } private void handleRegisterNetworkRequest(NetworkRequestInfo nri) { + ensureRunningOnConnectivityServiceThread(); mNetworkRequests.put(nri.request, nri); mNetworkRequestInfoLogs.log("REGISTER " + nri); if (nri.request.isListen()) { @@ -3264,7 +3272,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } } rematchAllNetworksAndRequests(null, 0); - if (nri.request.isRequest() && getNetworkForRequest(nri.request.requestId) == null) { + ensureRunningOnConnectivityServiceThread(); + if (nri.request.isRequest() && nri.mSatisfier == null) { sendUpdatedScoreToFactories(nri.request, null); } } @@ -3286,6 +3295,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // - UnneededFor.LINGER: foreground NetworkRequests. If a network is unneeded for this reason, // then it should be lingered. private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) { + ensureRunningOnConnectivityServiceThread(); final int numRequests; switch (reason) { case TEARDOWN: @@ -3310,6 +3320,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // If this Network is already the highest scoring Network for a request, or if // there is hope for it to become one if it validated, then it is needed. + ensureRunningOnConnectivityServiceThread(); if (nri.request.isRequest() && nai.satisfies(nri.request) && (nai.isSatisfyingRequest(nri.request.requestId) || // Note that this catches two important cases: @@ -3319,8 +3330,8 @@ public class ConnectivityService extends IConnectivityManager.Stub // 2. Unvalidated WiFi will not be reaped when validated cellular // is currently satisfying the request. This is desirable when // WiFi ends up validating and out scoring cellular. - getNetworkForRequest(nri.request.requestId).getCurrentScore() < - nai.getCurrentScoreAsValidated())) { + nri.mSatisfier.getCurrentScore() + < nai.getCurrentScoreAsValidated())) { return false; } } @@ -3344,10 +3355,12 @@ public class ConnectivityService extends IConnectivityManager.Stub } private void handleTimedOutNetworkRequest(final NetworkRequestInfo nri) { + ensureRunningOnConnectivityServiceThread(); if (mNetworkRequests.get(nri.request) == null) { return; } - if (getNetworkForRequest(nri.request.requestId) != null) { + ensureRunningOnConnectivityServiceThread(); + if (nri.mSatisfier != null) { return; } if (VDBG || (DBG && nri.request.isRequest())) { @@ -3374,6 +3387,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } private void handleRemoveNetworkRequest(final NetworkRequestInfo nri) { + ensureRunningOnConnectivityServiceThread(); + nri.unlinkDeathRecipient(); mNetworkRequests.remove(nri.request); @@ -3393,7 +3408,8 @@ public class ConnectivityService extends IConnectivityManager.Stub mNetworkRequestInfoLogs.log("RELEASE " + nri); if (nri.request.isRequest()) { boolean wasKept = false; - NetworkAgentInfo nai = getNetworkForRequest(nri.request.requestId); + ensureRunningOnConnectivityServiceThread(); + final NetworkAgentInfo nai = nri.mSatisfier; if (nai != null) { boolean wasBackgroundNetwork = nai.isBackgroundNetwork(); nai.removeRequest(nri.request.requestId); @@ -3410,7 +3426,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } else { wasKept = true; } - clearNetworkForRequest(nri.request.requestId); + nri.mSatisfier = null; if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) { // Went from foreground to background. updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities); @@ -5093,6 +5109,11 @@ public class ConnectivityService extends IConnectivityManager.Stub */ private class NetworkRequestInfo implements IBinder.DeathRecipient { final NetworkRequest request; + // The network currently satisfying this request, or null if none. Must only be touched + // on the handler thread. This only makes sense for network requests and not for listens, + // as defined by NetworkRequest#isRequest(). For listens, this is always null. + @Nullable + NetworkAgentInfo mSatisfier; final PendingIntent mPendingIntent; boolean mPendingIntentSent; private final IBinder mBinder; @@ -5479,16 +5500,6 @@ public class ConnectivityService extends IConnectivityManager.Stub if (DBG) log("unregisterNetworkFactory for " + nfi.name); } - /** - * NetworkAgentInfo supporting a request by requestId. - * These have already been vetted (their Capabilities satisfy the request) - * and the are the highest scored network available. - * the are keyed off the Requests requestId. - */ - // NOTE: Accessed on multiple threads, must be synchronized on itself. - @GuardedBy("mNetworkForRequestId") - private final SparseArray<NetworkAgentInfo> mNetworkForRequestId = new SparseArray<>(); - // NOTE: Accessed on multiple threads, must be synchronized on itself. @GuardedBy("mNetworkForNetId") private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>(); @@ -5506,7 +5517,11 @@ public class ConnectivityService extends IConnectivityManager.Stub private final HashSet<Integer> mBlockedAppUids = new HashSet<>(); // Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated. + @NonNull private final NetworkRequest mDefaultRequest; + // The NetworkAgentInfo currently satisfying the default request, if any. + @Nullable + private volatile NetworkAgentInfo mDefaultNetworkNai = null; // Request used to optionally keep mobile data active even when higher // priority networks like Wi-Fi are active. @@ -5516,26 +5531,8 @@ public class ConnectivityService extends IConnectivityManager.Stub // priority networks like ethernet are active. private final NetworkRequest mDefaultWifiRequest; - private NetworkAgentInfo getNetworkForRequest(int requestId) { - synchronized (mNetworkForRequestId) { - return mNetworkForRequestId.get(requestId); - } - } - - private void clearNetworkForRequest(int requestId) { - synchronized (mNetworkForRequestId) { - mNetworkForRequestId.remove(requestId); - } - } - - private void setNetworkForRequest(int requestId, NetworkAgentInfo nai) { - synchronized (mNetworkForRequestId) { - mNetworkForRequestId.put(requestId, nai); - } - } - private NetworkAgentInfo getDefaultNetwork() { - return getNetworkForRequest(mDefaultRequest.requestId); + return mDefaultNetworkNai; } @Nullable @@ -6253,7 +6250,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - private void makeDefault(NetworkAgentInfo newNetwork) { + private void makeDefault(@NonNull final NetworkAgentInfo newNetwork) { if (DBG) log("Switching to new default network: " + newNetwork); try { @@ -6262,6 +6259,7 @@ public class ConnectivityService extends IConnectivityManager.Stub loge("Exception setting default network :" + e); } + mDefaultNetworkNai = newNetwork; notifyLockdownVpn(newNetwork); handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy()); updateTcpBufferSizes(newNetwork.linkProperties.getTcpBufferSizes()); @@ -6325,6 +6323,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // validated) of becoming the highest scoring network. private void rematchNetworkAndRequests(NetworkAgentInfo newNetwork, ReapUnvalidatedNetworks reapUnvalidatedNetworks, long now) { + ensureRunningOnConnectivityServiceThread(); if (!newNetwork.everConnected) return; boolean keep = newNetwork.isVPN(); boolean isNewDefault = false; @@ -6335,10 +6334,8 @@ public class ConnectivityService extends IConnectivityManager.Stub if (VDBG || DDBG) log("rematching " + newNetwork.name()); - // Find and migrate to this Network any NetworkRequests for - // which this network is now the best. - ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<>(); - ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<>(); + final ArrayMap<NetworkRequestInfo, NetworkAgentInfo> reassignedRequests = new ArrayMap<>(); + NetworkCapabilities nc = newNetwork.networkCapabilities; if (VDBG) log(" network has: " + nc); for (NetworkRequestInfo nri : mNetworkRequests.values()) { @@ -6348,16 +6345,10 @@ public class ConnectivityService extends IConnectivityManager.Stub // requests or not, and doesn't affect the network's score. if (nri.request.isListen()) continue; - final NetworkAgentInfo currentNetwork = getNetworkForRequest(nri.request.requestId); + ensureRunningOnConnectivityServiceThread(); + final NetworkAgentInfo currentNetwork = nri.mSatisfier; final boolean satisfies = newNetwork.satisfies(nri.request); - if (newNetwork == currentNetwork && satisfies) { - if (VDBG) { - log("Network " + newNetwork.name() + " was already satisfying" + - " request " + nri.request.requestId + ". No change."); - } - keep = true; - continue; - } + if (newNetwork == currentNetwork && satisfies) continue; // check if it satisfies the NetworkCapabilities if (VDBG) log(" checking if request is satisfied: " + nri.request); @@ -6370,39 +6361,55 @@ public class ConnectivityService extends IConnectivityManager.Stub ", newScore = " + score); } if (currentNetwork == null || currentNetwork.getCurrentScore() < score) { - if (VDBG) log("rematch for " + newNetwork.name()); - if (currentNetwork != null) { - if (VDBG || DDBG){ - log(" accepting network in place of " + currentNetwork.name()); - } - currentNetwork.removeRequest(nri.request.requestId); - currentNetwork.lingerRequest(nri.request, now, mLingerDelayMs); - affectedNetworks.add(currentNetwork); - } else { - if (VDBG || DDBG) log(" accepting network in place of null"); - } - newNetwork.unlingerRequest(nri.request); - setNetworkForRequest(nri.request.requestId, newNetwork); - if (!newNetwork.addRequest(nri.request)) { - Slog.wtf(TAG, "BUG: " + newNetwork.name() + " already has " + nri.request); + reassignedRequests.put(nri, newNetwork); + } + } else if (newNetwork.isSatisfyingRequest(nri.request.requestId)) { + reassignedRequests.put(nri, null); + } + } + + // Find and migrate to this Network any NetworkRequests for + // which this network is now the best. + final ArrayList<NetworkAgentInfo> removedRequests = new ArrayList<>(); + final ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<>(); + for (final Map.Entry<NetworkRequestInfo, NetworkAgentInfo> entry : + reassignedRequests.entrySet()) { + final NetworkRequestInfo nri = entry.getKey(); + final NetworkAgentInfo previousSatisfier = nri.mSatisfier; + final NetworkAgentInfo newSatisfier = entry.getValue(); + if (newSatisfier != null) { + if (VDBG) log("rematch for " + newSatisfier.name()); + if (previousSatisfier != null) { + if (VDBG || DDBG) { + log(" accepting network in place of " + previousSatisfier.name()); } - addedRequests.add(nri); - keep = true; - // Tell NetworkFactories about the new score, so they can stop - // trying to connect if they know they cannot match it. - // TODO - this could get expensive if we have a lot of requests for this - // network. Think about if there is a way to reduce this. Push - // netid->request mapping to each factory? - sendUpdatedScoreToFactories(nri.request, newNetwork); - if (isDefaultRequest(nri)) { - isNewDefault = true; - oldDefaultNetwork = currentNetwork; - if (currentNetwork != null) { - mLingerMonitor.noteLingerDefaultNetwork(currentNetwork, newNetwork); - } + previousSatisfier.removeRequest(nri.request.requestId); + previousSatisfier.lingerRequest(nri.request, now, mLingerDelayMs); + removedRequests.add(previousSatisfier); + } else { + if (VDBG || DDBG) log(" accepting network in place of null"); + } + newSatisfier.unlingerRequest(nri.request); + nri.mSatisfier = newSatisfier; + if (!newSatisfier.addRequest(nri.request)) { + Slog.wtf(TAG, "BUG: " + newSatisfier.name() + " already has " + nri.request); + } + addedRequests.add(nri); + keep = true; + // Tell NetworkFactories about the new score, so they can stop + // trying to connect if they know they cannot match it. + // TODO - this could get expensive if we have a lot of requests for this + // network. Think about if there is a way to reduce this. Push + // netid->request mapping to each factory? + sendUpdatedScoreToFactories(nri.request, newSatisfier); + if (isDefaultRequest(nri)) { + isNewDefault = true; + oldDefaultNetwork = previousSatisfier; + if (previousSatisfier != null) { + mLingerMonitor.noteLingerDefaultNetwork(previousSatisfier, newSatisfier); } } - } else if (newNetwork.isSatisfyingRequest(nri.request.requestId)) { + } else { // If "newNetwork" is listed as satisfying "nri" but no longer satisfies "nri", // mark it as no longer satisfying "nri". Because networks are processed by // rematchAllNetworksAndRequests() in descending score order, "currentNetwork" will @@ -6415,13 +6422,14 @@ public class ConnectivityService extends IConnectivityManager.Stub " request " + nri.request.requestId); } newNetwork.removeRequest(nri.request.requestId); - if (currentNetwork == newNetwork) { - clearNetworkForRequest(nri.request.requestId); + if (previousSatisfier == newNetwork) { + nri.mSatisfier = null; + if (isDefaultRequest(nri)) mDefaultNetworkNai = null; sendUpdatedScoreToFactories(nri.request, null); } else { Slog.wtf(TAG, "BUG: Removing request " + nri.request.requestId + " from " + newNetwork.name() + - " without updating mNetworkForRequestId or factories!"); + " without updating mSatisfier or factories!"); } // TODO: Technically, sending CALLBACK_LOST here is // incorrect if there is a replacement network currently @@ -6433,6 +6441,7 @@ public class ConnectivityService extends IConnectivityManager.Stub callCallbackForRequest(nri, newNetwork, ConnectivityManager.CALLBACK_LOST, 0); } } + if (isNewDefault) { updateDataActivityTracking(newNetwork, oldDefaultNetwork); // Notify system services that this network is up. @@ -6472,7 +6481,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // Linger any networks that are no longer needed. This should be done after sending the // available callback for newNetwork. - for (NetworkAgentInfo nai : affectedNetworks) { + for (NetworkAgentInfo nai : removedRequests) { updateLingerState(nai, now); } // Possibly unlinger newNetwork. Unlingering a network does not send any callbacks so it diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java index 30a356325ada..d1e4231f88b0 100644 --- a/services/core/java/com/android/server/UiModeManagerService.java +++ b/services/core/java/com/android/server/UiModeManagerService.java @@ -16,6 +16,7 @@ package com.android.server; +import android.annotation.IntRange; import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityManager; @@ -41,6 +42,7 @@ import android.os.Handler; import android.os.PowerManager; import android.os.PowerManager.ServiceType; import android.os.PowerManagerInternal; +import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; @@ -53,6 +55,7 @@ import android.provider.Settings.Secure; import android.service.dreams.Sandman; import android.service.vr.IVrManager; import android.service.vr.IVrStateCallbacks; +import android.util.ArraySet; import android.util.Slog; import com.android.internal.R; @@ -66,6 +69,9 @@ import com.android.server.twilight.TwilightState; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; final class UiModeManagerService extends SystemService { private static final String TAG = UiModeManager.class.getSimpleName(); @@ -81,6 +87,7 @@ final class UiModeManagerService extends SystemService { private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED; private int mNightMode = UiModeManager.MODE_NIGHT_NO; + private Map<Integer, String> mCarModePackagePriority = new HashMap<>(); private boolean mCarModeEnabled = false; private boolean mCharging = false; private boolean mPowerSave = false; @@ -338,15 +345,25 @@ final class UiModeManagerService extends SystemService { private final IUiModeManager.Stub mService = new IUiModeManager.Stub() { @Override - public void enableCarMode(int flags) { + public void enableCarMode(@UiModeManager.EnableCarMode int flags, + @IntRange(from = 0) int priority, String callingPackage) { if (isUiModeLocked()) { Slog.e(TAG, "enableCarMode while UI mode is locked"); return; } + + if (priority != UiModeManager.DEFAULT_PRIORITY + && getContext().checkCallingOrSelfPermission( + android.Manifest.permission.ENTER_CAR_MODE_PRIORITIZED) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Enabling car mode with a priority requires " + + "permission ENTER_CAR_MODE_PRIORITIZED"); + } + final long ident = Binder.clearCallingIdentity(); try { synchronized (mLock) { - setCarModeLocked(true, flags); + setCarModeLocked(true, flags, priority, callingPackage); if (mSystemReady) { updateLocked(flags, 0); } @@ -356,16 +373,49 @@ final class UiModeManagerService extends SystemService { } } + /** + * This method is only kept around for the time being; the AIDL has an UnsupportedAppUsage + * tag which means this method is technically considered part of the greylist "API". + * @param flags + */ + @Override + public void disableCarMode(@UiModeManager.DisableCarMode int flags) { + disableCarModeByCallingPackage(flags, null /* callingPackage */); + } + + /** + * Handles requests to disable car mode. + * @param flags Disable car mode flags + * @param callingPackage + */ @Override - public void disableCarMode(int flags) { + public void disableCarModeByCallingPackage(@UiModeManager.DisableCarMode int flags, + String callingPackage) { if (isUiModeLocked()) { Slog.e(TAG, "disableCarMode while UI mode is locked"); return; } + + // If the caller is the system, we will allow the DISABLE_CAR_MODE_ALL_PRIORITIES car + // mode flag to be specified; this is so that the user can disable car mode at all + // priorities using the persistent notification. + boolean isSystemCaller = Binder.getCallingUid() == Process.SYSTEM_UID; + final int carModeFlags = + isSystemCaller ? flags : flags & ~UiModeManager.DISABLE_CAR_MODE_ALL_PRIORITIES; + final long ident = Binder.clearCallingIdentity(); try { synchronized (mLock) { - setCarModeLocked(false, 0); + // Determine if the caller has enabled car mode at a priority other than the + // default one. If they have, then attempt to disable at that priority. + int priority = mCarModePackagePriority.entrySet() + .stream() + .filter(e -> e.getValue().equals(callingPackage)) + .findFirst() + .map(Map.Entry::getKey) + .orElse(UiModeManager.DEFAULT_PRIORITY); + + setCarModeLocked(false, carModeFlags, priority, callingPackage); if (mSystemReady) { updateLocked(0, flags); } @@ -471,19 +521,32 @@ final class UiModeManagerService extends SystemService { synchronized (mLock) { pw.println("Current UI Mode Service state:"); pw.print(" mDockState="); pw.print(mDockState); - pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState); + pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState); + pw.print(" mNightMode="); pw.print(mNightMode); pw.print(" ("); - pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") "); - pw.print(" mNightModeLocked="); pw.print(mNightModeLocked); - pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled); - pw.print(" mComputedNightMode="); pw.print(mComputedNightMode); - pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags); - pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch); + pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") "); + pw.print(" mNightModeLocked="); pw.println(mNightModeLocked); + + pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled); + pw.print(" (carModeApps="); + for (Map.Entry<Integer, String> entry : mCarModePackagePriority.entrySet()) { + pw.print(entry.getKey()); + pw.print(":"); + pw.print(entry.getValue()); + pw.print(" "); + } + pw.println(""); + pw.print(" mComputedNightMode="); pw.print(mComputedNightMode); + pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags); + pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch); + pw.print(" mCurUiMode=0x"); pw.print(Integer.toHexString(mCurUiMode)); - pw.print(" mUiModeLocked="); pw.print(mUiModeLocked); - pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode)); + pw.print(" mUiModeLocked="); pw.print(mUiModeLocked); + pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode)); + pw.print(" mHoldingConfiguration="); pw.print(mHoldingConfiguration); - pw.print(" mSystemReady="); pw.println(mSystemReady); + pw.print(" mSystemReady="); pw.println(mSystemReady); + if (mTwilightManager != null) { // We may not have a TwilightManager. pw.print(" mTwilightService.getLastTwilightState()="); @@ -506,12 +569,32 @@ final class UiModeManagerService extends SystemService { } } - void setCarModeLocked(boolean enabled, int flags) { - if (mCarModeEnabled != enabled) { - mCarModeEnabled = enabled; + /** + * Updates the global car mode state. + * The device is considered to be in car mode if there exists an app at any priority level which + * has entered car mode. + * + * @param enabled {@code true} if the caller wishes to enable car mode, {@code false} otherwise. + * @param flags Flags used when enabling/disabling car mode. + * @param priority The priority level for entering or exiting car mode; defaults to + * {@link UiModeManager#DEFAULT_PRIORITY} for callers using + * {@link UiModeManager#enableCarMode(int)}. Callers using + * {@link UiModeManager#enableCarMode(int, int)} may specify a priority. + * @param packageName The package name of the app which initiated the request to enable or + * disable car mode. + */ + void setCarModeLocked(boolean enabled, int flags, int priority, String packageName) { + if (enabled) { + enableCarMode(priority, packageName); + } else { + disableCarMode(flags, priority, packageName); + } + boolean isCarModeNowEnabled = isCarModeEnabled(); + if (mCarModeEnabled != isCarModeNowEnabled) { + mCarModeEnabled = isCarModeNowEnabled; // When exiting car mode, restore night mode from settings - if (!mCarModeEnabled) { + if (!isCarModeNowEnabled) { Context context = getContext(); updateNightModeFromSettings(context, context.getResources(), @@ -521,11 +604,102 @@ final class UiModeManagerService extends SystemService { mCarModeEnableFlags = flags; } + /** + * Handles disabling car mode. + * <p> + * Car mode can be disabled at a priority level if any of the following is true: + * 1. The priority being disabled is the {@link UiModeManager#DEFAULT_PRIORITY}. + * 2. The priority level is enabled and the caller is the app who originally enabled it. + * 3. The {@link UiModeManager#DISABLE_CAR_MODE_ALL_PRIORITIES} flag was specified, meaning all + * car mode priorities are disabled. + * + * @param flags Car mode flags. + * @param priority The priority level at which to disable car mode. + * @param packageName The calling package which initiated the request. + */ + private void disableCarMode(int flags, int priority, String packageName) { + boolean isDisableAll = (flags & UiModeManager.DISABLE_CAR_MODE_ALL_PRIORITIES) != 0; + boolean isPriorityTracked = mCarModePackagePriority.keySet().contains(priority); + boolean isDefaultPriority = priority == UiModeManager.DEFAULT_PRIORITY; + boolean isChangeAllowed = + // Anyone can disable the default priority. + isDefaultPriority + // If priority was enabled, only enabling package can disable it. + || isPriorityTracked && mCarModePackagePriority.get(priority).equals(packageName) + // Disable all priorities flag can disable all regardless. + || isDisableAll; + if (isChangeAllowed) { + Slog.d(TAG, "disableCarMode: disabling, priority=" + priority + + ", packageName=" + packageName); + if (isDisableAll) { + Set<Map.Entry<Integer, String>> entries = + new ArraySet<>(mCarModePackagePriority.entrySet()); + mCarModePackagePriority.clear(); + + for (Map.Entry<Integer, String> entry : entries) { + notifyCarModeDisabled(entry.getKey(), entry.getValue()); + } + } else { + mCarModePackagePriority.remove(priority); + notifyCarModeDisabled(priority, packageName); + } + } + } + + /** + * Handles enabling car mode. + * <p> + * Car mode can be enabled at any priority if it has not already been enabled at that priority. + * The calling package is tracked for the first app which enters priority at the + * {@link UiModeManager#DEFAULT_PRIORITY}, though any app can disable it at that priority. + * + * @param priority The priority for enabling car mode. + * @param packageName The calling package which initiated the request. + */ + private void enableCarMode(int priority, String packageName) { + boolean isPriorityTracked = mCarModePackagePriority.containsKey(priority); + boolean isPackagePresent = mCarModePackagePriority.containsValue(packageName); + if (!isPriorityTracked && !isPackagePresent) { + Slog.d(TAG, "enableCarMode: enabled at priority=" + priority + ", packageName=" + + packageName); + mCarModePackagePriority.put(priority, packageName); + notifyCarModeEnabled(priority, packageName); + } else { + Slog.d(TAG, "enableCarMode: car mode at priority " + priority + " already enabled."); + } + + } + + private void notifyCarModeEnabled(int priority, String packageName) { + Intent intent = new Intent(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED); + intent.putExtra(UiModeManager.EXTRA_CALLING_PACKAGE, packageName); + intent.putExtra(UiModeManager.EXTRA_PRIORITY, priority); + getContext().sendBroadcastAsUser(intent, UserHandle.ALL, + android.Manifest.permission.HANDLE_CAR_MODE_CHANGES); + } + + private void notifyCarModeDisabled(int priority, String packageName) { + Intent intent = new Intent(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED); + intent.putExtra(UiModeManager.EXTRA_CALLING_PACKAGE, packageName); + intent.putExtra(UiModeManager.EXTRA_PRIORITY, priority); + getContext().sendBroadcastAsUser(intent, UserHandle.ALL, + android.Manifest.permission.HANDLE_CAR_MODE_CHANGES); + } + + /** + * Determines if car mode is enabled at any priority level. + * @return {@code true} if car mode is enabled, {@code false} otherwise. + */ + private boolean isCarModeEnabled() { + return mCarModePackagePriority.size() > 0; + } + private void updateDockState(int newState) { synchronized (mLock) { if (newState != mDockState) { mDockState = newState; - setCarModeLocked(mDockState == Intent.EXTRA_DOCK_STATE_CAR, 0); + setCarModeLocked(mDockState == Intent.EXTRA_DOCK_STATE_CAR, 0, + UiModeManager.DEFAULT_PRIORITY, "" /* packageName */); if (mSystemReady) { updateLocked(UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME, 0); } diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java index d622fb433ed8..0db8495e9af9 100644 --- a/services/core/java/com/android/server/VibratorService.java +++ b/services/core/java/com/android/server/VibratorService.java @@ -28,8 +28,8 @@ import android.content.pm.PackageManager; import android.content.res.Resources; import android.database.ContentObserver; import android.hardware.input.InputManager; +import android.hardware.vibrator.IVibrator; import android.hardware.vibrator.V1_0.EffectStrength; -import android.hardware.vibrator.V1_4.Capabilities; import android.icu.text.DateFormat; import android.media.AudioAttributes; import android.media.AudioManager; @@ -1153,7 +1153,7 @@ public class VibratorService extends IVibratorService.Stub long duration = vibratorPerformEffect(prebaked.getId(), prebaked.getEffectStrength(), vib); long timeout = duration; - if ((mCapabilities & Capabilities.PERFORM_COMPLETION_CALLBACK) != 0) { + if ((mCapabilities & IVibrator.CAP_PERFORM_CALLBACK) != 0) { timeout *= ASYNC_TIMEOUT_MULTIPLIER; } if (timeout > 0) { 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/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/InstructionSets.java b/services/core/java/com/android/server/pm/InstructionSets.java index f326f1d20c46..ec48713b0874 100644 --- a/services/core/java/com/android/server/pm/InstructionSets.java +++ b/services/core/java/com/android/server/pm/InstructionSets.java @@ -22,11 +22,11 @@ import android.os.SystemProperties; import android.text.TextUtils; import android.util.ArraySet; +import dalvik.system.VMRuntime; + import java.util.ArrayList; import java.util.List; -import dalvik.system.VMRuntime; - /** * Provides various methods for obtaining and converting of instruction sets. * @@ -113,12 +113,15 @@ public class InstructionSets { return allInstructionSets; } - public static String getPrimaryInstructionSet(ApplicationInfo info) { - if (info.primaryCpuAbi == null) { + /** + * Calculates the primary instruction set based on the computed Abis of a given package. + */ + public static String getPrimaryInstructionSet(PackageAbiHelper.Abis abis) { + if (abis.primary == null) { return getPreferredInstructionSet(); } - return VMRuntime.getInstructionSet(info.primaryCpuAbi); + return VMRuntime.getInstructionSet(abis.primary); } } diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS index 62ea95b21865..f8c173f6a9c1 100644 --- a/services/core/java/com/android/server/pm/OWNERS +++ b/services/core/java/com/android/server/pm/OWNERS @@ -32,6 +32,9 @@ per-file CrossProfileIntentFilter.java = omakoto@google.com, yamasani@google.com per-file CrossProfileIntentResolver.java = omakoto@google.com, yamasani@google.com per-file UserManagerService.java = omakoto@google.com, yamasani@google.com per-file UserRestrictionsUtils.java = omakoto@google.com, rubinxu@google.com, sandness@google.com, yamasani@google.com +per-file UserSystemPackageInstaller.java = bookatz@google.com, omakoto@google.com, yamasani@google.com +per-file UserTypeDetails.java = bookatz@google.com, omakoto@google.com, yamasani@google.com +per-file UserTypeFactory.java = bookatz@google.com, omakoto@google.com, yamasani@google.com # security per-file KeySetHandle.java = cbrubaker@google.com, nnk@google.com diff --git a/services/core/java/com/android/server/pm/PackageAbiHelper.java b/services/core/java/com/android/server/pm/PackageAbiHelper.java new file mode 100644 index 000000000000..6f46564068d9 --- /dev/null +++ b/services/core/java/com/android/server/pm/PackageAbiHelper.java @@ -0,0 +1,135 @@ +/* + * 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 com.android.server.pm; + +import android.annotation.Nullable; +import android.content.pm.PackageParser; +import android.util.Pair; + +import com.android.internal.annotations.VisibleForTesting; + +import java.io.File; +import java.util.Set; + +@VisibleForTesting +interface PackageAbiHelper { + /** + * Derive and get the location of native libraries for the given package, + * which varies depending on where and how the package was installed. + */ + NativeLibraryPaths getNativeLibraryPaths( + PackageParser.Package pkg, File appLib32InstallDir); + + /** + * Calculate the abis for a bundled app. These can uniquely be determined from the contents of + * the system partition, i.e whether it contains 64 or 32 bit shared libraries etc. We do not + * validate any of this information, and instead assume that the system was built sensibly. + */ + Abis getBundledAppAbis(PackageParser.Package pkg); + + /** + * Derive the ABI of a non-system package located at {@code pkg}. This information + * is derived purely on the basis of the contents of {@code pkg} and {@code cpuAbiOverride}. + * + * If {@code extractLibs} is true, native libraries are extracted from the app if required. + */ + Pair<Abis, NativeLibraryPaths> derivePackageAbi( + PackageParser.Package pkg, String cpuAbiOverride, boolean extractLibs) + throws PackageManagerException; + + /** + * Calculates adjusted ABIs for a set of packages belonging to a shared user so that they all + * match. i.e, so that all packages can be run inside a single process if required. + * + * Optionally, callers can pass in a parsed package via {@code scannedPackage} in which case + * this function will either try and make the ABI for all packages in + * {@code packagesForUser} match {@code scannedPackage} or will update the ABI of + * {@code scannedPackage} to match the ABI selected for {@code packagesForUser}. This + * variant is used when installing or updating a package that belongs to a shared user. + * + * NOTE: We currently only match for the primary CPU abi string. Matching the secondary + * adds unnecessary complexity. + * + * @return the calculated primary abi that should be set for all non-specified packages + * belonging to the shared user. + */ + @Nullable + String getAdjustedAbiForSharedUser( + Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage); + + /** + * The native library paths and related properties that should be set on a + * {@link android.content.pm.PackageParser.Package}. + */ + final class NativeLibraryPaths { + public final String nativeLibraryRootDir; + public final boolean nativeLibraryRootRequiresIsa; + public final String nativeLibraryDir; + public final String secondaryNativeLibraryDir; + + @VisibleForTesting + NativeLibraryPaths(String nativeLibraryRootDir, + boolean nativeLibraryRootRequiresIsa, String nativeLibraryDir, + String secondaryNativeLibraryDir) { + this.nativeLibraryRootDir = nativeLibraryRootDir; + this.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa; + this.nativeLibraryDir = nativeLibraryDir; + this.secondaryNativeLibraryDir = secondaryNativeLibraryDir; + } + + public void applyTo(PackageParser.Package pkg) { + pkg.applicationInfo.nativeLibraryRootDir = nativeLibraryRootDir; + pkg.applicationInfo.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa; + pkg.applicationInfo.nativeLibraryDir = nativeLibraryDir; + pkg.applicationInfo.secondaryNativeLibraryDir = secondaryNativeLibraryDir; + } + } + + /** + * The primary and secondary ABIs that should be set on a package and its package setting. + */ + final class Abis { + public final String primary; + public final String secondary; + + @VisibleForTesting + Abis(String primary, String secondary) { + this.primary = primary; + this.secondary = secondary; + } + + Abis(PackageParser.Package pkg) { + this(pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi); + } + + public void applyTo(PackageParser.Package pkg) { + pkg.applicationInfo.primaryCpuAbi = primary; + pkg.applicationInfo.secondaryCpuAbi = secondary; + } + public void applyTo(PackageSetting pkgSetting) { + // pkgSetting might be null during rescan following uninstall of updates + // to a bundled app, so accommodate that possibility. The settings in + // that case will be established later from the parsed package. + // + // If the settings aren't null, sync them up with what we've derived. + if (pkgSetting != null) { + pkgSetting.primaryCpuAbiString = primary; + pkgSetting.secondaryCpuAbiString = secondary; + } + } + } +} diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java new file mode 100644 index 000000000000..1d3d24c27041 --- /dev/null +++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java @@ -0,0 +1,528 @@ +/* + * 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 com.android.server.pm; + +import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; +import static android.content.pm.PackageParser.isApkFile; +import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; + +import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; +import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; +import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; +import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; + +import android.annotation.Nullable; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageParser; +import android.os.Build; +import android.os.Environment; +import android.os.FileUtils; +import android.os.Trace; +import android.text.TextUtils; +import android.util.Pair; +import android.util.Slog; + +import com.android.internal.content.NativeLibraryHelper; +import com.android.internal.util.ArrayUtils; + +import dalvik.system.VMRuntime; + +import libcore.io.IoUtils; + +import java.io.File; +import java.io.IOException; +import java.util.Set; + +final class PackageAbiHelperImpl implements PackageAbiHelper { + + private static String calculateBundledApkRoot(final String codePathString) { + final File codePath = new File(codePathString); + final File codeRoot; + if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { + codeRoot = Environment.getRootDirectory(); + } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { + codeRoot = Environment.getOemDirectory(); + } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { + codeRoot = Environment.getVendorDirectory(); + } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) { + codeRoot = Environment.getOdmDirectory(); + } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) { + codeRoot = Environment.getProductDirectory(); + } else if (FileUtils.contains(Environment.getSystemExtDirectory(), codePath)) { + codeRoot = Environment.getSystemExtDirectory(); + } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) { + codeRoot = Environment.getOdmDirectory(); + } else { + // Unrecognized code path; take its top real segment as the apk root: + // e.g. /something/app/blah.apk => /something + try { + File f = codePath.getCanonicalFile(); + File parent = f.getParentFile(); // non-null because codePath is a file + File tmp; + while ((tmp = parent.getParentFile()) != null) { + f = parent; + parent = tmp; + } + codeRoot = f; + Slog.w(PackageManagerService.TAG, "Unrecognized code path " + + codePath + " - using " + codeRoot); + } catch (IOException e) { + // Can't canonicalize the code path -- shenanigans? + Slog.w(PackageManagerService.TAG, "Can't canonicalize code path " + codePath); + return Environment.getRootDirectory().getPath(); + } + } + return codeRoot.getPath(); + } + + // Utility method that returns the relative package path with respect + // to the installation directory. Like say for /data/data/com.test-1.apk + // string com.test-1 is returned. + private static String deriveCodePathName(String codePath) { + if (codePath == null) { + return null; + } + final File codeFile = new File(codePath); + final String name = codeFile.getName(); + if (codeFile.isDirectory()) { + return name; + } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { + final int lastDot = name.lastIndexOf('.'); + return name.substring(0, lastDot); + } else { + Slog.w(PackageManagerService.TAG, "Odd, " + codePath + " doesn't look like an APK"); + return null; + } + } + + private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws + PackageManagerException { + if (copyRet < 0) { + if (copyRet != PackageManager.NO_NATIVE_LIBRARIES + && copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { + throw new PackageManagerException(copyRet, message); + } + } + } + + @Override + public NativeLibraryPaths getNativeLibraryPaths( + PackageParser.Package pkg, File appLib32InstallDir) { + return getNativeLibraryPaths(new Abis(pkg), appLib32InstallDir, pkg.codePath, + pkg.applicationInfo.sourceDir, pkg.applicationInfo.isSystemApp(), + pkg.applicationInfo.isUpdatedSystemApp()); + } + + private static NativeLibraryPaths getNativeLibraryPaths(final Abis abis, + final File appLib32InstallDir, final String codePath, final String sourceDir, + final boolean isSystemApp, final boolean isUpdatedSystemApp) { + final File codeFile = new File(codePath); + final boolean bundledApp = isSystemApp && !isUpdatedSystemApp; + + final String nativeLibraryRootDir; + final boolean nativeLibraryRootRequiresIsa; + final String nativeLibraryDir; + final String secondaryNativeLibraryDir; + + if (isApkFile(codeFile)) { + // Monolithic install + if (bundledApp) { + // If "/system/lib64/apkname" exists, assume that is the per-package + // native library directory to use; otherwise use "/system/lib/apkname". + final String apkRoot = calculateBundledApkRoot(sourceDir); + final boolean is64Bit = VMRuntime.is64BitInstructionSet( + getPrimaryInstructionSet(abis)); + + // This is a bundled system app so choose the path based on the ABI. + // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this + // is just the default path. + final String apkName = deriveCodePathName(codePath); + final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; + nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, + apkName).getAbsolutePath(); + + if (abis.secondary != null) { + final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; + secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), + secondaryLibDir, apkName).getAbsolutePath(); + } else { + secondaryNativeLibraryDir = null; + } + } else { + final String apkName = deriveCodePathName(codePath); + nativeLibraryRootDir = new File(appLib32InstallDir, apkName) + .getAbsolutePath(); + secondaryNativeLibraryDir = null; + } + + nativeLibraryRootRequiresIsa = false; + nativeLibraryDir = nativeLibraryRootDir; + } else { + // Cluster install + nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); + nativeLibraryRootRequiresIsa = true; + + nativeLibraryDir = new File(nativeLibraryRootDir, + getPrimaryInstructionSet(abis)).getAbsolutePath(); + + if (abis.secondary != null) { + secondaryNativeLibraryDir = new File(nativeLibraryRootDir, + VMRuntime.getInstructionSet(abis.secondary)).getAbsolutePath(); + } else { + secondaryNativeLibraryDir = null; + } + } + return new NativeLibraryPaths(nativeLibraryRootDir, nativeLibraryRootRequiresIsa, + nativeLibraryDir, secondaryNativeLibraryDir); + } + + @Override + public Abis getBundledAppAbis(PackageParser.Package pkg) { + final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); + + // If "/system/lib64/apkname" exists, assume that is the per-package + // native library directory to use; otherwise use "/system/lib/apkname". + final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); + final Abis abis = getBundledAppAbi(pkg, apkRoot, apkName); + return abis; + } + + /** + * Deduces the ABI of a bundled app and sets the relevant fields on the + * parsed pkg object. + * + * @param apkRoot the root of the installed apk, something like {@code /system} or + * {@code /oem} under which system libraries are installed. + * @param apkName the name of the installed package. + */ + private Abis getBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { + final File codeFile = new File(pkg.codePath); + + final boolean has64BitLibs; + final boolean has32BitLibs; + + final String primaryCpuAbi; + final String secondaryCpuAbi; + if (isApkFile(codeFile)) { + // Monolithic install + has64BitLibs = + (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); + has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); + } else { + // Cluster install + final File rootDir = new File(codeFile, LIB_DIR_NAME); + if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) + && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { + final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); + has64BitLibs = (new File(rootDir, isa)).exists(); + } else { + has64BitLibs = false; + } + if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) + && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { + final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); + has32BitLibs = (new File(rootDir, isa)).exists(); + } else { + has32BitLibs = false; + } + } + + if (has64BitLibs && !has32BitLibs) { + // The package has 64 bit libs, but not 32 bit libs. Its primary + // ABI should be 64 bit. We can safely assume here that the bundled + // native libraries correspond to the most preferred ABI in the list. + + primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; + secondaryCpuAbi = null; + } else if (has32BitLibs && !has64BitLibs) { + // The package has 32 bit libs but not 64 bit libs. Its primary + // ABI should be 32 bit. + + primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; + secondaryCpuAbi = null; + } else if (has32BitLibs && has64BitLibs) { + // The application has both 64 and 32 bit bundled libraries. We check + // here that the app declares multiArch support, and warn if it doesn't. + // + // We will be lenient here and record both ABIs. The primary will be the + // ABI that's higher on the list, i.e, a device that's configured to prefer + // 64 bit apps will see a 64 bit primary ABI, + + if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { + Slog.e(PackageManagerService.TAG, + "Package " + pkg + " has multiple bundled libs, but is not multiarch."); + } + + if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { + primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; + secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; + } else { + primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; + secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; + } + } else { + primaryCpuAbi = null; + secondaryCpuAbi = null; + } + return new Abis(primaryCpuAbi, secondaryCpuAbi); + } + + @Override + public Pair<Abis, NativeLibraryPaths> derivePackageAbi( + PackageParser.Package pkg, String cpuAbiOverride, boolean extractLibs) + throws PackageManagerException { + // Give ourselves some initial paths; we'll come back for another + // pass once we've determined ABI below. + final NativeLibraryPaths initialLibraryPaths = getNativeLibraryPaths(new Abis(pkg), + PackageManagerService.sAppLib32InstallDir, pkg.codePath, + pkg.applicationInfo.sourceDir, pkg.applicationInfo.isSystemApp(), + pkg.applicationInfo.isUpdatedSystemApp()); + + // We shouldn't attempt to extract libs from system app when it was not updated. + if (PackageManagerService.isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { + extractLibs = false; + } + + final String nativeLibraryRootStr = initialLibraryPaths.nativeLibraryRootDir; + final boolean useIsaSpecificSubdirs = initialLibraryPaths.nativeLibraryRootRequiresIsa; + + String primaryCpuAbi = null; + String secondaryCpuAbi = null; + + NativeLibraryHelper.Handle handle = null; + try { + handle = NativeLibraryHelper.Handle.create(pkg); + // TODO(multiArch): This can be null for apps that didn't go through the + // usual installation process. We can calculate it again, like we + // do during install time. + // + // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally + // unnecessary. + final File nativeLibraryRoot = new File(nativeLibraryRootStr); + + // Null out the abis so that they can be recalculated. + primaryCpuAbi = null; + secondaryCpuAbi = null; + if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0) { + // Warn if we've set an abiOverride for multi-lib packages.. + // By definition, we need to copy both 32 and 64 bit libraries for + // such packages. + if (pkg.cpuAbiOverride != null + && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { + Slog.w(PackageManagerService.TAG, + "Ignoring abiOverride for multi arch application."); + } + + int abi32 = PackageManager.NO_NATIVE_LIBRARIES; + int abi64 = PackageManager.NO_NATIVE_LIBRARIES; + if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { + if (extractLibs) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); + abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, + nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, + useIsaSpecificSubdirs); + } else { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); + abi32 = NativeLibraryHelper.findSupportedAbi( + handle, Build.SUPPORTED_32_BIT_ABIS); + } + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } + + // Shared library native code should be in the APK zip aligned + if (abi32 >= 0 && pkg.isLibrary() && extractLibs) { + throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, + "Shared library native lib extraction not supported"); + } + + maybeThrowExceptionForMultiArchCopy( + "Error unpackaging 32 bit native libs for multiarch app.", abi32); + + if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { + if (extractLibs) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); + abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, + nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, + useIsaSpecificSubdirs); + } else { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); + abi64 = NativeLibraryHelper.findSupportedAbi( + handle, Build.SUPPORTED_64_BIT_ABIS); + } + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } + + maybeThrowExceptionForMultiArchCopy( + "Error unpackaging 64 bit native libs for multiarch app.", abi64); + + if (abi64 >= 0) { + // Shared library native libs should be in the APK zip aligned + if (extractLibs && pkg.isLibrary()) { + throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, + "Shared library native lib extraction not supported"); + } + primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; + } + + if (abi32 >= 0) { + final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; + if (abi64 >= 0) { + if (pkg.use32bitAbi) { + secondaryCpuAbi = primaryCpuAbi; + primaryCpuAbi = abi; + } else { + secondaryCpuAbi = abi; + } + } else { + primaryCpuAbi = abi; + } + } + } else { + String[] abiList = (cpuAbiOverride != null) + ? new String[]{cpuAbiOverride} : Build.SUPPORTED_ABIS; + + // Enable gross and lame hacks for apps that are built with old + // SDK tools. We must scan their APKs for renderscript bitcode and + // not launch them if it's present. Don't bother checking on devices + // that don't have 64 bit support. + boolean needsRenderScriptOverride = false; + if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null + && NativeLibraryHelper.hasRenderscriptBitcode(handle)) { + abiList = Build.SUPPORTED_32_BIT_ABIS; + needsRenderScriptOverride = true; + } + + final int copyRet; + if (extractLibs) { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); + copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, + nativeLibraryRoot, abiList, useIsaSpecificSubdirs); + } else { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); + copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); + } + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + + if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { + throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, + "Error unpackaging native libs for app, errorCode=" + copyRet); + } + + if (copyRet >= 0) { + // Shared libraries that have native libs must be multi-architecture + if (pkg.isLibrary()) { + throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, + "Shared library with native libs must be multiarch"); + } + primaryCpuAbi = abiList[copyRet]; + } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES + && cpuAbiOverride != null) { + primaryCpuAbi = cpuAbiOverride; + } else if (needsRenderScriptOverride) { + primaryCpuAbi = abiList[0]; + } + } + } catch (IOException ioe) { + Slog.e(PackageManagerService.TAG, "Unable to get canonical file " + ioe.toString()); + } finally { + IoUtils.closeQuietly(handle); + } + + // Now that we've calculated the ABIs and determined if it's an internal app, + // we will go ahead and populate the nativeLibraryPath. + + final Abis abis = new Abis(primaryCpuAbi, secondaryCpuAbi); + return new Pair<>(abis, + getNativeLibraryPaths(abis, PackageManagerService.sAppLib32InstallDir, + pkg.codePath, pkg.applicationInfo.sourceDir, + pkg.applicationInfo.isSystemApp(), + pkg.applicationInfo.isUpdatedSystemApp())); + } + + /** + * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. + * i.e, so that all packages can be run inside a single process if required. + * + * Optionally, callers can pass in a parsed package via {@code newPackage} in which case + * this function will either try and make the ABI for all packages in + * {@code packagesForUser} match {@code scannedPackage} or will update the ABI of + * {@code scannedPackage} to match the ABI selected for {@code packagesForUser}. This + * variant is used when installing or updating a package that belongs to a shared user. + * + * NOTE: We currently only match for the primary CPU abi string. Matching the secondary + * adds unnecessary complexity. + */ + @Override + @Nullable + public String getAdjustedAbiForSharedUser( + Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) { + String requiredInstructionSet = null; + if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { + requiredInstructionSet = VMRuntime.getInstructionSet( + scannedPackage.applicationInfo.primaryCpuAbi); + } + + PackageSetting requirer = null; + for (PackageSetting ps : packagesForUser) { + // If packagesForUser contains scannedPackage, we skip it. This will happen + // when scannedPackage is an update of an existing package. Without this check, + // we will never be able to change the ABI of any package belonging to a shared + // user, even if it's compatible with other packages. + if (scannedPackage != null && scannedPackage.packageName.equals(ps.name)) { + continue; + } + if (ps.primaryCpuAbiString == null) { + continue; + } + + final String instructionSet = + VMRuntime.getInstructionSet(ps.primaryCpuAbiString); + if (requiredInstructionSet != null && !requiredInstructionSet.equals(instructionSet)) { + // We have a mismatch between instruction sets (say arm vs arm64) warn about + // this but there's not much we can do. + String errorMessage = "Instruction set mismatch, " + + ((requirer == null) ? "[caller]" : requirer) + + " requires " + requiredInstructionSet + " whereas " + ps + + " requires " + instructionSet; + Slog.w(PackageManagerService.TAG, errorMessage); + } + + if (requiredInstructionSet == null) { + requiredInstructionSet = instructionSet; + requirer = ps; + } + } + + if (requiredInstructionSet == null) { + return null; + } + final String adjustedAbi; + if (requirer != null) { + // requirer != null implies that either scannedPackage was null or that + // scannedPackage did not require an ABI, in which case we have to adjust + // scannedPackage to match the ABI of the set (which is the same as + // requirer's ABI) + adjustedAbi = requirer.primaryCpuAbiString; + } else { + // requirer == null implies that we're updating all ABIs in the set to + // match scannedPackage. + adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; + } + return adjustedAbi; + } +} diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 868b90ac1f26..a77b72871155 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -93,14 +93,12 @@ import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL; import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT; -import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; import static com.android.server.pm.ComponentResolver.RESOLVE_PRIORITY_SORTER; import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; -import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter; import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures; import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists; @@ -278,6 +276,7 @@ import android.view.Display; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.ResolverActivity; import com.android.internal.content.NativeLibraryHelper; import com.android.internal.content.PackageHelper; @@ -433,7 +432,7 @@ public class PackageManagerService extends IPackageManager.Stub // user, but by default initialize to this. public static final boolean DEBUG_DEXOPT = false; - private static final boolean DEBUG_ABI_SELECTION = false; + static final boolean DEBUG_ABI_SELECTION = false; private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE; private static final boolean DEBUG_APP_DATA = false; @@ -663,7 +662,8 @@ public class PackageManagerService extends IPackageManager.Stub private static final File sAppInstallDir = new File(Environment.getDataDirectory(), "app"); /** Directory where installed application's 32-bit native libraries are copied. */ - private static final File sAppLib32InstallDir = + @VisibleForTesting + static final File sAppLib32InstallDir = new File(Environment.getDataDirectory(), "app-lib"); // ---------------------------------------------------------------- @@ -754,6 +754,30 @@ public class PackageManagerService extends IPackageManager.Stub private final ApexManager mApexManager; + private final Injector mInjector; + + /** + * Unit tests will instantiate and / or extend to mock dependencies / behaviors. + */ + @VisibleForTesting + static class Injector { + private final UserManagerInternal mUserManager; + private final PackageAbiHelper mAbiHelper; + + Injector(UserManagerInternal userManager, PackageAbiHelper abiHelper) { + mUserManager = userManager; + mAbiHelper = abiHelper; + } + + public UserManagerInternal getUserManager() { + return mUserManager; + } + + public PackageAbiHelper getAbiHelper() { + return mAbiHelper; + } + } + class PackageParserCallback implements PackageParser.Callback { @Override public final boolean hasFeature(String feature) { return PackageManagerService.this.hasSystemFeature(feature, 0); @@ -1406,6 +1430,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; @@ -2092,8 +2117,8 @@ public class PackageManagerService extends IPackageManager.Stub // survive long enough to benefit of background optimizations. for (int userId : firstUserIds) { PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId); - // There's a race currently where some install events may interleave with an uninstall. - // This can lead to package info being null (b/36642664). + // There's a race currently where some install events may interleave with an + // uninstall. This can lead to package info being null (b/36642664). if (info != null) { mDexManager.notifyPackageInstalled(info, userId); } @@ -2163,6 +2188,7 @@ public class PackageManagerService extends IPackageManager.Stub * external/removable/unprotected storage. * @return {@link StorageEnum#TYPE_UNKNOWN} if the package is not stored externally or the * corresponding {@link StorageEnum} storage type value if it is. + * corresponding {@link StorageEnum} storage type value if it is. */ private static int getPackageExternalStorageType(VolumeInfo packageVolume, boolean packageIsExternal) { @@ -2420,6 +2446,11 @@ public class PackageManagerService extends IPackageManager.Stub mPermissionManager.getPermissionSettings(), mPackages); } } + + // TODO(b/137961986): We should pass this via constructor, but would first need to create + // a packages lock that could also be passed in. + mInjector = new Injector(getUserManagerInternal(), new PackageAbiHelperImpl()); + mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, @@ -3116,6 +3147,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. @@ -3126,7 +3158,9 @@ public class PackageManagerService extends IPackageManager.Stub // the rest of the commands above) because there's precious little we // can do about it. A settings error is reported, though. final List<String> changedAbiCodePath = - adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/); + applyAdjustedAbiToSharedUser(setting, null /*scannedPackage*/, + mInjector.getAbiHelper().getAdjustedAbiForSharedUser( + setting.packages, null /*scannedPackage*/)); if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) { for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) { final String codePathString = changedAbiCodePath.get(i); @@ -9395,7 +9429,8 @@ public class PackageManagerService extends IPackageManager.Stub null /* originalPkgSetting */, null, parseFlags, scanFlags, (pkg == mPlatformPackage), user); applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage); - final ScanResult scanResult = scanPackageOnlyLI(request, mFactoryTest, -1L); + final ScanResult scanResult = + scanPackageOnlyLI(request, mInjector, mFactoryTest, -1L); if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) { scanResult.request.pkgSetting.updateFrom(scanResult.pkgSetting); } @@ -10757,7 +10792,8 @@ public class PackageManagerService extends IPackageManager.Stub } /** The result of a package scan. */ - private static class ScanResult { + @VisibleForTesting + static class ScanResult { /** The request that initiated the scan that produced this result. */ public final ScanRequest request; /** Whether or not the package scan was successful */ @@ -10796,7 +10832,8 @@ public class PackageManagerService extends IPackageManager.Stub } /** A package to be scanned */ - private static class ScanRequest { + @VisibleForTesting + static class ScanRequest { /** The parsed package */ @NonNull public final PackageParser.Package pkg; /** The package this package replaces */ @@ -10989,7 +11026,7 @@ public class PackageManagerService extends IPackageManager.Stub pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting, originalPkgSetting, realPkgName, parseFlags, scanFlags, (pkg == mPlatformPackage), user); - return scanPackageOnlyLI(request, mFactoryTest, currentTime); + return scanPackageOnlyLI(request, mInjector, mFactoryTest, currentTime); } } @@ -11214,20 +11251,70 @@ public class PackageManagerService extends IPackageManager.Stub } /** + * Applies the adjusted ABI calculated by + * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(Set, PackageParser.Package)} to all + * relevant packages and settings. + * @param sharedUserSetting The {@code SharedUserSetting} to adjust + * @param scannedPackage the package being scanned or null + * @param adjustedAbi the adjusted ABI calculated by {@link PackageAbiHelper} + * @return the list of code paths that belong to packages that had their ABIs adjusted. + */ + private static List<String> applyAdjustedAbiToSharedUser(SharedUserSetting sharedUserSetting, + PackageParser.Package scannedPackage, String adjustedAbi) { + if (scannedPackage != null) { + scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; + } + List<String> changedAbiCodePath = null; + for (PackageSetting ps : sharedUserSetting.packages) { + if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { + if (ps.primaryCpuAbiString != null) { + continue; + } + + ps.primaryCpuAbiString = adjustedAbi; + if (ps.pkg != null && ps.pkg.applicationInfo != null + && !TextUtils.equals( + adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { + ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; + if (DEBUG_ABI_SELECTION) { + Slog.i(TAG, + "Adjusting ABI for " + ps.name + " to " + adjustedAbi + + " (scannedPackage=" + + (scannedPackage != null ? scannedPackage : "null") + + ")"); + } + if (changedAbiCodePath == null) { + changedAbiCodePath = new ArrayList<>(); + } + changedAbiCodePath.add(ps.codePathString); + } + } + } + return changedAbiCodePath; + } + + + /** * Just scans the package without any side effects. * <p>Not entirely true at the moment. There is still one side effect -- this * method potentially modifies a live {@link PackageSetting} object representing * the package being scanned. This will be resolved in the future. * + * @param injector injector for acquiring dependencies * @param request Information about the package to be scanned * @param isUnderFactoryTest Whether or not the device is under factory test * @param currentTime The current time, in millis * @return The results of the scan */ @GuardedBy("mInstallLock") - private static @NonNull ScanResult scanPackageOnlyLI(@NonNull ScanRequest request, + @VisibleForTesting + @NonNull + static ScanResult scanPackageOnlyLI(@NonNull ScanRequest request, + Injector injector, boolean isUnderFactoryTest, long currentTime) - throws PackageManagerException { + throws PackageManagerException { + final PackageAbiHelper packageAbiHelper = injector.getAbiHelper(); + final UserManagerInternal userManager = injector.getUserManager(); final PackageParser.Package pkg = request.pkg; PackageSetting pkgSetting = request.pkgSetting; final PackageSetting disabledPkgSetting = request.disabledPkgSetting; @@ -11333,7 +11420,7 @@ public class PackageManagerService extends IPackageManager.Stub if (!createNewPackage) { final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0; - setInstantAppForUser(pkgSetting, userId, instantApp, fullApp); + setInstantAppForUser(userManager, pkgSetting, userId, instantApp, fullApp); } // TODO(patb): see if we can do away with disabled check here. if (disabledPkgSetting != null @@ -11379,7 +11466,10 @@ public class PackageManagerService extends IPackageManager.Stub if (needToDeriveAbi) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi"); final boolean extractNativeLibs = !pkg.isLibrary(); - derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs); + final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> derivedAbi = + packageAbiHelper.derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs); + derivedAbi.first.applyTo(pkg); + derivedAbi.second.applyTo(pkg); Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); // Some system apps still use directory structure for native libraries @@ -11387,8 +11477,13 @@ public class PackageManagerService extends IPackageManager.Stub // structure. Try to detect abi based on directory structure. if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && pkg.applicationInfo.primaryCpuAbi == null) { - setBundledAppAbisAndRoots(pkg, pkgSetting); - setNativeLibraryPaths(pkg, sAppLib32InstallDir); + final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis( + pkg); + abis.applyTo(pkg); + abis.applyTo(pkgSetting); + final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths = + packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir); + nativeLibraryPaths.applyTo(pkg); } } else { // This is not a first boot or an upgrade, don't bother deriving the @@ -11397,7 +11492,9 @@ public class PackageManagerService extends IPackageManager.Stub pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings; pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings; - setNativeLibraryPaths(pkg, sAppLib32InstallDir); + final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths = + packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir); + nativeLibraryPaths.applyTo(pkg); if (DEBUG_ABI_SELECTION) { Slog.i(TAG, "Using ABIS and native lib paths from settings : " + @@ -11418,7 +11515,9 @@ public class PackageManagerService extends IPackageManager.Stub // ABIs we've determined above. For non-moves, the path will be updated based on the // ABIs we determined during compilation, but the path will depend on the final // package path (after the rename away from the stage path). - setNativeLibraryPaths(pkg, sAppLib32InstallDir); + final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths = + packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir); + nativeLibraryPaths.applyTo(pkg); } // This is a special case for the "system" package, where the ABI is @@ -11472,8 +11571,9 @@ public class PackageManagerService extends IPackageManager.Stub // We also do this *before* we perform dexopt on this package, so that // we can avoid redundant dexopts, and also to make sure we've got the // code and package path correct. - changedAbiCodePath = - adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg); + changedAbiCodePath = applyAdjustedAbiToSharedUser(pkgSetting.sharedUser, pkg, + packageAbiHelper.getAdjustedAbiForSharedUser( + pkgSetting.sharedUser.packages, pkg)); } if (isUnderFactoryTest && pkg.requestedPermissions.contains( @@ -12323,264 +12423,6 @@ public class PackageManagerService extends IPackageManager.Stub Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } - /** - * Derive the ABI of a non-system package located at {@code scanFile}. This information - * is derived purely on the basis of the contents of {@code scanFile} and - * {@code cpuAbiOverride}. - * - * If {@code extractLibs} is true, native libraries are extracted from the app if required. - */ - private static void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride, - boolean extractLibs) - throws PackageManagerException { - // Give ourselves some initial paths; we'll come back for another - // pass once we've determined ABI below. - setNativeLibraryPaths(pkg, sAppLib32InstallDir); - - // We shouldn't attempt to extract libs from system app when it was not updated. - if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { - extractLibs = false; - } - - final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; - final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; - - NativeLibraryHelper.Handle handle = null; - try { - handle = NativeLibraryHelper.Handle.create(pkg); - // TODO(multiArch): This can be null for apps that didn't go through the - // usual installation process. We can calculate it again, like we - // do during install time. - // - // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally - // unnecessary. - final File nativeLibraryRoot = new File(nativeLibraryRootStr); - - // Null out the abis so that they can be recalculated. - pkg.applicationInfo.primaryCpuAbi = null; - pkg.applicationInfo.secondaryCpuAbi = null; - if (isMultiArch(pkg.applicationInfo)) { - // Warn if we've set an abiOverride for multi-lib packages.. - // By definition, we need to copy both 32 and 64 bit libraries for - // such packages. - if (pkg.cpuAbiOverride != null - && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { - Slog.w(TAG, "Ignoring abiOverride for multi arch application."); - } - - int abi32 = PackageManager.NO_NATIVE_LIBRARIES; - int abi64 = PackageManager.NO_NATIVE_LIBRARIES; - if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { - if (extractLibs) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); - abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, - nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, - useIsaSpecificSubdirs); - } else { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); - abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); - } - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - } - - // Shared library native code should be in the APK zip aligned - if (abi32 >= 0 && pkg.isLibrary() && extractLibs) { - throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, - "Shared library native lib extraction not supported"); - } - - maybeThrowExceptionForMultiArchCopy( - "Error unpackaging 32 bit native libs for multiarch app.", abi32); - - if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { - if (extractLibs) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); - abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, - nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, - useIsaSpecificSubdirs); - } else { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); - abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); - } - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - } - - maybeThrowExceptionForMultiArchCopy( - "Error unpackaging 64 bit native libs for multiarch app.", abi64); - - if (abi64 >= 0) { - // Shared library native libs should be in the APK zip aligned - if (extractLibs && pkg.isLibrary()) { - throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, - "Shared library native lib extraction not supported"); - } - pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; - } - - if (abi32 >= 0) { - final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; - if (abi64 >= 0) { - if (pkg.use32bitAbi) { - pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; - pkg.applicationInfo.primaryCpuAbi = abi; - } else { - pkg.applicationInfo.secondaryCpuAbi = abi; - } - } else { - pkg.applicationInfo.primaryCpuAbi = abi; - } - } - } else { - String[] abiList = (cpuAbiOverride != null) ? - new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; - - // Enable gross and lame hacks for apps that are built with old - // SDK tools. We must scan their APKs for renderscript bitcode and - // not launch them if it's present. Don't bother checking on devices - // that don't have 64 bit support. - boolean needsRenderScriptOverride = false; - if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && - NativeLibraryHelper.hasRenderscriptBitcode(handle)) { - abiList = Build.SUPPORTED_32_BIT_ABIS; - needsRenderScriptOverride = true; - } - - final int copyRet; - if (extractLibs) { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); - copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, - nativeLibraryRoot, abiList, useIsaSpecificSubdirs); - } else { - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); - copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); - } - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); - - if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { - throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, - "Error unpackaging native libs for app, errorCode=" + copyRet); - } - - if (copyRet >= 0) { - // Shared libraries that have native libs must be multi-architecture - if (pkg.isLibrary()) { - throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, - "Shared library with native libs must be multiarch"); - } - pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; - } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { - pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; - } else if (needsRenderScriptOverride) { - pkg.applicationInfo.primaryCpuAbi = abiList[0]; - } - } - } catch (IOException ioe) { - Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); - } finally { - IoUtils.closeQuietly(handle); - } - - // Now that we've calculated the ABIs and determined if it's an internal app, - // we will go ahead and populate the nativeLibraryPath. - setNativeLibraryPaths(pkg, sAppLib32InstallDir); - } - - /** - * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. - * i.e, so that all packages can be run inside a single process if required. - * - * Optionally, callers can pass in a parsed package via {@code newPackage} in which case - * this function will either try and make the ABI for all packages in {@code packagesForUser} - * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match - * the ABI selected for {@code packagesForUser}. This variant is used when installing or - * updating a package that belongs to a shared user. - * - * NOTE: We currently only match for the primary CPU abi string. Matching the secondary - * adds unnecessary complexity. - */ - private static @Nullable List<String> adjustCpuAbisForSharedUserLPw( - Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) { - List<String> changedAbiCodePath = null; - String requiredInstructionSet = null; - if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { - requiredInstructionSet = VMRuntime.getInstructionSet( - scannedPackage.applicationInfo.primaryCpuAbi); - } - - PackageSetting requirer = null; - for (PackageSetting ps : packagesForUser) { - // If packagesForUser contains scannedPackage, we skip it. This will happen - // when scannedPackage is an update of an existing package. Without this check, - // we will never be able to change the ABI of any package belonging to a shared - // user, even if it's compatible with other packages. - if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { - if (ps.primaryCpuAbiString == null) { - continue; - } - - final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); - if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { - // We have a mismatch between instruction sets (say arm vs arm64) warn about - // this but there's not much we can do. - String errorMessage = "Instruction set mismatch, " - + ((requirer == null) ? "[caller]" : requirer) - + " requires " + requiredInstructionSet + " whereas " + ps - + " requires " + instructionSet; - Slog.w(TAG, errorMessage); - } - - if (requiredInstructionSet == null) { - requiredInstructionSet = instructionSet; - requirer = ps; - } - } - } - - if (requiredInstructionSet != null) { - String adjustedAbi; - if (requirer != null) { - // requirer != null implies that either scannedPackage was null or that scannedPackage - // did not require an ABI, in which case we have to adjust scannedPackage to match - // the ABI of the set (which is the same as requirer's ABI) - adjustedAbi = requirer.primaryCpuAbiString; - if (scannedPackage != null) { - scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; - } - } else { - // requirer == null implies that we're updating all ABIs in the set to - // match scannedPackage. - adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; - } - - for (PackageSetting ps : packagesForUser) { - if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { - if (ps.primaryCpuAbiString != null) { - continue; - } - - ps.primaryCpuAbiString = adjustedAbi; - if (ps.pkg != null && ps.pkg.applicationInfo != null && - !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { - ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; - if (DEBUG_ABI_SELECTION) { - Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi - + " (requirer=" - + (requirer != null ? requirer.pkg : "null") - + ", scannedPackage=" - + (scannedPackage != null ? scannedPackage : "null") - + ")"); - } - if (changedAbiCodePath == null) { - changedAbiCodePath = new ArrayList<>(); - } - changedAbiCodePath.add(ps.codePathString); - } - } - } - } - return changedAbiCodePath; - } - private void setUpCustomResolverActivity(PackageParser.Package pkg) { synchronized (mPackages) { mResolverReplaced = true; @@ -12632,207 +12474,6 @@ public class PackageManagerService extends IPackageManager.Stub | IntentFilter.MATCH_ADJUSTMENT_NORMAL; } - private static String calculateBundledApkRoot(final String codePathString) { - final File codePath = new File(codePathString); - final File codeRoot; - if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { - codeRoot = Environment.getRootDirectory(); - } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { - codeRoot = Environment.getOemDirectory(); - } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { - codeRoot = Environment.getVendorDirectory(); - } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) { - codeRoot = Environment.getOdmDirectory(); - } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) { - codeRoot = Environment.getProductDirectory(); - } else if (FileUtils.contains(Environment.getSystemExtDirectory(), codePath)) { - codeRoot = Environment.getSystemExtDirectory(); - } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) { - codeRoot = Environment.getOdmDirectory(); - } else { - // Unrecognized code path; take its top real segment as the apk root: - // e.g. /something/app/blah.apk => /something - try { - File f = codePath.getCanonicalFile(); - File parent = f.getParentFile(); // non-null because codePath is a file - File tmp; - while ((tmp = parent.getParentFile()) != null) { - f = parent; - parent = tmp; - } - codeRoot = f; - Slog.w(TAG, "Unrecognized code path " - + codePath + " - using " + codeRoot); - } catch (IOException e) { - // Can't canonicalize the code path -- shenanigans? - Slog.w(TAG, "Can't canonicalize code path " + codePath); - return Environment.getRootDirectory().getPath(); - } - } - return codeRoot.getPath(); - } - - /** - * Derive and set the location of native libraries for the given package, - * which varies depending on where and how the package was installed. - */ - private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) { - final ApplicationInfo info = pkg.applicationInfo; - final String codePath = pkg.codePath; - final File codeFile = new File(codePath); - final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); - - info.nativeLibraryRootDir = null; - info.nativeLibraryRootRequiresIsa = false; - info.nativeLibraryDir = null; - info.secondaryNativeLibraryDir = null; - - if (isApkFile(codeFile)) { - // Monolithic install - if (bundledApp) { - // If "/system/lib64/apkname" exists, assume that is the per-package - // native library directory to use; otherwise use "/system/lib/apkname". - final String apkRoot = calculateBundledApkRoot(info.sourceDir); - final boolean is64Bit = VMRuntime.is64BitInstructionSet( - getPrimaryInstructionSet(info)); - - // This is a bundled system app so choose the path based on the ABI. - // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this - // is just the default path. - final String apkName = deriveCodePathName(codePath); - final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; - info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, - apkName).getAbsolutePath(); - - if (info.secondaryCpuAbi != null) { - final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; - info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), - secondaryLibDir, apkName).getAbsolutePath(); - } - } else { - final String apkName = deriveCodePathName(codePath); - info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName) - .getAbsolutePath(); - } - - info.nativeLibraryRootRequiresIsa = false; - info.nativeLibraryDir = info.nativeLibraryRootDir; - } else { - // Cluster install - info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); - info.nativeLibraryRootRequiresIsa = true; - - info.nativeLibraryDir = new File(info.nativeLibraryRootDir, - getPrimaryInstructionSet(info)).getAbsolutePath(); - - if (info.secondaryCpuAbi != null) { - info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, - VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); - } - } - } - - /** - * Calculate the abis and roots for a bundled app. These can uniquely - * be determined from the contents of the system partition, i.e whether - * it contains 64 or 32 bit shared libraries etc. We do not validate any - * of this information, and instead assume that the system was built - * sensibly. - */ - private static void setBundledAppAbisAndRoots(PackageParser.Package pkg, - PackageSetting pkgSetting) { - final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); - - // If "/system/lib64/apkname" exists, assume that is the per-package - // native library directory to use; otherwise use "/system/lib/apkname". - final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); - setBundledAppAbi(pkg, apkRoot, apkName); - // pkgSetting might be null during rescan following uninstall of updates - // to a bundled app, so accommodate that possibility. The settings in - // that case will be established later from the parsed package. - // - // If the settings aren't null, sync them up with what we've just derived. - // note that apkRoot isn't stored in the package settings. - if (pkgSetting != null) { - pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; - pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; - } - } - - /** - * Deduces the ABI of a bundled app and sets the relevant fields on the - * parsed pkg object. - * - * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} - * under which system libraries are installed. - * @param apkName the name of the installed package. - */ - private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { - final File codeFile = new File(pkg.codePath); - - final boolean has64BitLibs; - final boolean has32BitLibs; - if (isApkFile(codeFile)) { - // Monolithic install - has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); - has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); - } else { - // Cluster install - final File rootDir = new File(codeFile, LIB_DIR_NAME); - if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) - && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { - final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); - has64BitLibs = (new File(rootDir, isa)).exists(); - } else { - has64BitLibs = false; - } - if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) - && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { - final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); - has32BitLibs = (new File(rootDir, isa)).exists(); - } else { - has32BitLibs = false; - } - } - - if (has64BitLibs && !has32BitLibs) { - // The package has 64 bit libs, but not 32 bit libs. Its primary - // ABI should be 64 bit. We can safely assume here that the bundled - // native libraries correspond to the most preferred ABI in the list. - - pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; - pkg.applicationInfo.secondaryCpuAbi = null; - } else if (has32BitLibs && !has64BitLibs) { - // The package has 32 bit libs but not 64 bit libs. Its primary - // ABI should be 32 bit. - - pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; - pkg.applicationInfo.secondaryCpuAbi = null; - } else if (has32BitLibs && has64BitLibs) { - // The application has both 64 and 32 bit bundled libraries. We check - // here that the app declares multiArch support, and warn if it doesn't. - // - // We will be lenient here and record both ABIs. The primary will be the - // ABI that's higher on the list, i.e, a device that's configured to prefer - // 64 bit apps will see a 64 bit primary ABI, - - if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { - Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); - } - - if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { - pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; - pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; - } else { - pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; - pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; - } - } else { - pkg.applicationInfo.primaryCpuAbi = null; - pkg.applicationInfo.secondaryCpuAbi = null; - } - } - private void killApplication(String pkgName, int appId, String reason) { killApplication(pkgName, appId, UserHandle.USER_ALL, reason); } @@ -13554,7 +13195,8 @@ public class PackageManagerService extends IPackageManager.Stub // upgrade app from instant to full; we don't allow app downgrade installed = true; } - setInstantAppForUser(pkgSetting, userId, instantApp, fullApp); + setInstantAppForUser( + getUserManagerInternal(), pkgSetting, userId, instantApp, fullApp); } if (installed) { @@ -13602,8 +13244,8 @@ public class PackageManagerService extends IPackageManager.Stub } } - static void setInstantAppForUser(PackageSetting pkgSetting, int userId, - boolean instantApp, boolean fullApp) { + static void setInstantAppForUser(UserManagerInternal userManager, PackageSetting pkgSetting, + int userId, boolean instantApp, boolean fullApp) { // no state specified; do nothing if (!instantApp && !fullApp) { return; @@ -13615,7 +13257,7 @@ public class PackageManagerService extends IPackageManager.Stub pkgSetting.setInstantApp(false /*instantApp*/, userId); } } else { - for (int currentUserId : sUserManager.getUserIds()) { + for (int currentUserId : userManager.getUserIds()) { if (instantApp && !pkgSetting.getInstantApp(currentUserId)) { pkgSetting.setInstantApp(true /*instantApp*/, currentUserId); } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) { @@ -15889,16 +15531,6 @@ public class PackageManagerService extends IPackageManager.Stub } } - private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws - PackageManagerException { - if (copyRet < 0) { - if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && - copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { - throw new PackageManagerException(copyRet, message); - } - } - } - /** * Logic to handle movement of existing installed applications. */ @@ -16025,26 +15657,6 @@ public class PackageManagerService extends IPackageManager.Stub return result; } - // Utility method that returns the relative package path with respect - // to the installation directory. Like say for /data/data/com.test-1.apk - // string com.test-1 is returned. - static String deriveCodePathName(String codePath) { - if (codePath == null) { - return null; - } - final File codeFile = new File(codePath); - final String name = codeFile.getName(); - if (codeFile.isDirectory()) { - return name; - } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { - final int lastDot = name.lastIndexOf('.'); - return name.substring(0, lastDot); - } else { - Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); - return null; - } - } - static class PackageInstalledInfo { String name; int uid; @@ -16977,7 +16589,8 @@ public class PackageManagerService extends IPackageManager.Stub final PrepareResult prepareResult; try { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage"); - prepareResult = preparePackageLI(request.args, request.installResult); + prepareResult = + preparePackageLI(request.args, request.installResult); } catch (PrepareFailure prepareFailure) { request.installResult.setError(prepareFailure.error, prepareFailure.getMessage()); @@ -17637,7 +17250,11 @@ public class PackageManagerService extends IPackageManager.Stub String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? args.abiOverride : pkg.cpuAbiOverride); final boolean extractNativeLibs = !pkg.isLibrary(); - derivePackageAbi(pkg, abiOverride, extractNativeLibs); + final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> + derivedAbi = mInjector.getAbiHelper().derivePackageAbi( + pkg, abiOverride, extractNativeLibs); + derivedAbi.first.applyTo(pkg); + derivedAbi.second.applyTo(pkg); } catch (PackageManagerException pme) { Slog.e(TAG, "Error deriving application ABI", pme); throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR, @@ -18166,10 +17783,6 @@ public class PackageManagerService extends IPackageManager.Stub } } - private static boolean isMultiArch(ApplicationInfo info) { - return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; - } - private static boolean isExternal(PackageParser.Package pkg) { return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; } @@ -18178,7 +17791,7 @@ public class PackageManagerService extends IPackageManager.Stub return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; } - private static boolean isSystemApp(PackageParser.Package pkg) { + static boolean isSystemApp(PackageParser.Package pkg) { return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; } @@ -21175,6 +20788,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 +23946,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 @@ -24506,6 +24131,12 @@ public class PackageManagerService extends IPackageManager.Stub public List<ResolveInfo> queryIntentActivities( Intent intent, int flags, int filterCallingUid, int userId) { final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver()); + return queryIntentActivities(intent, resolvedType, flags, filterCallingUid, userId); + } + + @Override + public List<ResolveInfo> queryIntentActivities( + Intent intent, String resolvedType, int flags, int filterCallingUid, int userId) { return PackageManagerService.this .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid, userId, false /*resolveForStart*/, true /*allowDynamicSplits*/); diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index 58f262c4c889..029673ffd87b 100644 --- a/services/core/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java @@ -270,7 +270,8 @@ public abstract class PackageSettingBase extends SettingBase { updateAvailable = orig.updateAvailable; } - private PackageUserState modifyUserState(int userId) { + @VisibleForTesting + PackageUserState modifyUserState(int userId) { PackageUserState state = mUserState.get(userId); if (state == null) { state = new PackageUserState(); @@ -463,6 +464,18 @@ public abstract class PackageSettingBase extends SettingBase { state.harmfulAppWarning = harmfulAppWarning; } + void setUserState(int userId, PackageUserState otherState) { + setUserState(userId, otherState.ceDataInode, otherState.enabled, otherState.installed, + otherState.stopped, otherState.notLaunched, otherState.hidden, + otherState.distractionFlags, otherState.suspended, otherState.suspendingPackage, + otherState.dialogInfo, otherState.suspendedAppExtras, + otherState.suspendedLauncherExtras, otherState.instantApp, + otherState.virtualPreload, otherState.lastDisableAppCaller, + otherState.enabledComponents, otherState.disabledComponents, + otherState.domainVerificationStatus, otherState.appLinkGeneration, + otherState.installReason, otherState.harmfulAppWarning); + } + ArraySet<String> getEnabledComponents(int userId) { return readUserState(userId).enabledComponents; } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 3bc2236a8221..4ecfbfee6e65 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -3337,7 +3337,8 @@ public final class Settings { int flags, ComponentName cn, String scheme, PatternMatcher ssp, IntentFilter.AuthorityEntry auth, PatternMatcher path, int userId) { final List<ResolveInfo> ri = - pmInternal.queryIntentActivities(intent, flags, Binder.getCallingUid(), 0); + pmInternal.queryIntentActivities( + intent, intent.getType(), flags, Binder.getCallingUid(), 0); if (PackageManagerService.DEBUG_PREFERRED) { Log.d(TAG, "Queried " + intent + " results: " + ri); } diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING index 15dc6ae36656..0101366e48b4 100644 --- a/services/core/java/com/android/server/pm/TEST_MAPPING +++ b/services/core/java/com/android/server/pm/TEST_MAPPING @@ -8,6 +8,20 @@ }, { "name": "CtsCompilationTestCases" + }, + { + "name": "FrameworksServicesTests", + "options": [ + { + "include-filter": "com.android.server.pm." + }, + { + "include-annotation": "android.platform.test.annotations.Presubmit" + }, + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] } ], "imports": [ 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/core/java/com/android/server/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java index 997178e1582b..d78aaa5f9c9d 100644 --- a/services/core/java/com/android/server/RecoverySystemService.java +++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server; +package com.android.server.recoverysystem; import android.content.Context; import android.net.LocalSocket; @@ -27,6 +27,8 @@ import android.os.RemoteException; import android.os.SystemProperties; import android.util.Slog; +import com.android.server.SystemService; + import libcore.io.IoUtils; import java.io.DataInputStream; diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 6175d4183020..7b3fbb97da56 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -130,7 +130,6 @@ cc_defaults { "android.hardware.vibrator@1.1", "android.hardware.vibrator@1.2", "android.hardware.vibrator@1.3", - "android.hardware.vibrator@1.4", "android.hardware.vr@1.0", "android.frameworks.schedulerservice@1.0", "android.frameworks.sensorservice@1.0", diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp index 372622801aa0..746610df11ae 100644 --- a/services/core/jni/com_android_server_VibratorService.cpp +++ b/services/core/jni/com_android_server_VibratorService.cpp @@ -16,7 +16,7 @@ #define LOG_TAG "VibratorService" -#include <android/hardware/vibrator/1.4/IVibrator.h> +#include <android/hardware/vibrator/1.3/IVibrator.h> #include <android/hardware/vibrator/BnVibratorCallback.h> #include <android/hardware/vibrator/IVibrator.h> #include <binder/IServiceManager.h> @@ -43,166 +43,41 @@ namespace V1_0 = android::hardware::vibrator::V1_0; namespace V1_1 = android::hardware::vibrator::V1_1; namespace V1_2 = android::hardware::vibrator::V1_2; namespace V1_3 = android::hardware::vibrator::V1_3; -namespace V1_4 = android::hardware::vibrator::V1_4; namespace aidl = android::hardware::vibrator; namespace android { static jmethodID sMethodIdOnComplete; -// TODO(b/141828236): remove HIDL 1.4 and re-write all of this code to remove -// shim -class VibratorShim : public V1_4::IVibrator { - public: - VibratorShim(const sp<aidl::IVibrator>& vib) : mVib(vib) {} - - Return<V1_0::Status> on(uint32_t timeoutMs) override { - return on_1_4(timeoutMs, nullptr); - } - - Return<V1_0::Status> off() override { - return toHidlStatus(mVib->off()); - } - - Return<bool> supportsAmplitudeControl() override { - int32_t cap = 0; - if (!mVib->getCapabilities(&cap).isOk()) return false; - if (mUnderExternalControl) { - return (cap & aidl::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0; - } else { - return (cap & aidl::IVibrator::CAP_AMPLITUDE_CONTROL) > 0; - } - } - - Return<V1_0::Status> setAmplitude(uint8_t amplitude) override { - return toHidlStatus(mVib->setAmplitude(amplitude)); - } - - Return<void> perform(V1_0::Effect effect, V1_0::EffectStrength strength, - perform_cb _hidl_cb) override { - return perform_1_4(static_cast<V1_3::Effect>(effect), strength, nullptr, _hidl_cb); - } - - Return<void> perform_1_1(V1_1::Effect_1_1 effect, V1_0::EffectStrength strength, - perform_1_1_cb _hidl_cb) override { - return perform_1_4(static_cast<V1_3::Effect>(effect), strength, nullptr, _hidl_cb); - } - - Return<void> perform_1_2(V1_2::Effect effect, V1_0::EffectStrength strength, - perform_1_2_cb _hidl_cb) override { - return perform_1_4(static_cast<V1_3::Effect>(effect), strength, nullptr, _hidl_cb); - } - - Return<bool> supportsExternalControl() override { - int32_t cap = 0; - if (!mVib->getCapabilities(&cap).isOk()) return false; - return (cap & aidl::IVibrator::CAP_EXTERNAL_CONTROL) > 0; - } - - Return<V1_0::Status> setExternalControl(bool enabled) override { - Return<V1_0::Status> status = toHidlStatus(mVib->setExternalControl(enabled)); - if (status.isOk() && status == V1_0::Status::OK) { - mUnderExternalControl = enabled; - } - return status; - } - - Return<void> perform_1_3(V1_3::Effect effect, V1_0::EffectStrength strength, - perform_1_3_cb _hidl_cb) override { - return perform_1_4(static_cast<V1_3::Effect>(effect), strength, nullptr, _hidl_cb); - } - - Return<uint32_t> getCapabilities() override { - static_assert(static_cast<int32_t>(V1_4::Capabilities::ON_COMPLETION_CALLBACK) == - static_cast<int32_t>(aidl::IVibrator::CAP_ON_CALLBACK)); - static_assert(static_cast<int32_t>(V1_4::Capabilities::PERFORM_COMPLETION_CALLBACK) == - static_cast<int32_t>(aidl::IVibrator::CAP_PERFORM_CALLBACK)); - - int32_t cap; - if (!mVib->getCapabilities(&cap).isOk()) return 0; - return (cap & (aidl::IVibrator::CAP_ON_CALLBACK | - aidl::IVibrator::CAP_PERFORM_CALLBACK)) > 0; - } - - Return<V1_0::Status> on_1_4(uint32_t timeoutMs, - const sp<V1_4::IVibratorCallback>& callback) override { - sp<aidl::IVibratorCallback> cb = callback ? new CallbackShim(callback) : nullptr; - return toHidlStatus(mVib->on(timeoutMs, cb)); - } - - Return<void> perform_1_4(V1_3::Effect effect, V1_0::EffectStrength strength, - const sp<V1_4::IVibratorCallback>& callback, - perform_1_4_cb _hidl_cb) override { - static_assert(static_cast<uint8_t>(V1_0::EffectStrength::LIGHT) == - static_cast<uint8_t>(aidl::EffectStrength::LIGHT)); - static_assert(static_cast<uint8_t>(V1_0::EffectStrength::MEDIUM) == - static_cast<uint8_t>(aidl::EffectStrength::MEDIUM)); - static_assert(static_cast<uint8_t>(V1_0::EffectStrength::STRONG) == - static_cast<uint8_t>(aidl::EffectStrength::STRONG)); - static_assert(static_cast<uint8_t>(V1_3::Effect::CLICK) == - static_cast<uint8_t>(aidl::Effect::CLICK)); - static_assert(static_cast<uint8_t>(V1_3::Effect::DOUBLE_CLICK) == - static_cast<uint8_t>(aidl::Effect::DOUBLE_CLICK)); - static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) == - static_cast<uint8_t>(aidl::Effect::TICK)); - static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) == - static_cast<uint8_t>(aidl::Effect::THUD)); - static_assert(static_cast<uint8_t>(V1_3::Effect::POP) == - static_cast<uint8_t>(aidl::Effect::POP)); - static_assert(static_cast<uint8_t>(V1_3::Effect::HEAVY_CLICK) == - static_cast<uint8_t>(aidl::Effect::HEAVY_CLICK)); - static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_1) == - static_cast<uint8_t>(aidl::Effect::RINGTONE_1)); - static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_2) == - static_cast<uint8_t>(aidl::Effect::RINGTONE_2)); - static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_15) == - static_cast<uint8_t>(aidl::Effect::RINGTONE_15)); - static_assert(static_cast<uint8_t>(V1_3::Effect::TEXTURE_TICK) == - static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK)); - - sp<aidl::IVibratorCallback> cb = callback ? new CallbackShim(callback) : nullptr; - int timeoutMs = 0; - Return<V1_0::Status> status = toHidlStatus( - mVib->perform(static_cast<aidl::Effect>(effect), - static_cast<aidl::EffectStrength>(strength), cb, &timeoutMs)); - - if (status.isOk()) { - _hidl_cb(status, timeoutMs); - return android::hardware::Status::ok(); - } else { - return android::hardware::details::StatusOf<V1_0::Status, void>(status); - } - } - private: - sp<aidl::IVibrator> mVib; - bool mUnderExternalControl = false; - - Return<V1_0::Status> toHidlStatus(const android::binder::Status& status) { - switch(status.exceptionCode()) { - using android::hardware::Status; - case Status::EX_NONE: return V1_0::Status::OK; - case Status::EX_ILLEGAL_ARGUMENT: return V1_0::Status::BAD_VALUE; - case Status::EX_UNSUPPORTED_OPERATION: return V1_0::Status::UNSUPPORTED_OPERATION; - case Status::EX_TRANSACTION_FAILED: { - return Status::fromStatusT(status.transactionError()); - } - } - return V1_0::Status::UNKNOWN_ERROR; - } - - class CallbackShim : public aidl::BnVibratorCallback { - public: - CallbackShim(const sp<V1_4::IVibratorCallback>& cb) : mCb(cb) {} - binder::Status onComplete() { - mCb->onComplete(); - return binder::Status::ok(); // oneway, local call - } - private: - sp<V1_4::IVibratorCallback> mCb; - }; -}; - -class VibratorCallback : public V1_4::IVibratorCallback { +static_assert(static_cast<uint8_t>(V1_0::EffectStrength::LIGHT) == + static_cast<uint8_t>(aidl::EffectStrength::LIGHT)); +static_assert(static_cast<uint8_t>(V1_0::EffectStrength::MEDIUM) == + static_cast<uint8_t>(aidl::EffectStrength::MEDIUM)); +static_assert(static_cast<uint8_t>(V1_0::EffectStrength::STRONG) == + static_cast<uint8_t>(aidl::EffectStrength::STRONG)); + +static_assert(static_cast<uint8_t>(V1_3::Effect::CLICK) == + static_cast<uint8_t>(aidl::Effect::CLICK)); +static_assert(static_cast<uint8_t>(V1_3::Effect::DOUBLE_CLICK) == + static_cast<uint8_t>(aidl::Effect::DOUBLE_CLICK)); +static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) == + static_cast<uint8_t>(aidl::Effect::TICK)); +static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) == + static_cast<uint8_t>(aidl::Effect::THUD)); +static_assert(static_cast<uint8_t>(V1_3::Effect::POP) == + static_cast<uint8_t>(aidl::Effect::POP)); +static_assert(static_cast<uint8_t>(V1_3::Effect::HEAVY_CLICK) == + static_cast<uint8_t>(aidl::Effect::HEAVY_CLICK)); +static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_1) == + static_cast<uint8_t>(aidl::Effect::RINGTONE_1)); +static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_2) == + static_cast<uint8_t>(aidl::Effect::RINGTONE_2)); +static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_15) == + static_cast<uint8_t>(aidl::Effect::RINGTONE_15)); +static_assert(static_cast<uint8_t>(V1_3::Effect::TEXTURE_TICK) == + static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK)); + +class VibratorCallback { public: VibratorCallback(JNIEnv *env, jobject vibration) : mVibration(MakeGlobalRefOrDie(env, vibration)) {} @@ -212,47 +87,92 @@ class VibratorCallback : public V1_4::IVibratorCallback { env->DeleteGlobalRef(mVibration); } - Return<void> onComplete() override { + void onComplete() { auto env = AndroidRuntime::getJNIEnv(); env->CallVoidMethod(mVibration, sMethodIdOnComplete); - return Void(); } private: jobject mVibration; }; +class AidlVibratorCallback : public aidl::BnVibratorCallback { + public: + AidlVibratorCallback(JNIEnv *env, jobject vibration) : + mCb(env, vibration) {} + + binder::Status onComplete() override { + mCb.onComplete(); + return binder::Status::ok(); // oneway, local call + } + + private: + VibratorCallback mCb; +}; + static constexpr int NUM_TRIES = 2; +template<class R> +inline R NoneStatus() { + using ::android::hardware::Status; + return Status::fromExceptionCode(Status::EX_NONE); +} + +template<> +inline binder::Status NoneStatus() { + using binder::Status; + return Status::fromExceptionCode(Status::EX_NONE); +} + // Creates a Return<R> with STATUS::EX_NULL_POINTER. template<class R> -inline Return<R> NullptrStatus() { +inline R NullptrStatus() { using ::android::hardware::Status; - return Return<R>{Status::fromExceptionCode(Status::EX_NULL_POINTER)}; + return Status::fromExceptionCode(Status::EX_NULL_POINTER); +} + +template<> +inline binder::Status NullptrStatus() { + using binder::Status; + return Status::fromExceptionCode(Status::EX_NULL_POINTER); +} + +template <typename I> +sp<I> getService() { + return I::getService(); +} + +template <> +sp<aidl::IVibrator> getService() { + return waitForVintfService<aidl::IVibrator>(); +} + +template <typename I> +sp<I> tryGetService() { + return I::tryGetService(); +} + +template <> +sp<aidl::IVibrator> tryGetService() { + return checkVintfService<aidl::IVibrator>(); } template <typename I> class HalWrapper { public: static std::unique_ptr<HalWrapper> Create() { - sp<aidl::IVibrator> aidlVib = waitForVintfService<aidl::IVibrator>(); - if (aidlVib) { - return std::unique_ptr<HalWrapper>(new HalWrapper(new VibratorShim(aidlVib))); - } - // Assume that if getService returns a nullptr, HAL is not available on the // device. - auto hal = I::getService(); + auto hal = getService<I>(); return hal ? std::unique_ptr<HalWrapper>(new HalWrapper(std::move(hal))) : nullptr; } // Helper used to transparently deal with the vibrator HAL becoming unavailable. template<class R, class... Args0, class... Args1> - Return<R> call(Return<R> (I::* fn)(Args0...), Args1&&... args1) { + R call(R (I::* fn)(Args0...), Args1&&... args1) { // Return<R> doesn't have a default constructor, so make a Return<R> with // STATUS::EX_NONE. - using ::android::hardware::Status; - Return<R> ret{Status::fromExceptionCode(Status::EX_NONE)}; + R ret{NoneStatus<R>()}; // Note that ret is guaranteed to be changed after this loop. for (int i = 0; i < NUM_TRIES; ++i) { @@ -266,12 +186,7 @@ class HalWrapper { ALOGE("Failed to issue command to vibrator HAL. Retrying."); // Restoring connection to the HAL. - sp<aidl::IVibrator> aidlVib = checkVintfService<aidl::IVibrator>(); - if (aidlVib) { - mHal = new VibratorShim(aidlVib); - } else { - mHal = I::tryGetService(); - } + mHal = tryGetService<I>(); } return ret; } @@ -290,7 +205,7 @@ static auto getHal() { } template<class R, class I, class... Args0, class... Args1> -Return<R> halCall(Return<R> (I::* fn)(Args0...), Args1&&... args1) { +R halCall(R (I::* fn)(Args0...), Args1&&... args1) { auto hal = getHal<I>(); return hal ? hal->call(fn, std::forward<Args1>(args1)...) : NullptrStatus<R>(); } @@ -307,110 +222,192 @@ bool isValidEffect(jlong effect) { static void vibratorInit(JNIEnv *env, jclass clazz) { - halCall(&V1_0::IVibrator::ping).isOk(); + if (auto hal = getHal<aidl::IVibrator>()) { + // IBinder::pingBinder isn't accessible as a pointer function + // but getCapabilities can serve the same purpose + int32_t cap; + hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk(); + } else { + halCall(&V1_0::IVibrator::ping).isOk(); + } } static jboolean vibratorExists(JNIEnv* /* env */, jclass /* clazz */) { - return halCall(&V1_0::IVibrator::ping).isOk() ? JNI_TRUE : JNI_FALSE; + bool ok; + + if (auto hal = getHal<aidl::IVibrator>()) { + // IBinder::pingBinder isn't accessible as a pointer function + // but getCapabilities can serve the same purpose + int32_t cap; + ok = hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk(); + } else { + ok = halCall(&V1_0::IVibrator::ping).isOk(); + } + return ok ? JNI_TRUE : JNI_FALSE; } static void vibratorOn(JNIEnv* /* env */, jclass /* clazz */, jlong timeout_ms) { - Status retStatus = halCall(&V1_0::IVibrator::on, timeout_ms).withDefault(Status::UNKNOWN_ERROR); - if (retStatus != Status::OK) { - ALOGE("vibratorOn command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus)); + if (auto hal = getHal<aidl::IVibrator>()) { + auto status = hal->call(&aidl::IVibrator::on, timeout_ms, nullptr); + if (!status.isOk()) { + ALOGE("vibratorOn command failed: %s", status.toString8().string()); + } + } else { + Status retStatus = halCall(&V1_0::IVibrator::on, timeout_ms).withDefault(Status::UNKNOWN_ERROR); + if (retStatus != Status::OK) { + ALOGE("vibratorOn command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus)); + } } } static void vibratorOff(JNIEnv* /* env */, jclass /* clazz */) { - Status retStatus = halCall(&V1_0::IVibrator::off).withDefault(Status::UNKNOWN_ERROR); - if (retStatus != Status::OK) { - ALOGE("vibratorOff command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus)); + if (auto hal = getHal<aidl::IVibrator>()) { + auto status = hal->call(&aidl::IVibrator::off); + if (!status.isOk()) { + ALOGE("vibratorOff command failed: %s", status.toString8().string()); + } + } else { + Status retStatus = halCall(&V1_0::IVibrator::off).withDefault(Status::UNKNOWN_ERROR); + if (retStatus != Status::OK) { + ALOGE("vibratorOff command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus)); + } } } static jlong vibratorSupportsAmplitudeControl(JNIEnv*, jclass) { - return halCall(&V1_0::IVibrator::supportsAmplitudeControl).withDefault(false); + if (auto hal = getHal<aidl::IVibrator>()) { + int32_t cap = 0; + if (!hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk()) { + return false; + } + return (cap & aidl::IVibrator::CAP_AMPLITUDE_CONTROL) > 0; + } else { + return halCall(&V1_0::IVibrator::supportsAmplitudeControl).withDefault(false); + } } static void vibratorSetAmplitude(JNIEnv*, jclass, jint amplitude) { - Status status = halCall(&V1_0::IVibrator::setAmplitude, static_cast<uint32_t>(amplitude)) - .withDefault(Status::UNKNOWN_ERROR); - if (status != Status::OK) { - ALOGE("Failed to set vibrator amplitude (%" PRIu32 ").", - static_cast<uint32_t>(status)); + if (auto hal = getHal<aidl::IVibrator>()) { + auto status = hal->call(&aidl::IVibrator::IVibrator::setAmplitude, amplitude); + if (!status.isOk()) { + ALOGE("Failed to set vibrator amplitude: %s", status.toString8().string()); + } + } else { + Status status = halCall(&V1_0::IVibrator::setAmplitude, static_cast<uint32_t>(amplitude)) + .withDefault(Status::UNKNOWN_ERROR); + if (status != Status::OK) { + ALOGE("Failed to set vibrator amplitude (%" PRIu32 ").", + static_cast<uint32_t>(status)); + } } } static jboolean vibratorSupportsExternalControl(JNIEnv*, jclass) { - return halCall(&V1_3::IVibrator::supportsExternalControl).withDefault(false); + if (auto hal = getHal<aidl::IVibrator>()) { + int32_t cap = 0; + if (!hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk()) { + return false; + } + return (cap & aidl::IVibrator::CAP_EXTERNAL_CONTROL) > 0; + } else { + return halCall(&V1_3::IVibrator::supportsExternalControl).withDefault(false); + } } static void vibratorSetExternalControl(JNIEnv*, jclass, jboolean enabled) { - Status status = halCall(&V1_3::IVibrator::setExternalControl, static_cast<uint32_t>(enabled)) - .withDefault(Status::UNKNOWN_ERROR); - if (status != Status::OK) { - ALOGE("Failed to set vibrator external control (%" PRIu32 ").", - static_cast<uint32_t>(status)); + if (auto hal = getHal<aidl::IVibrator>()) { + auto status = hal->call(&aidl::IVibrator::IVibrator::setExternalControl, enabled); + if (!status.isOk()) { + ALOGE("Failed to set vibrator external control: %s", status.toString8().string()); + } + } else { + Status status = halCall(&V1_3::IVibrator::setExternalControl, static_cast<uint32_t>(enabled)) + .withDefault(Status::UNKNOWN_ERROR); + if (status != Status::OK) { + ALOGE("Failed to set vibrator external control (%" PRIu32 ").", + static_cast<uint32_t>(status)); + } } } static jlong vibratorPerformEffect(JNIEnv* env, jclass, jlong effect, jlong strength, jobject vibration) { - Status status; - uint32_t lengthMs; - auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) { - status = retStatus; - lengthMs = retLengthMs; - }; - EffectStrength effectStrength(static_cast<EffectStrength>(strength)); - - Return<void> ret; - if (auto hal = getHal<V1_4::IVibrator>(); hal && isValidEffect<V1_3::Effect>(effect)) { - sp<VibratorCallback> effectCallback = new VibratorCallback(env, vibration); - ret = hal->call(&V1_4::IVibrator::perform_1_4, static_cast<V1_3::Effect>(effect), - effectStrength, effectCallback, callback); - } else if (isValidEffect<V1_0::Effect>(effect)) { - ret = halCall(&V1_0::IVibrator::perform, static_cast<V1_0::Effect>(effect), - effectStrength, callback); - } else if (isValidEffect<Effect_1_1>(effect)) { - ret = halCall(&V1_1::IVibrator::perform_1_1, static_cast<Effect_1_1>(effect), - effectStrength, callback); - } else if (isValidEffect<V1_2::Effect>(effect)) { - ret = halCall(&V1_2::IVibrator::perform_1_2, static_cast<V1_2::Effect>(effect), - effectStrength, callback); - } else if (isValidEffect<V1_3::Effect>(effect)) { - ret = halCall(&V1_3::IVibrator::perform_1_3, static_cast<V1_3::Effect>(effect), - effectStrength, callback); + if (auto hal = getHal<aidl::IVibrator>()) { + int32_t lengthMs; + sp<AidlVibratorCallback> effectCallback = new AidlVibratorCallback(env, vibration); + aidl::Effect effectType(static_cast<aidl::Effect>(strength)); + aidl::EffectStrength effectStrength(static_cast<aidl::EffectStrength>(strength)); + + auto status = hal->call(&aidl::IVibrator::perform, effectType, effectStrength, effectCallback, &lengthMs); + if (!status.isOk()) { + if (status.exceptionCode() != binder::Status::EX_UNSUPPORTED_OPERATION) { + ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32 + ": %s", static_cast<int64_t>(effect), static_cast<int32_t>(strength), status.toString8().string()); + } + return -1; + } + return lengthMs; } else { - ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")", - static_cast<int32_t>(effect)); - return -1; - } + Status status; + uint32_t lengthMs; + auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) { + status = retStatus; + lengthMs = retLengthMs; + }; + EffectStrength effectStrength(static_cast<EffectStrength>(strength)); + + Return<void> ret; + if (isValidEffect<V1_0::Effect>(effect)) { + ret = halCall(&V1_0::IVibrator::perform, static_cast<V1_0::Effect>(effect), + effectStrength, callback); + } else if (isValidEffect<Effect_1_1>(effect)) { + ret = halCall(&V1_1::IVibrator::perform_1_1, static_cast<Effect_1_1>(effect), + effectStrength, callback); + } else if (isValidEffect<V1_2::Effect>(effect)) { + ret = halCall(&V1_2::IVibrator::perform_1_2, static_cast<V1_2::Effect>(effect), + effectStrength, callback); + } else if (isValidEffect<V1_3::Effect>(effect)) { + ret = halCall(&V1_3::IVibrator::perform_1_3, static_cast<V1_3::Effect>(effect), + effectStrength, callback); + } else { + ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")", + static_cast<int32_t>(effect)); + return -1; + } - if (!ret.isOk()) { - ALOGW("Failed to perform effect (%" PRId32 ")", static_cast<int32_t>(effect)); - return -1; - } + if (!ret.isOk()) { + ALOGW("Failed to perform effect (%" PRId32 ")", static_cast<int32_t>(effect)); + return -1; + } - if (status == Status::OK) { - return lengthMs; - } else if (status != Status::UNSUPPORTED_OPERATION) { - // Don't warn on UNSUPPORTED_OPERATION, that's a normal event and just means the motor - // doesn't have a pre-defined waveform to perform for it, so we should just give the - // opportunity to fall back to the framework waveforms. - ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32 - ", error=%" PRIu32 ").", static_cast<int64_t>(effect), - static_cast<int32_t>(strength), static_cast<uint32_t>(status)); + if (status == Status::OK) { + return lengthMs; + } else if (status != Status::UNSUPPORTED_OPERATION) { + // Don't warn on UNSUPPORTED_OPERATION, that's a normal event and just means the motor + // doesn't have a pre-defined waveform to perform for it, so we should just give the + // opportunity to fall back to the framework waveforms. + ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32 + ", error=%" PRIu32 ").", static_cast<int64_t>(effect), + static_cast<int32_t>(strength), static_cast<uint32_t>(status)); + } } return -1; } static jlong vibratorGetCapabilities(JNIEnv*, jclass) { - return halCall(&V1_4::IVibrator::getCapabilities).withDefault(0); + if (auto hal = getHal<aidl::IVibrator>()) { + int32_t cap = 0; + if (!hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk()) { + return 0; + } + return cap; + } + + return 0; } static const JNINativeMethod method_table[] = { diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 16c60ca3997a..c1b7a50a8623 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -135,6 +135,7 @@ import com.android.server.policy.role.LegacyRoleResolutionPolicy; import com.android.server.power.PowerManagerService; import com.android.server.power.ShutdownThread; import com.android.server.power.ThermalManagerService; +import com.android.server.recoverysystem.RecoverySystemService; import com.android.server.restrictions.RestrictionsManagerService; import com.android.server.role.RoleManagerService; import com.android.server.rollback.RollbackManagerService; 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/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java index e9e96c9c7efb..8fd8d0461e75 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java @@ -56,6 +56,7 @@ import android.net.WifiKey; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; import android.net.wifi.WifiSsid; import android.os.Binder; import android.os.Handler; @@ -719,7 +720,7 @@ public class NetworkScoreServiceTest { @Test public void testCurrentNetworkScoreCacheFilter_invalidWifiInfo_noneSsid() throws Exception { - when(mWifiInfo.getSSID()).thenReturn(WifiSsid.NONE); + when(mWifiInfo.getSSID()).thenReturn(WifiManager.UNKNOWN_SSID); NetworkScoreService.CurrentNetworkScoreCacheFilter cacheFilter = new NetworkScoreService.CurrentNetworkScoreCacheFilter(() -> mWifiInfo); @@ -793,7 +794,7 @@ public class NetworkScoreServiceTest { List<ScanResult> invalidScanResults = Lists.newArrayList( new ScanResult(), createScanResult("", SCORED_NETWORK.networkKey.wifiKey.bssid), - createScanResult(WifiSsid.NONE, SCORED_NETWORK.networkKey.wifiKey.bssid), + createScanResult(WifiManager.UNKNOWN_SSID, SCORED_NETWORK.networkKey.wifiKey.bssid), createScanResult(SSID, null), createScanResult(SSID, INVALID_BSSID) ); diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java new file mode 100644 index 000000000000..470d4fa92833 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java @@ -0,0 +1,122 @@ +/* + * 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 com.android.server.pm; + +import android.content.pm.PackageParser; + +import com.android.internal.util.ArrayUtils; + +class PackageBuilder { + final PackageParser.Package mPkg; + + PackageBuilder(String packageName) { + mPkg = new PackageParser.Package(packageName); + } + + PackageBuilder setApplicationInfoCodePath(String codePath) { + mPkg.applicationInfo.setCodePath(codePath); + return this; + } + + PackageBuilder setApplicationInfoResourcePath(String resourcePath) { + mPkg.applicationInfo.setResourcePath(resourcePath); + return this; + } + + PackageBuilder setCodePath(String codePath) { + mPkg.codePath = codePath; + return this; + } + + PackageBuilder setBaseCodePath(String baseCodePath) { + mPkg.baseCodePath = baseCodePath; + return this; + } + + PackageBuilder addUsesStaticLibrary(String name, long version) { + mPkg.usesStaticLibraries = ArrayUtils.add(mPkg.usesStaticLibraries, name); + mPkg.usesStaticLibrariesVersions = + ArrayUtils.appendLong(mPkg.usesStaticLibrariesVersions, version); + return this; + } + + PackageBuilder setApplicationInfoNativeLibraryRootDir(String dir) { + mPkg.applicationInfo.nativeLibraryRootDir = dir; + return this; + } + + PackageBuilder setStaticSharedLib(String staticSharedLibName, long staticSharedLibVersion) { + mPkg.staticSharedLibVersion = staticSharedLibVersion; + mPkg.staticSharedLibName = staticSharedLibName; + return this; + } + + PackageBuilder setManifestPackageName(String manifestPackageName) { + mPkg.manifestPackageName = manifestPackageName; + return this; + } + + PackageBuilder setVersionCodeMajor(int versionCodeMajor) { + mPkg.mVersionCodeMajor = versionCodeMajor; + return this; + } + + PackageBuilder setVersionCode(int versionCode) { + mPkg.mVersionCode = versionCode; + return this; + } + + PackageBuilder addSplitCodePath(String splitCodePath) { + mPkg.splitCodePaths = + ArrayUtils.appendElement(String.class, mPkg.splitCodePaths, splitCodePath); + return this; + } + + PackageBuilder setApplicationInfoVolumeUuid(String volumeUuid) { + mPkg.applicationInfo.volumeUuid = volumeUuid; + return this; + } + + PackageBuilder addLibraryName(String libraryName) { + mPkg.libraryNames = ArrayUtils.add(mPkg.libraryNames, libraryName); + return this; + } + + PackageBuilder setRealPackageName(String realPackageName) { + mPkg.mRealPackage = realPackageName; + return this; + } + + PackageBuilder setCpuAbiOVerride(String cpuAbiOverride) { + mPkg.cpuAbiOverride = cpuAbiOverride; + return this; + } + + PackageBuilder addPermissionRequest(String permissionName) { + mPkg.requestedPermissions.add(permissionName); + return this; + } + + PackageParser.Package build() { + return mPkg; + } + + public PackageBuilder addApplicationInfoFlag(int flag) { + mPkg.applicationInfo.flags |= flag; + return this; + } +} diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java new file mode 100644 index 000000000000..b42cfd8be4a6 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java @@ -0,0 +1,154 @@ +/* + * 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 com.android.server.pm; + +import android.content.pm.PackageUserState; +import android.util.SparseArray; + +import java.io.File; +import java.util.List; + +class PackageSettingBuilder { + private String mName; + private String mRealName; + private String mCodePath; + private String mResourcePath; + private String mLegacyNativeLibraryPathString; + private String mPrimaryCpuAbiString; + private String mSecondaryCpuAbiString; + private String mCpuAbiOverrideString; + private long mPVersionCode; + private int mPkgFlags; + private int mPrivateFlags; + private String mParentPackageName; + private List<String> mChildPackageNames; + private int mSharedUserId; + private String[] mUsesStaticLibraries; + private long[] mUsesStaticLibrariesVersions; + private String mVolumeUuid; + private SparseArray<PackageUserState> mUserStates = new SparseArray<>(); + + public PackageSettingBuilder setName(String name) { + this.mName = name; + return this; + } + + public PackageSettingBuilder setRealName(String realName) { + this.mRealName = realName; + return this; + } + + public PackageSettingBuilder setCodePath(String codePath) { + this.mCodePath = codePath; + return this; + } + + public PackageSettingBuilder setResourcePath(String resourcePath) { + this.mResourcePath = resourcePath; + return this; + } + + public PackageSettingBuilder setLegacyNativeLibraryPathString( + String legacyNativeLibraryPathString) { + this.mLegacyNativeLibraryPathString = legacyNativeLibraryPathString; + return this; + } + + public PackageSettingBuilder setPrimaryCpuAbiString(String primaryCpuAbiString) { + this.mPrimaryCpuAbiString = primaryCpuAbiString; + return this; + } + + public PackageSettingBuilder setSecondaryCpuAbiString(String secondaryCpuAbiString) { + this.mSecondaryCpuAbiString = secondaryCpuAbiString; + return this; + } + + public PackageSettingBuilder setCpuAbiOverrideString(String cpuAbiOverrideString) { + this.mCpuAbiOverrideString = cpuAbiOverrideString; + return this; + } + + public PackageSettingBuilder setPVersionCode(long pVersionCode) { + this.mPVersionCode = pVersionCode; + return this; + } + + public PackageSettingBuilder setPkgFlags(int pkgFlags) { + this.mPkgFlags = pkgFlags; + return this; + } + + public PackageSettingBuilder setPrivateFlags(int privateFlags) { + this.mPrivateFlags = privateFlags; + return this; + } + + public PackageSettingBuilder setParentPackageName(String parentPackageName) { + this.mParentPackageName = parentPackageName; + return this; + } + + public PackageSettingBuilder setChildPackageNames(List<String> childPackageNames) { + this.mChildPackageNames = childPackageNames; + return this; + } + + public PackageSettingBuilder setSharedUserId(int sharedUserId) { + this.mSharedUserId = sharedUserId; + return this; + } + + public PackageSettingBuilder setUsesStaticLibraries(String[] usesStaticLibraries) { + this.mUsesStaticLibraries = usesStaticLibraries; + return this; + } + + public PackageSettingBuilder setUsesStaticLibrariesVersions( + long[] usesStaticLibrariesVersions) { + this.mUsesStaticLibrariesVersions = usesStaticLibrariesVersions; + return this; + } + + public PackageSettingBuilder setVolumeUuid(String volumeUuid) { + this.mVolumeUuid = volumeUuid; + return this; + } + + public PackageSettingBuilder setInstantAppUserState(int userId, boolean isInstant) { + if (mUserStates.indexOfKey(userId) < 0) { + mUserStates.put(userId, new PackageUserState()); + } + mUserStates.get(userId).instantApp = isInstant; + return this; + } + + public PackageSetting build() { + final PackageSetting packageSetting = new PackageSetting(mName, mRealName, + new File(mCodePath), new File(mResourcePath), + mLegacyNativeLibraryPathString, mPrimaryCpuAbiString, mSecondaryCpuAbiString, + mCpuAbiOverrideString, mPVersionCode, mPkgFlags, mPrivateFlags, mParentPackageName, + mChildPackageNames, mSharedUserId, mUsesStaticLibraries, + mUsesStaticLibrariesVersions); + packageSetting.volumeUuid = this.mVolumeUuid; + for (int i = 0; i < mUserStates.size(); i++) { + packageSetting.setUserState(mUserStates.keyAt(i), mUserStates.valueAt(i)); + } + return packageSetting; + + } +} diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java b/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java new file mode 100644 index 000000000000..34a3f860496a --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java @@ -0,0 +1,105 @@ +/* + * 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 com.android.server.pm; + +import android.content.pm.PackageParser; +import android.os.UserHandle; + +class ScanRequestBuilder { + private final PackageParser.Package mPkg; + private PackageParser.Package mOldPkg; + private SharedUserSetting mSharedUserSetting; + private PackageSetting mPkgSetting; + private PackageSetting mDisabledPkgSetting; + private PackageSetting mOriginalPkgSetting; + private String mRealPkgName; + private int mParseFlags; + private int mScanFlags; + private UserHandle mUser; + private boolean mIsPlatformPackage; + + ScanRequestBuilder(PackageParser.Package pkg) { + this.mPkg = pkg; + } + + public ScanRequestBuilder setOldPkg(PackageParser.Package oldPkg) { + this.mOldPkg = oldPkg; + return this; + } + + public ScanRequestBuilder setSharedUserSetting(SharedUserSetting sharedUserSetting) { + this.mSharedUserSetting = sharedUserSetting; + return this; + } + + public ScanRequestBuilder setPkgSetting(PackageSetting pkgSetting) { + this.mPkgSetting = pkgSetting; + return this; + } + + public ScanRequestBuilder setDisabledPkgSetting(PackageSetting disabledPkgSetting) { + this.mDisabledPkgSetting = disabledPkgSetting; + return this; + } + + public ScanRequestBuilder setOriginalPkgSetting(PackageSetting originalPkgSetting) { + this.mOriginalPkgSetting = originalPkgSetting; + return this; + } + + public ScanRequestBuilder setRealPkgName(String realPkgName) { + this.mRealPkgName = realPkgName; + return this; + } + + public ScanRequestBuilder setParseFlags(int parseFlags) { + this.mParseFlags = parseFlags; + return this; + } + + public ScanRequestBuilder addParseFlag(int parseFlag) { + this.mParseFlags |= parseFlag; + return this; + } + + public ScanRequestBuilder setScanFlags(int scanFlags) { + this.mScanFlags = scanFlags; + return this; + } + + public ScanRequestBuilder addScanFlag(int scanFlag) { + this.mScanFlags |= scanFlag; + return this; + } + + public ScanRequestBuilder setUser(UserHandle user) { + this.mUser = user; + return this; + } + + public ScanRequestBuilder setIsPlatformPackage(boolean isPlatformPackage) { + this.mIsPlatformPackage = isPlatformPackage; + return this; + } + + PackageManagerService.ScanRequest build() { + return new PackageManagerService.ScanRequest( + mPkg, mSharedUserSetting, mOldPkg, mPkgSetting, mDisabledPkgSetting, + mOriginalPkgSetting, mRealPkgName, mParseFlags, mScanFlags, mIsPlatformPackage, + mUser); + } +} diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java new file mode 100644 index 000000000000..dd3d8b929793 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java @@ -0,0 +1,551 @@ +/* + * 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 com.android.server.pm; + +import static android.content.pm.SharedLibraryInfo.TYPE_DYNAMIC; +import static android.content.pm.SharedLibraryInfo.TYPE_STATIC; +import static android.content.pm.SharedLibraryInfo.VERSION_UNDEFINED; + +import static com.android.server.pm.PackageManagerService.SCAN_AS_FULL_APP; +import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP; +import static com.android.server.pm.PackageManagerService.SCAN_FIRST_BOOT_OR_UPGRADE; +import static com.android.server.pm.PackageManagerService.SCAN_NEW_INSTALL; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.collection.IsArrayContainingInOrder.arrayContaining; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertNotSame; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.Mockito.when; + +import android.Manifest; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageParser; +import android.content.pm.SharedLibraryInfo; +import android.os.Environment; +import android.os.UserHandle; +import android.os.UserManagerInternal; +import android.platform.test.annotations.Presubmit; +import android.util.Pair; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.io.File; + +@RunWith(MockitoJUnitRunner.class) +@Presubmit +// TODO: shared user tests +public class ScanTests { + + private static final String DUMMY_PACKAGE_NAME = "some.app.to.test"; + + @Mock + PackageAbiHelper mMockPackageAbiHelper; + @Mock + UserManagerInternal mMockUserManager; + + @Before + public void setupDefaultUser() { + when(mMockUserManager.getUserIds()).thenReturn(new int[]{0}); + } + + @Before + public void setupDefaultAbiBehavior() throws Exception { + when(mMockPackageAbiHelper.derivePackageAbi( + any(PackageParser.Package.class), nullable(String.class), anyBoolean())) + .thenReturn(new Pair<>( + new PackageAbiHelper.Abis("derivedPrimary", "derivedSecondary"), + new PackageAbiHelper.NativeLibraryPaths( + "derivedRootDir", true, "derivedNativeDir", "derivedNativeDir2"))); + when(mMockPackageAbiHelper.getNativeLibraryPaths( + any(PackageParser.Package.class), any(File.class))) + .thenReturn(new PackageAbiHelper.NativeLibraryPaths( + "getRootDir", true, "getNativeDir", "getNativeDir2" + )); + when(mMockPackageAbiHelper.getBundledAppAbis( + any(PackageParser.Package.class))) + .thenReturn(new PackageAbiHelper.Abis("bundledPrimary", "bundledSecondary")); + } + + @Test + public void newInstallSimpleAllNominal() throws Exception { + final PackageManagerService.ScanRequest scanRequest = + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) + .addScanFlag(PackageManagerService.SCAN_NEW_INSTALL) + .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP) + .build(); + + final PackageManagerService.ScanResult scanResult = executeScan(scanRequest); + + assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, false /*isInstant*/); + assertThat(scanResult.existingSettingCopied, is(false)); + assertPathsNotDerived(scanResult); + } + + @Test + public void newInstallForAllUsers() throws Exception { + final int[] userIds = {0, 10, 11}; + when(mMockUserManager.getUserIds()).thenReturn(userIds); + + final PackageManagerService.ScanRequest scanRequest = + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) + .setRealPkgName(null) + .addScanFlag(PackageManagerService.SCAN_NEW_INSTALL) + .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP) + .build(); + final PackageManagerService.ScanResult scanResult = executeScan(scanRequest); + + for (int uid : userIds) { + assertThat(scanResult.pkgSetting.readUserState(uid).installed, is(true)); + } + } + + @Test + public void installRealPackageName() throws Exception { + final PackageManagerService.ScanRequest scanRequest = + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) + .setRealPkgName("com.package.real") + .build(); + + final PackageManagerService.ScanResult scanResult = executeScan(scanRequest); + + assertThat(scanResult.pkgSetting.realName, is("com.package.real")); + + final PackageManagerService.ScanRequest scanRequestNoRealPkg = + createBasicScanRequestBuilder( + createBasicPackage(DUMMY_PACKAGE_NAME) + .setRealPackageName("com.package.real").build()) + .build(); + + final PackageManagerService.ScanResult scanResultNoReal = executeScan(scanRequestNoRealPkg); + assertThat(scanResultNoReal.pkgSetting.realName, nullValue()); + } + + @Test + public void updateSimpleNominal() throws Exception { + when(mMockUserManager.getUserIds()).thenReturn(new int[]{0}); + + final PackageSetting pkgSetting = createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME) + .setPrimaryCpuAbiString("primaryCpuAbi") + .setSecondaryCpuAbiString("secondaryCpuAbi") + .build(); + final PackageManagerService.ScanRequest scanRequest = + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) + .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP) + .setPkgSetting(pkgSetting) + .build(); + + + final PackageManagerService.ScanResult scanResult = executeScan(scanRequest); + + assertThat(scanResult.existingSettingCopied, is(true)); + + // ensure we don't overwrite the existing pkgSetting, in case something post-scan fails + assertNotSame(pkgSetting, scanResult.pkgSetting); + + assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, false /*isInstant*/); + + assertThat(scanResult.pkgSetting.primaryCpuAbiString, is("primaryCpuAbi")); + assertThat(scanResult.pkgSetting.secondaryCpuAbiString, is("secondaryCpuAbi")); + assertThat(scanResult.pkgSetting.cpuAbiOverrideString, nullValue()); + + assertPathsNotDerived(scanResult); + } + + @Test + public void updateInstantSimpleNominal() throws Exception { + when(mMockUserManager.getUserIds()).thenReturn(new int[]{0}); + + final PackageSetting existingPkgSetting = + createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME) + .setInstantAppUserState(0, true) + .build(); + + final PackageManagerService.ScanRequest scanRequest = + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) + .setPkgSetting(existingPkgSetting) + .build(); + + + final PackageManagerService.ScanResult scanResult = executeScan(scanRequest); + + assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, true /*isInstant*/); + } + + @Test + public void installStaticSharedLibrary() throws Exception { + final PackageParser.Package pkg = createBasicPackage("static.lib.pkg.123") + .setStaticSharedLib("static.lib", 123L) + .setManifestPackageName("static.lib.pkg") + .setVersionCodeMajor(1) + .setVersionCode(234) + .setBaseCodePath("/some/path.apk") + .addSplitCodePath("/some/other/path.apk") + .build(); + + final PackageManagerService.ScanRequest scanRequest = new ScanRequestBuilder( + pkg).setUser(UserHandle.of(0)).build(); + + + final PackageManagerService.ScanResult scanResult = executeScan(scanRequest); + + assertThat(scanResult.staticSharedLibraryInfo.getPackageName(), is("static.lib.pkg.123")); + assertThat(scanResult.staticSharedLibraryInfo.getName(), is("static.lib")); + assertThat(scanResult.staticSharedLibraryInfo.getLongVersion(), is(123L)); + assertThat(scanResult.staticSharedLibraryInfo.getType(), is(TYPE_STATIC)); + assertThat(scanResult.staticSharedLibraryInfo.getDeclaringPackage().getPackageName(), + is("static.lib.pkg")); + assertThat(scanResult.staticSharedLibraryInfo.getDeclaringPackage().getLongVersionCode(), + is(pkg.getLongVersionCode())); + assertThat(scanResult.staticSharedLibraryInfo.getAllCodePaths(), + hasItems("/some/path.apk", "/some/other/path.apk")); + assertThat(scanResult.staticSharedLibraryInfo.getDependencies(), nullValue()); + assertThat(scanResult.staticSharedLibraryInfo.getDependentPackages(), empty()); + } + + @Test + public void installDynamicLibraries() throws Exception { + final PackageParser.Package pkg = createBasicPackage("dynamic.lib.pkg") + .setManifestPackageName("dynamic.lib.pkg") + .addLibraryName("liba") + .addLibraryName("libb") + .setVersionCodeMajor(1) + .setVersionCode(234) + .setBaseCodePath("/some/path.apk") + .addSplitCodePath("/some/other/path.apk") + .build(); + + final PackageManagerService.ScanRequest scanRequest = + new ScanRequestBuilder(pkg).setUser(UserHandle.of(0)).build(); + + + final PackageManagerService.ScanResult scanResult = executeScan(scanRequest); + + final SharedLibraryInfo dynamicLib0 = scanResult.dynamicSharedLibraryInfos.get(0); + assertThat(dynamicLib0.getPackageName(), is("dynamic.lib.pkg")); + assertThat(dynamicLib0.getName(), is("liba")); + assertThat(dynamicLib0.getLongVersion(), is((long) VERSION_UNDEFINED)); + assertThat(dynamicLib0.getType(), is(TYPE_DYNAMIC)); + assertThat(dynamicLib0.getDeclaringPackage().getPackageName(), is("dynamic.lib.pkg")); + assertThat(dynamicLib0.getDeclaringPackage().getLongVersionCode(), + is(pkg.getLongVersionCode())); + assertThat(dynamicLib0.getAllCodePaths(), + hasItems("/some/path.apk", "/some/other/path.apk")); + assertThat(dynamicLib0.getDependencies(), nullValue()); + assertThat(dynamicLib0.getDependentPackages(), empty()); + + final SharedLibraryInfo dynamicLib1 = scanResult.dynamicSharedLibraryInfos.get(1); + assertThat(dynamicLib1.getPackageName(), is("dynamic.lib.pkg")); + assertThat(dynamicLib1.getName(), is("libb")); + assertThat(dynamicLib1.getLongVersion(), is((long) VERSION_UNDEFINED)); + assertThat(dynamicLib1.getType(), is(TYPE_DYNAMIC)); + assertThat(dynamicLib1.getDeclaringPackage().getPackageName(), is("dynamic.lib.pkg")); + assertThat(dynamicLib1.getDeclaringPackage().getLongVersionCode(), + is(pkg.getLongVersionCode())); + assertThat(dynamicLib1.getAllCodePaths(), + hasItems("/some/path.apk", "/some/other/path.apk")); + assertThat(dynamicLib1.getDependencies(), nullValue()); + assertThat(dynamicLib1.getDependentPackages(), empty()); + } + + @Test + public void volumeUuidChangesOnUpdate() throws Exception { + final PackageSetting pkgSetting = + createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME) + .setVolumeUuid("someUuid") + .build(); + + final PackageParser.Package basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME) + .setApplicationInfoVolumeUuid("someNewUuid") + .build(); + + + final PackageManagerService.ScanResult scanResult = executeScan( + new ScanRequestBuilder(basicPackage).setPkgSetting(pkgSetting).build()); + + assertThat(scanResult.pkgSetting.volumeUuid, is("someNewUuid")); + } + + @Test + public void scanFirstBoot_derivesAbis() throws Exception { + final PackageSetting pkgSetting = + createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME).build(); + + final PackageParser.Package basicPackage = + createBasicPackage(DUMMY_PACKAGE_NAME) + .setCpuAbiOVerride("testOverride") + .build(); + + + final PackageManagerService.ScanResult scanResult = executeScan(new ScanRequestBuilder( + basicPackage) + .setPkgSetting(pkgSetting) + .addScanFlag(SCAN_FIRST_BOOT_OR_UPGRADE) + .build()); + + assertAbiAndPathssDerived(scanResult); + } + + @Test + public void scanWithOriginalPkgSetting_packageNameChanges() throws Exception { + final PackageSetting originalPkgSetting = + createBasicPackageSettingBuilder("original.package").build(); + + final PackageParser.Package basicPackage = + createBasicPackage(DUMMY_PACKAGE_NAME) + .build(); + + + final PackageManagerService.ScanResult result = + executeScan(new ScanRequestBuilder(basicPackage) + .setOriginalPkgSetting(originalPkgSetting) + .build()); + + assertThat(result.request.pkg.packageName, is("original.package")); + } + + @Test + public void updateInstant_changeToFull() throws Exception { + when(mMockUserManager.getUserIds()).thenReturn(new int[]{0}); + + final PackageSetting existingPkgSetting = + createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME) + .setInstantAppUserState(0, true) + .build(); + + final PackageManagerService.ScanRequest scanRequest = + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) + .setPkgSetting(existingPkgSetting) + .addScanFlag(SCAN_AS_FULL_APP) + .build(); + + + final PackageManagerService.ScanResult scanResult = executeScan(scanRequest); + + assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, false /*isInstant*/); + } + + @Test + public void updateFull_changeToInstant() throws Exception { + when(mMockUserManager.getUserIds()).thenReturn(new int[]{0}); + + final PackageSetting existingPkgSetting = + createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME) + .setInstantAppUserState(0, false) + .build(); + + final PackageManagerService.ScanRequest scanRequest = + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) + .setPkgSetting(existingPkgSetting) + .addScanFlag(SCAN_AS_INSTANT_APP) + .build(); + + + final PackageManagerService.ScanResult scanResult = executeScan(scanRequest); + + assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, true /*isInstant*/); + } + + @Test + public void updateSystemApp_applicationInfoFlagSet() throws Exception { + final PackageSetting existingPkgSetting = + createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME) + .setPkgFlags(ApplicationInfo.FLAG_SYSTEM) + .build(); + + final PackageManagerService.ScanRequest scanRequest = + createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build()) + .setPkgSetting(existingPkgSetting) + .setDisabledPkgSetting(existingPkgSetting) + .addScanFlag(SCAN_NEW_INSTALL) + .build(); + + final PackageManagerService.ScanResult scanResult = executeScan(scanRequest); + + assertThat(scanResult.request.pkg.applicationInfo.flags, + hasFlag(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)); + } + + @Test + public void factoryTestFlagSet() throws Exception { + final PackageParser.Package basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME) + .addPermissionRequest(Manifest.permission.FACTORY_TEST) + .build(); + + final PackageManagerService.ScanResult scanResult = PackageManagerService.scanPackageOnlyLI( + createBasicScanRequestBuilder(basicPackage).build(), + new PackageManagerService.Injector(mMockUserManager, mMockPackageAbiHelper), + true /*isUnderFactoryTest*/, + System.currentTimeMillis()); + + assertThat(scanResult.request.pkg.applicationInfo.flags, + hasFlag(ApplicationInfo.FLAG_FACTORY_TEST)); + } + + @Test + public void scanSystemApp_isOrphanedTrue() throws Exception { + final PackageParser.Package pkg = createBasicPackage(DUMMY_PACKAGE_NAME) + .addApplicationInfoFlag(ApplicationInfo.FLAG_SYSTEM) + .build(); + + final PackageManagerService.ScanRequest scanRequest = + createBasicScanRequestBuilder(pkg) + .build(); + + final PackageManagerService.ScanResult scanResult = executeScan(scanRequest); + + assertThat(scanResult.pkgSetting.isOrphaned, is(true)); + } + + private static Matcher<Integer> hasFlag(final int flag) { + return new BaseMatcher<Integer>() { + @Override public void describeTo(Description description) { + description.appendText("flags "); + } + + @Override public boolean matches(Object item) { + return ((int) item & flag) != 0; + } + + @Override + public void describeMismatch(Object item, Description mismatchDescription) { + mismatchDescription + .appendValue(item) + .appendText(" does not contain flag ") + .appendValue(flag); + } + }; + } + + private PackageManagerService.ScanResult executeScan( + PackageManagerService.ScanRequest scanRequest) throws PackageManagerException { + return PackageManagerService.scanPackageOnlyLI( + scanRequest, + new PackageManagerService.Injector(mMockUserManager, mMockPackageAbiHelper), + false /*isUnderFactoryTest*/, + System.currentTimeMillis()); + } + + private static String createResourcePath(String packageName) { + return "/data/app/" + packageName + "-randompath/base.apk"; + } + + private static String createCodePath(String packageName) { + return "/data/app/" + packageName + "-randompath"; + } + + private static PackageSettingBuilder createBasicPackageSettingBuilder(String packageName) { + return new PackageSettingBuilder() + .setName(packageName) + .setCodePath(createCodePath(packageName)) + .setResourcePath(createResourcePath(packageName)); + } + + private static ScanRequestBuilder createBasicScanRequestBuilder(PackageParser.Package pkg) { + return new ScanRequestBuilder(pkg) + .setUser(UserHandle.of(0)); + } + + + private static PackageBuilder createBasicPackage(String packageName) { + return new PackageBuilder(packageName) + .setCodePath("/data/tmp/randompath") + .setApplicationInfoCodePath(createCodePath(packageName)) + .setApplicationInfoResourcePath(createResourcePath(packageName)) + .setApplicationInfoVolumeUuid("volumeUuid") + .setBaseCodePath("/data/tmp/randompath/base.apk") + .addUsesStaticLibrary("some.static.library", 234L) + .addUsesStaticLibrary("some.other.static.library", 456L) + .setApplicationInfoNativeLibraryRootDir("/data/tmp/randompath/base.apk:/lib") + .setVersionCodeMajor(1) + .setVersionCode(2345); + } + + private static void assertBasicPackageScanResult( + PackageManagerService.ScanResult scanResult, String packageName, boolean isInstant) { + assertThat(scanResult.success, is(true)); + + final PackageSetting pkgSetting = scanResult.pkgSetting; + assertBasicPackageSetting(scanResult, packageName, isInstant, pkgSetting); + + final ApplicationInfo applicationInfo = pkgSetting.pkg.applicationInfo; + assertBasicApplicationInfo(scanResult, applicationInfo); + + } + + private static void assertBasicPackageSetting(PackageManagerService.ScanResult scanResult, + String packageName, boolean isInstant, PackageSetting pkgSetting) { + assertThat(pkgSetting.pkg.packageName, is(packageName)); + assertThat(pkgSetting.getInstantApp(0), is(isInstant)); + assertThat(pkgSetting.usesStaticLibraries, + arrayContaining("some.static.library", "some.other.static.library")); + assertThat(pkgSetting.usesStaticLibrariesVersions, is(new long[]{234L, 456L})); + assertThat(pkgSetting.pkg, is(scanResult.request.pkg)); + assertThat(pkgSetting.pkg.mExtras, is(pkgSetting)); + assertThat(pkgSetting.codePath, is(new File(createCodePath(packageName)))); + assertThat(pkgSetting.resourcePath, is(new File(createResourcePath(packageName)))); + assertThat(pkgSetting.versionCode, is(PackageInfo.composeLongVersionCode(1, 2345))); + } + + private static void assertBasicApplicationInfo(PackageManagerService.ScanResult scanResult, + ApplicationInfo applicationInfo) { + assertThat(applicationInfo.processName, is(scanResult.request.pkg.packageName)); + + final int uid = applicationInfo.uid; + assertThat(UserHandle.getUserId(uid), is(UserHandle.USER_SYSTEM)); + + final String calculatedCredentialId = Environment.getDataUserCePackageDirectory( + applicationInfo.volumeUuid, UserHandle.USER_SYSTEM, + scanResult.request.pkg.packageName).getAbsolutePath(); + assertThat(applicationInfo.credentialProtectedDataDir, is(calculatedCredentialId)); + assertThat(applicationInfo.dataDir, is(applicationInfo.credentialProtectedDataDir)); + } + + private static void assertAbiAndPathssDerived(PackageManagerService.ScanResult scanResult) { + final ApplicationInfo applicationInfo = scanResult.pkgSetting.pkg.applicationInfo; + assertThat(applicationInfo.primaryCpuAbi, is("derivedPrimary")); + assertThat(applicationInfo.secondaryCpuAbi, is("derivedSecondary")); + + assertThat(applicationInfo.nativeLibraryRootDir, is("derivedRootDir")); + assertThat(scanResult.pkgSetting.legacyNativeLibraryPathString, is("derivedRootDir")); + assertThat(applicationInfo.nativeLibraryRootRequiresIsa, is(true)); + assertThat(applicationInfo.nativeLibraryDir, is("derivedNativeDir")); + assertThat(applicationInfo.secondaryNativeLibraryDir, is("derivedNativeDir2")); + } + + private static void assertPathsNotDerived(PackageManagerService.ScanResult scanResult) { + final ApplicationInfo applicationInfo = scanResult.pkgSetting.pkg.applicationInfo; + assertThat(applicationInfo.nativeLibraryRootDir, is("getRootDir")); + assertThat(scanResult.pkgSetting.legacyNativeLibraryPathString, is("getRootDir")); + assertThat(applicationInfo.nativeLibraryRootRequiresIsa, is(true)); + assertThat(applicationInfo.nativeLibraryDir, is("getNativeDir")); + assertThat(applicationInfo.secondaryNativeLibraryDir, is("getNativeDir2")); + } +} 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/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java index d669e905e4df..58abf0051539 100644 --- a/telecomm/java/android/telecom/Conference.java +++ b/telecomm/java/android/telecom/Conference.java @@ -24,6 +24,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.SystemClock; import android.telecom.Connection.VideoProvider; +import android.telephony.Annotation.RilRadioTechnology; import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.util.ArraySet; diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index e2f5d0bba0b0..4c22ba9715b0 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -35,6 +35,7 @@ import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.SystemClock; +import android.telephony.Annotation.RilRadioTechnology; import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.util.ArraySet; diff --git a/telecomm/java/android/telecom/DisconnectCause.java b/telecomm/java/android/telecom/DisconnectCause.java index ae924645d3da..bebbbd01fd88 100644 --- a/telecomm/java/android/telecom/DisconnectCause.java +++ b/telecomm/java/android/telecom/DisconnectCause.java @@ -97,6 +97,14 @@ public final class DisconnectCause implements Parcelable { */ public static final String REASON_EMULATING_SINGLE_CALL = "EMULATING_SINGLE_CALL"; + /** + * This reason is set when a call is ended in order to place an emergency call when a + * {@link PhoneAccount} doesn't support holding an ongoing call to place an emergency call. This + * reason string should only be associated with the {@link #LOCAL} disconnect code returned from + * {@link #getCode()}. + */ + public static final String REASON_EMERGENCY_CALL_PLACED = "REASON_EMERGENCY_CALL_PLACED"; + private int mDisconnectCode; private CharSequence mDisconnectLabel; private CharSequence mDisconnectDescription; diff --git a/telephony/java/com/android/internal/telephony/GsmAlphabet.java b/telephony/common/com/android/internal/telephony/GsmAlphabet.java index 79d366037f08..79d366037f08 100644 --- a/telephony/java/com/android/internal/telephony/GsmAlphabet.java +++ b/telephony/common/com/android/internal/telephony/GsmAlphabet.java 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/Annotation.java b/telephony/java/android/telephony/Annotation.java index a884a7039d5b..72f758eba39a 100644 --- a/telephony/java/android/telephony/Annotation.java +++ b/telephony/java/android/telephony/Annotation.java @@ -469,4 +469,44 @@ public class Annotation { @Retention(RetentionPolicy.SOURCE) public @interface DataFailureCause { } + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"PRECISE_CALL_STATE_"}, + value = { + PreciseCallState.PRECISE_CALL_STATE_NOT_VALID, + PreciseCallState.PRECISE_CALL_STATE_IDLE, + PreciseCallState.PRECISE_CALL_STATE_ACTIVE, + PreciseCallState.PRECISE_CALL_STATE_HOLDING, + PreciseCallState.PRECISE_CALL_STATE_DIALING, + PreciseCallState.PRECISE_CALL_STATE_ALERTING, + PreciseCallState. PRECISE_CALL_STATE_INCOMING, + PreciseCallState.PRECISE_CALL_STATE_WAITING, + PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED, + PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING}) + public @interface PreciseCallStates {} + + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"RIL_RADIO_TECHNOLOGY_" }, value = { + ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN, + ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, + ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, + ServiceState.RIL_RADIO_TECHNOLOGY_UMTS, + ServiceState.RIL_RADIO_TECHNOLOGY_IS95A, + ServiceState.RIL_RADIO_TECHNOLOGY_IS95B, + ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT, + ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0, + ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A, + ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA, + ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA, + ServiceState.RIL_RADIO_TECHNOLOGY_HSPA, + ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B, + ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD, + ServiceState.RIL_RADIO_TECHNOLOGY_LTE, + ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP, + ServiceState.RIL_RADIO_TECHNOLOGY_GSM, + ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA, + ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN, + ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA, + ServiceState.RIL_RADIO_TECHNOLOGY_NR}) + public @interface RilRadioTechnology {} } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 4dad01f9d5c0..a0aa8928dae8 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"; @@ -1743,6 +1745,15 @@ public class CarrierConfigManager { "allow_emergency_video_calls_bool"; /** + * Flag indicating whether or not an ongoing call will be held when an outgoing emergency call + * is placed. If true, ongoing calls will be put on hold when an emergency call is placed. If + * false, placing an emergency call will trigger the disconnect of all ongoing calls before + * the emergency call is placed. + */ + public static final String KEY_ALLOW_HOLD_CALL_DURING_EMERGENCY_BOOL = + "allow_hold_call_during_emergency_bool"; + + /** * Flag indicating whether the carrier supports RCS presence indication for * User Capability Exchange (UCE). When presence is supported, the device should use the * {@link android.provider.ContactsContract.Data#CARRIER_PRESENCE} bit mask and set the @@ -3499,6 +3510,7 @@ public class CarrierConfigManager { sDefaults.putString(KEY_MMS_USER_AGENT_STRING, ""); sDefaults.putBoolean(KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL, true); sDefaults.putInt(KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT, 0); + sDefaults.putBoolean(KEY_ALLOW_HOLD_CALL_DURING_EMERGENCY_BOOL, true); sDefaults.putBoolean(KEY_USE_RCS_PRESENCE_BOOL, false); sDefaults.putBoolean(KEY_USE_RCS_SIP_OPTIONS_BOOL, false); sDefaults.putBoolean(KEY_FORCE_IMEI_BOOL, false); diff --git a/telephony/java/com/android/internal/telephony/CbGeoUtils.java b/telephony/java/android/telephony/CbGeoUtils.java index 0b73252a1e1b..f4ce6e75769c 100644 --- a/telephony/java/com/android/internal/telephony/CbGeoUtils.java +++ b/telephony/java/android/telephony/CbGeoUtils.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.android.internal.telephony; +package android.telephony; import android.annotation.NonNull; -import android.telephony.Rlog; +import android.annotation.SystemApi; import android.text.TextUtils; import java.util.ArrayList; @@ -30,8 +30,17 @@ import java.util.stream.Collectors; * The coordinates used by this utils class are latitude and longitude, but some algorithms in this * class only use them as coordinates on plane, so the calculation will be inaccurate. So don't use * this class for anything other then geo-targeting of cellbroadcast messages. + * @hide */ +@SystemApi public class CbGeoUtils { + + /** + * This class is never instantiated + * @hide + */ + private CbGeoUtils() {} + /** Geometric interface. */ public interface Geometry { /** @@ -39,27 +48,36 @@ public class CbGeoUtils { * @param p point in latitude, longitude format. * @return {@code True} if the given point is inside the geometry. */ - boolean contains(LatLng p); + boolean contains(@NonNull LatLng p); } /** * Tolerance for determining if the value is 0. If the absolute value of a value is less than * this tolerance, it will be treated as 0. + * @hide */ public static final double EPS = 1e-7; - /** The radius of earth. */ + /** + * The radius of earth. + * @hide + */ public static final int EARTH_RADIUS_METER = 6371 * 1000; private static final String TAG = "CbGeoUtils"; - /** The TLV tags of WAC, defined in ATIS-0700041 5.2.3 WAC tag coding. */ + // The TLV tags of WAC, defined in ATIS-0700041 5.2.3 WAC tag coding. + /** @hide */ public static final int GEO_FENCING_MAXIMUM_WAIT_TIME = 0x01; + /** @hide */ public static final int GEOMETRY_TYPE_POLYGON = 0x02; + /** @hide */ public static final int GEOMETRY_TYPE_CIRCLE = 0x03; - /** The identifier of geometry in the encoded string. */ + // The identifier of geometry in the encoded string. + /** @hide */ private static final String CIRCLE_SYMBOL = "circle"; + /** @hide */ private static final String POLYGON_SYMBOL = "polygon"; /** Point represent by (latitude, longitude). */ @@ -81,7 +99,8 @@ public class CbGeoUtils { * @param p the point use to calculate the subtraction result. * @return the result of this point subtract the given point {@code p}. */ - public LatLng subtract(LatLng p) { + @NonNull + public LatLng subtract(@NonNull LatLng p) { return new LatLng(lat - p.lat, lng - p.lng); } @@ -90,7 +109,7 @@ public class CbGeoUtils { * @param p the point use to calculate the distance. * @return the distance in meter. */ - public double distance(LatLng p) { + public double distance(@NonNull LatLng p) { double dlat = Math.sin(0.5 * Math.toRadians(lat - p.lat)); double dlng = Math.sin(0.5 * Math.toRadians(lng - p.lng)); double x = dlat * dlat @@ -106,6 +125,7 @@ public class CbGeoUtils { /** * The class represents a simple polygon with at least 3 points. + * @hide */ public static class Polygon implements Geometry { /** @@ -239,7 +259,10 @@ public class CbGeoUtils { } } - /** The class represents a circle. */ + /** + * The class represents a circle. + * @hide + */ public static class Circle implements Geometry { private final LatLng mCenter; private final double mRadiusMeter; @@ -266,6 +289,7 @@ public class CbGeoUtils { /** * Parse the geometries from the encoded string {@code str}. The string must follow the * geometry encoding specified by {@link android.provider.Telephony.CellBroadcasts#GEOMETRIES}. + * @hide */ @NonNull public static List<Geometry> parseGeometriesFromString(@NonNull String str) { @@ -297,6 +321,7 @@ public class CbGeoUtils { * * @param geometries the list of geometry objects need to be encoded. * @return the encoded string. + * @hide */ @NonNull public static String encodeGeometriesToString(List<Geometry> geometries) { @@ -313,6 +338,7 @@ public class CbGeoUtils { * {@link android.provider.Telephony.CellBroadcasts#GEOMETRIES}. * @param geometry the geometry object need to be encoded. * @return the encoded string. + * @hide */ @NonNull private static String encodeGeometryToString(@NonNull Geometry geometry) { @@ -351,6 +377,7 @@ public class CbGeoUtils { * * @param str encoded lat/lng string. * @Return {@link LatLng} object. + * @hide */ @NonNull public static LatLng parseLatLngFromString(@NonNull String str) { @@ -361,6 +388,7 @@ public class CbGeoUtils { /** * @Return the sign of the given value {@code value} with the specified tolerance. Return 1 * means the sign is positive, -1 means negative, 0 means the value will be treated as 0. + * @hide */ public static int sign(double value) { if (value > EPS) return 1; diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java index 85110c22aa18..04ec4b6949af 100644 --- a/telephony/java/android/telephony/DisconnectCause.java +++ b/telephony/java/android/telephony/DisconnectCause.java @@ -354,6 +354,12 @@ public final class DisconnectCause { */ public static final int WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION = 79; + /** + * Indicates that an emergency call was placed, which caused the existing connection to be + * hung up. + */ + public static final int OUTGOING_EMERGENCY_CALL_PLACED = 80; + //********************************************************************************************* // When adding a disconnect type: // 1) Update toString() with the newly added disconnect type. @@ -528,6 +534,8 @@ public final class DisconnectCause { return "EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE"; case WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION: return "WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION"; + case OUTGOING_EMERGENCY_CALL_PLACED: + return "OUTGOING_EMERGENCY_CALL_PLACED"; default: return "INVALID: " + cause; } diff --git a/telephony/java/android/telephony/ImsiEncryptionInfo.java b/telephony/java/android/telephony/ImsiEncryptionInfo.java index ef2f121ba01b..75a79d62d2aa 100644 --- a/telephony/java/android/telephony/ImsiEncryptionInfo.java +++ b/telephony/java/android/telephony/ImsiEncryptionInfo.java @@ -15,9 +15,11 @@ */ package android.telephony; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; -import java.util.Date; import android.util.Log; import java.security.KeyFactory; @@ -25,18 +27,18 @@ import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; +import java.util.Date; /** * Class to represent information sent by the carrier, which will be used to encrypt * the IMSI + IMPI. The ecryption is being done by WLAN, and the modem. - * * @hide */ +@SystemApi public final class ImsiEncryptionInfo implements Parcelable { private static final String LOG_TAG = "ImsiEncryptionInfo"; - private final String mcc; private final String mnc; private final PublicKey publicKey; @@ -45,11 +47,13 @@ public final class ImsiEncryptionInfo implements Parcelable { //Date-Time in UTC when the key will expire. private final Date expirationTime; + /** @hide */ public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier, byte[] key, Date expirationTime) { this(mcc, mnc, keyType, keyIdentifier, makeKeyObject(key), expirationTime); } + /** @hide */ public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier, PublicKey publicKey, Date expirationTime) { // todo need to validate that ImsiEncryptionInfo is being created with the correct params. @@ -63,6 +67,7 @@ public final class ImsiEncryptionInfo implements Parcelable { this.expirationTime = expirationTime; } + /** @hide */ public ImsiEncryptionInfo(Parcel in) { int length = in.readInt(); byte b[] = new byte[length]; @@ -75,26 +80,40 @@ public final class ImsiEncryptionInfo implements Parcelable { expirationTime = new Date(in.readLong()); } + /** @hide */ public String getMnc() { return this.mnc; } + /** @hide */ public String getMcc() { return this.mcc; } + /** + * Returns key identifier, a string that helps the authentication server to locate the + * private key to decrypt the permanent identity, or {@code null} when uavailable. + */ + @Nullable public String getKeyIdentifier() { return this.keyIdentifier; } + /** @hide */ public int getKeyType() { return this.keyType; } + /** + * Returns the carrier public key that is used for the IMSI encryption, + * or {@code null} when uavailable. + */ + @Nullable public PublicKey getPublicKey() { return this.publicKey; } + /** @hide */ public Date getExpirationTime() { return this.expirationTime; } @@ -115,7 +134,7 @@ public final class ImsiEncryptionInfo implements Parcelable { return 0; } - public static final @android.annotation.NonNull Parcelable.Creator<ImsiEncryptionInfo> CREATOR = + public static final @NonNull Parcelable.Creator<ImsiEncryptionInfo> CREATOR = new Parcelable.Creator<ImsiEncryptionInfo>() { @Override public ImsiEncryptionInfo createFromParcel(Parcel in) { @@ -129,7 +148,7 @@ public final class ImsiEncryptionInfo implements Parcelable { }; @Override - public void writeToParcel(Parcel dest, int flags) { + public void writeToParcel(@NonNull Parcel dest, int flags) { byte[] b = publicKey.getEncoded(); dest.writeInt(b.length); dest.writeByteArray(b); diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java index f929649453b9..9f75332c4a03 100644 --- a/telephony/java/android/telephony/PreciseCallState.java +++ b/telephony/java/android/telephony/PreciseCallState.java @@ -23,6 +23,7 @@ import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Annotation.PreciseCallStates; import android.telephony.DisconnectCause; import android.telephony.PreciseDisconnectCause; @@ -48,22 +49,6 @@ import java.util.Objects; @SystemApi public final class PreciseCallState implements Parcelable { - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = {"PRECISE_CALL_STATE_"}, - value = { - PRECISE_CALL_STATE_NOT_VALID, - PRECISE_CALL_STATE_IDLE, - PRECISE_CALL_STATE_ACTIVE, - PRECISE_CALL_STATE_HOLDING, - PRECISE_CALL_STATE_DIALING, - PRECISE_CALL_STATE_ALERTING, - PRECISE_CALL_STATE_INCOMING, - PRECISE_CALL_STATE_WAITING, - PRECISE_CALL_STATE_DISCONNECTED, - PRECISE_CALL_STATE_DISCONNECTING}) - public @interface State {} - /** Call state is not valid (Not received a call state). */ public static final int PRECISE_CALL_STATE_NOT_VALID = -1; /** Call state: No activity. */ @@ -85,9 +70,9 @@ public final class PreciseCallState implements Parcelable { /** Call state: Disconnecting. */ public static final int PRECISE_CALL_STATE_DISCONNECTING = 8; - private @State int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID; - private @State int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID; - private @State int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID; + private @PreciseCallStates int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID; + private @PreciseCallStates int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID; + private @PreciseCallStates int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID; private int mDisconnectCause = DisconnectCause.NOT_VALID; private int mPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID; @@ -97,8 +82,9 @@ public final class PreciseCallState implements Parcelable { * @hide */ @UnsupportedAppUsage - public PreciseCallState(@State int ringingCall, @State int foregroundCall, - @State int backgroundCall, int disconnectCause, + public PreciseCallState(@PreciseCallStates int ringingCall, + @PreciseCallStates int foregroundCall, + @PreciseCallStates int backgroundCall, int disconnectCause, int preciseDisconnectCause) { mRingingCallState = ringingCall; mForegroundCallState = foregroundCall; @@ -131,21 +117,21 @@ public final class PreciseCallState implements Parcelable { /** * Returns the precise ringing call state. */ - public @State int getRingingCallState() { + public @PreciseCallStates int getRingingCallState() { return mRingingCallState; } /** * Returns the precise foreground call state. */ - public @State int getForegroundCallState() { + public @PreciseCallStates int getForegroundCallState() { return mForegroundCallState; } /** * Returns the precise background call state. */ - public @State int getBackgroundCallState() { + public @PreciseCallStates int getBackgroundCallState() { return mBackgroundCallState; } diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 3fd8990ffc9a..1e601cf3de5f 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -30,6 +30,7 @@ import android.os.Parcelable; import android.telephony.AccessNetworkConstants.AccessNetworkType; import android.telephony.AccessNetworkConstants.TransportType; import android.telephony.Annotation.NetworkType; +import android.telephony.Annotation.RilRadioTechnology; import android.telephony.NetworkRegistrationInfo.Domain; import android.telephony.NetworkRegistrationInfo.NRState; import android.text.TextUtils; @@ -155,32 +156,6 @@ public class ServiceState implements Parcelable { */ public static final int DUPLEX_MODE_TDD = 2; - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = { "RIL_RADIO_TECHNOLOGY_" }, - value = { - RIL_RADIO_TECHNOLOGY_UNKNOWN, - RIL_RADIO_TECHNOLOGY_GPRS, - RIL_RADIO_TECHNOLOGY_EDGE, - RIL_RADIO_TECHNOLOGY_UMTS, - RIL_RADIO_TECHNOLOGY_IS95A, - RIL_RADIO_TECHNOLOGY_IS95B, - RIL_RADIO_TECHNOLOGY_1xRTT, - RIL_RADIO_TECHNOLOGY_EVDO_0, - RIL_RADIO_TECHNOLOGY_EVDO_A, - RIL_RADIO_TECHNOLOGY_HSDPA, - RIL_RADIO_TECHNOLOGY_HSUPA, - RIL_RADIO_TECHNOLOGY_HSPA, - RIL_RADIO_TECHNOLOGY_EVDO_B, - RIL_RADIO_TECHNOLOGY_EHRPD, - RIL_RADIO_TECHNOLOGY_LTE, - RIL_RADIO_TECHNOLOGY_HSPAP, - RIL_RADIO_TECHNOLOGY_GSM, - RIL_RADIO_TECHNOLOGY_TD_SCDMA, - RIL_RADIO_TECHNOLOGY_IWLAN, - RIL_RADIO_TECHNOLOGY_LTE_CA, - RIL_RADIO_TECHNOLOGY_NR}) - public @interface RilRadioTechnology {} /** * Available radio technologies for GSM, UMTS and CDMA. * Duplicates the constants from hardware/radio/include/ril.h diff --git a/telephony/java/android/telephony/SmsCbLocation.java b/telephony/java/android/telephony/SmsCbLocation.java index adf7154b4e07..663e8e25a115 100644 --- a/telephony/java/android/telephony/SmsCbLocation.java +++ b/telephony/java/android/telephony/SmsCbLocation.java @@ -65,9 +65,12 @@ public final class SmsCbLocation implements Parcelable { /** * Construct a location object for the PLMN, LAC, and Cell ID. This class is immutable, so * the same object can be reused for multiple broadcasts. - * @hide + * + * @param plmn the MCC/MNC of the network + * @param lac the GSM location area code, or UMTS service area code + * @param cid the GSM or UMTS cell ID */ - public SmsCbLocation(String plmn, int lac, int cid) { + public SmsCbLocation(@NonNull String plmn, int lac, int cid) { mPlmn = plmn; mLac = lac; mCid = cid; diff --git a/telephony/java/android/telephony/SmsCbMessage.java b/telephony/java/android/telephony/SmsCbMessage.java index dc991b9a3ea7..737ead1f8131 100644 --- a/telephony/java/android/telephony/SmsCbMessage.java +++ b/telephony/java/android/telephony/SmsCbMessage.java @@ -25,9 +25,7 @@ import android.database.Cursor; import android.os.Parcel; import android.os.Parcelable; import android.provider.Telephony.CellBroadcasts; - -import com.android.internal.telephony.CbGeoUtils; -import com.android.internal.telephony.CbGeoUtils.Geometry; +import android.telephony.CbGeoUtils.Geometry; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -140,8 +138,8 @@ public final class SmsCbMessage implements Parcelable { public @interface MessagePriority {} /** - * ATIS-0700041 Section 5.2.8 WAC Geo-Fencing Maximum Wait Time Table 12. - * @hide + * Integer indicating that the maximum wait time is not set. + * Based on ATIS-0700041 Section 5.2.8 WAC Geo-Fencing Maximum Wait Time Table 12. */ public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255; @@ -211,6 +209,7 @@ public final class SmsCbMessage implements Parcelable { /** * Create a new SmsCbMessage with the specified data. + * @hide */ public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber, @NonNull SmsCbLocation location, int serviceCategory, @Nullable String language, @@ -223,14 +222,14 @@ public final class SmsCbMessage implements Parcelable { } /** - * Create a new {@link SmsCbMessage} with the warning area coordinates information. - * @hide + * Create a new {@link SmsCbMessage} with the specified data, including warning area + * coordinates information. */ public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber, - SmsCbLocation location, int serviceCategory, String language, String body, - int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo, - int maximumWaitTimeSec, List<Geometry> geometries, long receivedTimeMillis, - int slotIndex) { + @NonNull SmsCbLocation location, int serviceCategory, @Nullable String language, + @Nullable String body, int priority, @Nullable SmsCbEtwsInfo etwsWarningInfo, + @Nullable SmsCbCmasInfo cmasWarningInfo, int maximumWaitTimeSec, + @Nullable List<Geometry> geometries, long receivedTimeMillis, int slotIndex) { mMessageFormat = messageFormat; mGeographicalScope = geographicalScope; mSerialNumber = serialNumber; @@ -414,9 +413,8 @@ public final class SmsCbMessage implements Parcelable { /** * Get the Geo-Fencing Maximum Wait Time. * @return the time in second. - * @hide */ - public int getMaximumWaitingTime() { + public int getMaximumWaitingDuration() { return mMaximumWaitTimeSec; } 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..3c890a18e344 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; @@ -60,11 +61,10 @@ import android.telephony.euicc.EuiccManager; import android.telephony.ims.ImsMmTelManager; import android.util.DisplayMetrics; import android.util.Log; +import android.util.Pair; -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; @@ -77,6 +77,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; @@ -911,6 +912,11 @@ public class SubscriptionManager { private final Context mContext; private volatile INetworkPolicyManager mNetworkPolicy; + // Cache of Resource that has been created in getResourcesForSubId. Key is a Pair containing + // the Context and subId. + private static final Map<Pair<Context, Integer>, Resources> sResourcesCache = + new ConcurrentHashMap<>(); + /** * A listener class for monitoring changes to {@link SubscriptionInfo} records. * <p> @@ -931,20 +937,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 +963,7 @@ public class SubscriptionManager { * @hide */ public OnSubscriptionsChangedListener(Looper looper) { - mHandler = new OnSubscriptionsChangedListenerHandler(looper); + mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler(looper)); } /** @@ -965,18 +975,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 +1016,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 +1040,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 +1070,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 +1078,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 +1104,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 +1130,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); } } @@ -2351,8 +2311,20 @@ public class SubscriptionManager { * @return Resources associated with Subscription. * @hide */ + @NonNull public static Resources getResourcesForSubId(Context context, int subId, boolean useRootLocale) { + // Check if resources for this context and subId already exist in the resource cache. + // Resources that use the root locale are not cached. + Pair<Context, Integer> cacheKey = null; + if (isValidSubscriptionId(subId) && !useRootLocale) { + cacheKey = Pair.create(context, subId); + if (sResourcesCache.containsKey(cacheKey)) { + // Cache hit. Use cached Resources. + return sResourcesCache.get(cacheKey); + } + } + final SubscriptionInfo subInfo = SubscriptionManager.from(context).getActiveSubscriptionInfo(subId); @@ -2372,7 +2344,13 @@ public class SubscriptionManager { DisplayMetrics metrics = context.getResources().getDisplayMetrics(); DisplayMetrics newMetrics = new DisplayMetrics(); newMetrics.setTo(metrics); - return new Resources(context.getResources().getAssets(), newMetrics, newConfig); + Resources res = new Resources(context.getResources().getAssets(), newMetrics, newConfig); + + if (cacheKey != null) { + // Save the newly created Resources in the resource cache. + sResourcesCache.put(cacheKey, res); + } + return res; } /** diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 55212cd969f0..e99465d58764 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -200,12 +200,29 @@ public class TelephonyManager { /** @hide */ static public final int OTASP_SIM_UNPROVISIONED = 5; - /** @hide */ + /** + * Used in carrier Wi-Fi for IMSI + IMPI encryption, this indicates a public key that's + * available for use in ePDG links. + * + * @hide + */ + @SystemApi static public final int KEY_TYPE_EPDG = 1; - /** @hide */ + /** + * Used in carrier Wi-Fi for IMSI + IMPI encryption, this indicates a public key that's + * available for use in WLAN links. + * + * @hide + */ + @SystemApi static public final int KEY_TYPE_WLAN = 2; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"KEY_TYPE_"}, value = {KEY_TYPE_EPDG, KEY_TYPE_WLAN}) + public @interface KeyType {} + /** * No Single Radio Voice Call Continuity (SRVCC) handover is active. * See TS 23.216 for more information. @@ -3814,25 +3831,27 @@ public class TelephonyManager { } /** - * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI. - * This includes the public key and the key identifier. For multi-sim devices, if no subId - * has been specified, we will return the value for the dafault data sim. - * Return null if it is unavailable. + * Returns carrier specific information that will be used to encrypt the IMSI and IMPI, + * including the public key and the key identifier; or {@code null} if not available. * <p> - * Requires Permission: - * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} - * @param keyType whether the key is being used for wlan or epdg. Valid key types are - * {@link TelephonyManager#KEY_TYPE_EPDG} or - * {@link TelephonyManager#KEY_TYPE_WLAN}. + * For a multi-sim device, the dafault data sim is used if not specified. + * <p> + * Requires Permission: READ_PRIVILEGED_PHONE_STATE. + * + * @param keyType whether the key is being used for EPDG or WLAN. Valid values are + * {@link #KEY_TYPE_EPDG} or {@link #KEY_TYPE_WLAN}. * @return ImsiEncryptionInfo Carrier specific information that will be used to encrypt the * IMSI and IMPI. This includes the public key and the key identifier. This information - * will be stored in the device keystore. The system will return a null when no key was - * found, and the carrier does not require a key. The system will throw - * IllegalArgumentException when an invalid key is sent or when key is required but + * will be stored in the device keystore. {@code null} will be returned when no key is + * found, and the carrier does not require a key. + * @throws IllegalArgumentException when an invalid key is found or when key is required but * not found. * @hide */ - public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType) { + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + @SystemApi + @Nullable + public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(@KeyType int keyType) { try { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) { @@ -3860,14 +3879,21 @@ public class TelephonyManager { } /** - * Resets the Carrier Keys in the database. This involves 2 steps: + * Resets the carrier keys used to encrypt the IMSI and IMPI. + * <p> + * This involves 2 steps: * 1. Delete the keys from the database. * 2. Send an intent to download new Certificates. * <p> - * Requires Permission: - * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} + * For a multi-sim device, the dafault data sim is used if not specified. + * <p> + * Requires Permission: MODIFY_PHONE_STATE. + * + * @see #getCarrierInfoForImsiEncryption * @hide */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @SystemApi public void resetCarrierKeysForImsiEncryption() { try { IPhoneSubInfo info = getSubscriberInfo(); @@ -3894,7 +3920,7 @@ public class TelephonyManager { * @return true if the digit at position keyType is 1, else false. * @hide */ - private static boolean isKeyEnabled(int keyAvailability, int keyType) { + private static boolean isKeyEnabled(int keyAvailability, @KeyType int keyType) { int returnValue = (keyAvailability >> (keyType - 1)) & 1; return (returnValue == 1) ? true : false; } @@ -3903,7 +3929,7 @@ public class TelephonyManager { * If Carrier requires Imsi to be encrypted. * @hide */ - private boolean isImsiEncryptionRequired(int subId, int keyType) { + private boolean isImsiEncryptionRequired(int subId, @KeyType int keyType) { CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); if (configManager == null) { @@ -7673,8 +7699,8 @@ public class TelephonyManager { */ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @SystemApi - public boolean isTetherApnRequired() { - return isTetherApnRequired(getSubId(SubscriptionManager.getActiveDataSubscriptionId())); + public boolean isTetheringApnRequired() { + return isTetheringApnRequired(getSubId(SubscriptionManager.getActiveDataSubscriptionId())); } /** @@ -7684,11 +7710,11 @@ public class TelephonyManager { * @return {@code true} if DUN APN is required for tethering. * @hide */ - public boolean isTetherApnRequired(int subId) { + public boolean isTetheringApnRequired(int subId) { try { ITelephony telephony = getITelephony(); if (telephony != null) - return telephony.isTetherApnRequiredForSubscriber(subId); + return telephony.isTetheringApnRequiredForSubscriber(subId); } catch (RemoteException ex) { Rlog.e(TAG, "hasMatchedTetherApnSetting RemoteException", ex); } catch (NullPointerException ex) { @@ -8806,7 +8832,10 @@ public class TelephonyManager { @Deprecated public boolean isTtyModeSupported() { try { - TelecomManager telecomManager = TelecomManager.from(mContext); + TelecomManager telecomManager = null; + if (mContext != null) { + telecomManager = mContext.getSystemService(TelecomManager.class); + } if (telecomManager != null) { return telecomManager.isTtySupported(); } diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java index eb0e2f7b8786..5fd0af564d34 100644 --- a/telephony/java/android/telephony/ims/ImsMmTelManager.java +++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java @@ -979,25 +979,25 @@ public class ImsMmTelManager implements RegistrationManager { /** * Get the status of the MmTel Feature registered on this subscription. + * @param executor The executor that will be used to call the callback. * @param callback A callback containing an Integer describing the current state of the * MmTel feature, Which will be one of the following: * {@link ImsFeature#STATE_UNAVAILABLE}, * {@link ImsFeature#STATE_INITIALIZING}, * {@link ImsFeature#STATE_READY}. Will be called using the executor * specified when the service state has been retrieved from the IMS service. - * @param executor The executor that will be used to call the callback. * @throws ImsException if the IMS service associated with this subscription is not available or * the IMS service is not available. */ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public void getFeatureState(@NonNull @ImsFeature.ImsState Consumer<Integer> callback, - @NonNull @CallbackExecutor Executor executor) throws ImsException { - if (callback == null) { - throw new IllegalArgumentException("Must include a non-null Consumer."); - } + public void getFeatureState(@NonNull @CallbackExecutor Executor executor, + @NonNull @ImsFeature.ImsState Consumer<Integer> callback) throws ImsException { if (executor == null) { throw new IllegalArgumentException("Must include a non-null Executor."); } + if (callback == null) { + throw new IllegalArgumentException("Must include a non-null Consumer."); + } try { getITelephony().getImsMmTelFeatureState(mSubId, new IIntegerConsumer.Stub() { @Override diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java index 119f890bcb7b..e96d082ca953 100644 --- a/telephony/java/android/telephony/ims/feature/RcsFeature.java +++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java @@ -199,12 +199,19 @@ public class RcsFeature extends ImsFeature { /** @hide*/ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = "CAPABILITY_TYPE_", flag = true, value = { + CAPABILITY_TYPE_NONE, CAPABILITY_TYPE_OPTIONS_UCE, CAPABILITY_TYPE_PRESENCE_UCE }) public @interface RcsImsCapabilityFlag {} /** + * Undefined capability type for initialization + * @hide + */ + public static final int CAPABILITY_TYPE_NONE = 0; + + /** * This carrier supports User Capability Exchange using SIP OPTIONS as defined by the * framework. If set, the RcsFeature should support capability exchange using SIP OPTIONS. * If not set, this RcsFeature should not service capability requests. diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index b502ee711107..2f18049e7e71 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -819,7 +819,7 @@ interface ITelephony { * @return {@code true} if DUN APN is required for tethering. * @hide */ - boolean isTetherApnRequiredForSubscriber(int subId); + boolean isTetheringApnRequiredForSubscriber(int subId); /** * Enables framework IMS and triggers IMS Registration. diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java index c3d490a6d5cf..5766287d6691 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java @@ -25,17 +25,17 @@ import static android.telephony.SmsCbEtwsInfo.ETWS_WARNING_TYPE_TSUNAMI; import android.annotation.NonNull; import android.content.Context; import android.content.res.Resources; +import android.telephony.CbGeoUtils; +import android.telephony.CbGeoUtils.Circle; +import android.telephony.CbGeoUtils.Geometry; +import android.telephony.CbGeoUtils.LatLng; +import android.telephony.CbGeoUtils.Polygon; import android.telephony.SmsCbLocation; import android.telephony.SmsCbMessage; import android.util.Pair; import android.util.Slog; import com.android.internal.R; -import com.android.internal.telephony.CbGeoUtils; -import com.android.internal.telephony.CbGeoUtils.Circle; -import com.android.internal.telephony.CbGeoUtils.Geometry; -import com.android.internal.telephony.CbGeoUtils.LatLng; -import com.android.internal.telephony.CbGeoUtils.Polygon; import com.android.internal.telephony.GsmAlphabet; import com.android.internal.telephony.SmsConstants; import com.android.internal.telephony.gsm.GsmSmsCbMessage.GeoFencingTriggerMessage.CellBroadcastIdentity; 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/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java index 727684eca7ea..1de6260f3719 100644 --- a/test-mock/src/android/test/mock/MockContext.java +++ b/test-mock/src/android/test/mock/MockContext.java @@ -765,6 +765,12 @@ public class MockContext extends Context { /** {@hide} */ @Override + public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) { + throw new UnsupportedOperationException(); + } + + /** {@hide} */ + @Override public int getUserId() { throw new UnsupportedOperationException(); } 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..aad2f3da40f2 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() { @@ -438,7 +461,7 @@ public class ConnectivityServiceTest { } // Bring up a network that we can use to send messages to ConnectivityService. - ConditionVariable cv = waitForConnectivityBroadcasts(1); + ConditionVariable cv = registerConnectivityBroadcast(1); mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mWiFiNetworkAgent.connect(false); waitFor(cv); @@ -458,7 +481,7 @@ public class ConnectivityServiceTest { @Ignore public void verifyThatNotWaitingForIdleCausesRaceConditions() throws Exception { // Bring up a network that we can use to send messages to ConnectivityService. - ConditionVariable cv = waitForConnectivityBroadcasts(1); + ConditionVariable cv = registerConnectivityBroadcast(1); mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mWiFiNetworkAgent.connect(false); waitFor(cv); @@ -1227,17 +1250,26 @@ public class ConnectivityServiceTest { * Return a ConditionVariable that opens when {@code count} numbers of CONNECTIVITY_ACTION * broadcasts are received. */ - private ConditionVariable waitForConnectivityBroadcasts(final int count) { + private ConditionVariable registerConnectivityBroadcast(final int count) { + return registerConnectivityBroadcastThat(count, intent -> true); + } + + private ConditionVariable registerConnectivityBroadcastThat(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 = registerConnectivityBroadcastThat(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 = registerConnectivityBroadcastThat(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 = registerConnectivityBroadcast(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 = registerConnectivityBroadcastThat(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 = registerConnectivityBroadcastThat(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 = registerConnectivityBroadcastThat(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); @@ -1265,7 +1366,7 @@ public class ConnectivityServiceTest { assertNull(mCm.getActiveNetworkInfo()); assertNull(mCm.getActiveNetwork()); // Test bringing up validated cellular. - ConditionVariable cv = waitForConnectivityBroadcasts(1); + ConditionVariable cv = registerConnectivityBroadcast(1); mCellNetworkAgent.connect(true); waitFor(cv); verifyActiveNetwork(TRANSPORT_CELLULAR); @@ -1275,7 +1376,7 @@ public class ConnectivityServiceTest { assertTrue(mCm.getAllNetworks()[0].equals(mWiFiNetworkAgent.getNetwork()) || mCm.getAllNetworks()[1].equals(mWiFiNetworkAgent.getNetwork())); // Test bringing up validated WiFi. - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); mWiFiNetworkAgent.connect(true); waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); @@ -1292,7 +1393,7 @@ public class ConnectivityServiceTest { assertLength(1, mCm.getAllNetworks()); assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork()); // Test WiFi disconnect. - cv = waitForConnectivityBroadcasts(1); + cv = registerConnectivityBroadcast(1); mWiFiNetworkAgent.disconnect(); waitFor(cv); verifyNoNetwork(); @@ -1302,7 +1403,7 @@ public class ConnectivityServiceTest { public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception { // Test bringing up unvalidated WiFi mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - ConditionVariable cv = waitForConnectivityBroadcasts(1); + ConditionVariable cv = registerConnectivityBroadcast(1); mWiFiNetworkAgent.connect(false); waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); @@ -1317,17 +1418,17 @@ public class ConnectivityServiceTest { verifyActiveNetwork(TRANSPORT_WIFI); // Test bringing up validated cellular mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); mCellNetworkAgent.connect(true); waitFor(cv); verifyActiveNetwork(TRANSPORT_CELLULAR); // Test cellular disconnect. - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); mCellNetworkAgent.disconnect(); waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); // Test WiFi disconnect. - cv = waitForConnectivityBroadcasts(1); + cv = registerConnectivityBroadcast(1); mWiFiNetworkAgent.disconnect(); waitFor(cv); verifyNoNetwork(); @@ -1337,23 +1438,23 @@ public class ConnectivityServiceTest { public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception { // Test bringing up unvalidated cellular. mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - ConditionVariable cv = waitForConnectivityBroadcasts(1); + ConditionVariable cv = registerConnectivityBroadcast(1); mCellNetworkAgent.connect(false); waitFor(cv); verifyActiveNetwork(TRANSPORT_CELLULAR); // Test bringing up unvalidated WiFi. mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); mWiFiNetworkAgent.connect(false); waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); // Test WiFi disconnect. - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); mWiFiNetworkAgent.disconnect(); waitFor(cv); verifyActiveNetwork(TRANSPORT_CELLULAR); // Test cellular disconnect. - cv = waitForConnectivityBroadcasts(1); + cv = registerConnectivityBroadcast(1); mCellNetworkAgent.disconnect(); waitFor(cv); verifyNoNetwork(); @@ -1363,7 +1464,7 @@ public class ConnectivityServiceTest { public void testUnlingeringDoesNotValidate() throws Exception { // Test bringing up unvalidated WiFi. mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - ConditionVariable cv = waitForConnectivityBroadcasts(1); + ConditionVariable cv = registerConnectivityBroadcast(1); mWiFiNetworkAgent.connect(false); waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); @@ -1371,14 +1472,14 @@ public class ConnectivityServiceTest { NET_CAPABILITY_VALIDATED)); // Test bringing up validated cellular. mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); mCellNetworkAgent.connect(true); waitFor(cv); verifyActiveNetwork(TRANSPORT_CELLULAR); assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( NET_CAPABILITY_VALIDATED)); // Test cellular disconnect. - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); mCellNetworkAgent.disconnect(); waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); @@ -1391,23 +1492,23 @@ public class ConnectivityServiceTest { public void testCellularOutscoresWeakWifi() throws Exception { // Test bringing up validated cellular. mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - ConditionVariable cv = waitForConnectivityBroadcasts(1); + ConditionVariable cv = registerConnectivityBroadcast(1); mCellNetworkAgent.connect(true); waitFor(cv); verifyActiveNetwork(TRANSPORT_CELLULAR); // Test bringing up validated WiFi. mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); mWiFiNetworkAgent.connect(true); waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); // Test WiFi getting really weak. - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); mWiFiNetworkAgent.adjustScore(-11); waitFor(cv); verifyActiveNetwork(TRANSPORT_CELLULAR); // Test WiFi restoring signal strength. - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); mWiFiNetworkAgent.adjustScore(11); waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); @@ -1427,7 +1528,7 @@ public class ConnectivityServiceTest { mCellNetworkAgent.expectDisconnected(); // Test bringing up validated WiFi. mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - final ConditionVariable cv = waitForConnectivityBroadcasts(1); + final ConditionVariable cv = registerConnectivityBroadcast(1); mWiFiNetworkAgent.connect(true); waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); @@ -1446,18 +1547,18 @@ public class ConnectivityServiceTest { public void testCellularFallback() throws Exception { // Test bringing up validated cellular. mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - ConditionVariable cv = waitForConnectivityBroadcasts(1); + ConditionVariable cv = registerConnectivityBroadcast(1); mCellNetworkAgent.connect(true); waitFor(cv); verifyActiveNetwork(TRANSPORT_CELLULAR); // Test bringing up validated WiFi. mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); mWiFiNetworkAgent.connect(true); waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); // Reevaluate WiFi (it'll instantly fail DNS). - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability( NET_CAPABILITY_VALIDATED)); mCm.reportBadNetwork(mWiFiNetworkAgent.getNetwork()); @@ -1467,7 +1568,7 @@ public class ConnectivityServiceTest { NET_CAPABILITY_VALIDATED)); verifyActiveNetwork(TRANSPORT_CELLULAR); // Reevaluate cellular (it'll instantly fail DNS). - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( NET_CAPABILITY_VALIDATED)); mCm.reportBadNetwork(mCellNetworkAgent.getNetwork()); @@ -1484,18 +1585,18 @@ public class ConnectivityServiceTest { public void testWiFiFallback() throws Exception { // Test bringing up unvalidated WiFi. mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - ConditionVariable cv = waitForConnectivityBroadcasts(1); + ConditionVariable cv = registerConnectivityBroadcast(1); mWiFiNetworkAgent.connect(false); waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); // Test bringing up validated cellular. mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); mCellNetworkAgent.connect(true); waitFor(cv); verifyActiveNetwork(TRANSPORT_CELLULAR); // Reevaluate cellular (it'll instantly fail DNS). - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); assertTrue(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability( NET_CAPABILITY_VALIDATED)); mCm.reportBadNetwork(mCellNetworkAgent.getNetwork()); @@ -1570,7 +1671,7 @@ public class ConnectivityServiceTest { mCm.registerNetworkCallback(cellRequest, cellNetworkCallback); // Test unvalidated networks - ConditionVariable cv = waitForConnectivityBroadcasts(1); + ConditionVariable cv = registerConnectivityBroadcast(1); mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); mCellNetworkAgent.connect(false); genericNetworkCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); @@ -1585,7 +1686,7 @@ public class ConnectivityServiceTest { assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mWiFiNetworkAgent.connect(false); genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); @@ -1594,7 +1695,7 @@ public class ConnectivityServiceTest { waitFor(cv); assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); - cv = waitForConnectivityBroadcasts(2); + cv = registerConnectivityBroadcast(2); mWiFiNetworkAgent.disconnect(); genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent); @@ -1602,7 +1703,7 @@ public class ConnectivityServiceTest { waitFor(cv); assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); - cv = waitForConnectivityBroadcasts(1); + cv = registerConnectivityBroadcast(1); mCellNetworkAgent.disconnect(); genericNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); @@ -2192,7 +2293,7 @@ public class ConnectivityServiceTest { // Test bringing up validated WiFi. mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - final ConditionVariable cv = waitForConnectivityBroadcasts(1); + final ConditionVariable cv = registerConnectivityBroadcast(1); mWiFiNetworkAgent.connect(true); waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); @@ -2220,7 +2321,7 @@ public class ConnectivityServiceTest { public void testMMSonCell() throws Exception { // Test bringing up cellular without MMS mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); - ConditionVariable cv = waitForConnectivityBroadcasts(1); + ConditionVariable cv = registerConnectivityBroadcast(1); mCellNetworkAgent.connect(false); waitFor(cv); verifyActiveNetwork(TRANSPORT_CELLULAR); @@ -3679,7 +3780,7 @@ public class ConnectivityServiceTest { } mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); - ConditionVariable cv = waitForConnectivityBroadcasts(1); + ConditionVariable cv = registerConnectivityBroadcast(1); mWiFiNetworkAgent.connect(true); waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); @@ -4212,7 +4313,7 @@ public class ConnectivityServiceTest { assertNotPinnedToWifi(); // Disconnect cell and wifi. - ConditionVariable cv = waitForConnectivityBroadcasts(3); // cell down, wifi up, wifi down. + ConditionVariable cv = registerConnectivityBroadcast(3); // cell down, wifi up, wifi down. mCellNetworkAgent.disconnect(); mWiFiNetworkAgent.disconnect(); waitFor(cv); @@ -4225,7 +4326,7 @@ public class ConnectivityServiceTest { assertPinnedToWifiWithWifiDefault(); // ... and is maintained even when that network is no longer the default. - cv = waitForConnectivityBroadcasts(1); + cv = registerConnectivityBroadcast(1); mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mCellNetworkAgent.connect(true); waitFor(cv); @@ -4326,7 +4427,7 @@ public class ConnectivityServiceTest { @Test public void testNetworkInfoOfTypeNone() throws Exception { - ConditionVariable broadcastCV = waitForConnectivityBroadcasts(1); + ConditionVariable broadcastCV = registerConnectivityBroadcast(1); verifyNoNetwork(); TestNetworkAgentWrapper wifiAware = new TestNetworkAgentWrapper(TRANSPORT_WIFI_AWARE); @@ -5778,7 +5879,7 @@ public class ConnectivityServiceTest { .destroyNetworkCache(eq(mCellNetworkAgent.getNetwork().netId)); // Disconnect wifi - ConditionVariable cv = waitForConnectivityBroadcasts(1); + ConditionVariable cv = registerConnectivityBroadcast(1); reset(mNetworkManagementService); mWiFiNetworkAgent.disconnect(); waitFor(cv); 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/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 68355c603914..b53b2aaaf547 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1128,6 +1128,9 @@ public class WifiManager { */ private static final int MAX_ACTIVE_LOCKS = 50; + /** Indicates an invalid SSID. */ + public static final String UNKNOWN_SSID = "<unknown ssid>"; + /* Number of currently active WifiLocks and MulticastLocks */ @UnsupportedAppUsage private int mActiveLockCount; @@ -2326,7 +2329,7 @@ public class WifiManager { * <p> * In the connected state, access to the SSID and BSSID requires * the same permissions as {@link #getScanResults}. If such access is not allowed, - * {@link WifiInfo#getSSID} will return {@code "<unknown ssid>"} and + * {@link WifiInfo#getSSID} will return {@link #UNKNOWN_SSID} and * {@link WifiInfo#getBSSID} will return {@code "02:00:00:00:00:00"}. * * @return the Wi-Fi information, contained in {@link WifiInfo}. @@ -3117,7 +3120,7 @@ public class WifiManager { /** * Base class for soft AP callback. Should be extended by applications and set when calling - * {@link WifiManager#registerSoftApCallback(SoftApCallback, Handler)}. + * {@link WifiManager#registerSoftApCallback(Executor, SoftApCallback)}. * * @hide */ @@ -3197,16 +3200,16 @@ public class WifiManager { * without the permission will trigger a {@link java.lang.SecurityException}. * <p> * - * @param callback Callback for soft AP events * @param executor The executor to execute the callbacks of the {@code executor} * object. If null, then the application's main executor will be used. + * @param callback Callback for soft AP events * * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) - public void registerSoftApCallback(@NonNull SoftApCallback callback, - @Nullable @CallbackExecutor Executor executor) { + public void registerSoftApCallback(@Nullable @CallbackExecutor Executor executor, + @NonNull SoftApCallback callback) { if (callback == null) throw new IllegalArgumentException("callback cannot be null"); Log.v(TAG, "registerSoftApCallback: callback=" + callback + ", executor=" + executor); diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java index 70ca0882d7da..f187e1042c58 100644 --- a/wifi/java/android/net/wifi/WifiSsid.java +++ b/wifi/java/android/net/wifi/WifiSsid.java @@ -48,7 +48,7 @@ public class WifiSsid implements Parcelable { private static final int HEX_RADIX = 16; @UnsupportedAppUsage - public static final String NONE = "<unknown ssid>"; + public static final String NONE = WifiManager.UNKNOWN_SSID; private WifiSsid() { } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index cfdb6f1dd304..4260c20255ac 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -686,7 +686,7 @@ public class WifiManagerTest { @Test public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnNullArgumentForCallback() { try { - mWifiManager.registerSoftApCallback(null, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), null); fail("expected IllegalArgumentException"); } catch (IllegalArgumentException expected) { } @@ -710,7 +710,7 @@ public class WifiManagerTest { @Test public void registerSoftApCallbackUsesMainLooperOnNullArgumentForHandler() { when(mContext.getMainLooper()).thenReturn(mLooper.getLooper()); - mWifiManager.registerSoftApCallback(mSoftApCallback, null); + mWifiManager.registerSoftApCallback(null, mSoftApCallback); verify(mContext).getMainExecutor(); } @@ -719,7 +719,7 @@ public class WifiManagerTest { */ @Test public void registerSoftApCallbackCallGoesToWifiServiceImpl() throws Exception { - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), anyInt()); } @@ -730,7 +730,7 @@ public class WifiManagerTest { @Test public void unregisterSoftApCallbackCallGoesToWifiServiceImpl() throws Exception { ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), callbackIdentifier.capture()); @@ -745,7 +745,7 @@ public class WifiManagerTest { public void softApCallbackProxyCallsOnStateChanged() throws Exception { ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -761,7 +761,7 @@ public class WifiManagerTest { public void softApCallbackProxyCallsOnConnectedClientsChanged() throws Exception { ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -778,7 +778,7 @@ public class WifiManagerTest { public void softApCallbackProxyCallsOnMultipleUpdates() throws Exception { ArgumentCaptor<ISoftApCallback.Stub> callbackCaptor = ArgumentCaptor.forClass(ISoftApCallback.Stub.class); - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -802,7 +802,7 @@ public class WifiManagerTest { ArgumentCaptor.forClass(ISoftApCallback.Stub.class); TestLooper altLooper = new TestLooper(); Handler altHandler = new Handler(altLooper.getLooper()); - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(altHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(altHandler), mSoftApCallback); verify(mWifiService).registerSoftApCallback(any(IBinder.class), callbackCaptor.capture(), anyInt()); @@ -816,7 +816,7 @@ public class WifiManagerTest { */ @Test public void testCorrectLooperIsUsedForSoftApCallbackHandler() throws Exception { - mWifiManager.registerSoftApCallback(mSoftApCallback, new HandlerExecutor(mHandler)); + mWifiManager.registerSoftApCallback(new HandlerExecutor(mHandler), mSoftApCallback); mLooper.dispatchAll(); verify(mWifiService).registerSoftApCallback(any(IBinder.class), any(ISoftApCallback.Stub.class), anyInt()); |