Merge changes from topic "apks_in_apex"
* changes:
PackageAbiHepler no longer modifies Package
Adds scan unit tests
diff --git a/Android.bp b/Android.bp
index 891ee91..670860b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -520,24 +520,22 @@
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 @@
],
}
-// TODO: Don't rely on this list by switching package.html into package-info.java
-frameworks_base_subdirs = [
- "core/java",
- "graphics/java",
- "location/java",
- "media/java",
- "media/mca/effect/java",
- "media/mca/filterfw/java",
- "media/mca/filterpacks/java",
- "drm/java",
- "mms/java",
- "opengl/java",
- "sax/java",
- "telecomm/java",
- "telephony/common",
- "telephony/java",
- "wifi/java",
- "lowpan/java",
- "keystore/java",
- "rs/java",
-]
-
// Make the api/current.txt file available for use by modules in other
// directories.
filegroup {
@@ -998,7 +974,6 @@
"test-runner/src/**/*.java",
],
libs: framework_docs_only_libs,
- local_sourcepaths: frameworks_base_subdirs,
create_doc_stubs: true,
annotations_enabled: true,
api_levels_annotations_enabled: true,
@@ -1059,7 +1034,6 @@
":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 19fd711..4ba4fbe 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2023,7 +2023,7 @@
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 @@
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 @@
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 {
@@ -34548,8 +34548,8 @@
}
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 +43520,7 @@
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 +44049,7 @@
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 +44066,7 @@
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 b947918..a4ccfb6 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -595,10 +595,6 @@
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 2a8fb63..341dd6f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -66,6 +66,7 @@
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 @@
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 @@
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 @@
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();
@@ -1746,6 +1759,7 @@
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;
@@ -5668,14 +5682,6 @@
}
-package android.os.telephony {
-
- public class TelephonyRegistryManager {
- method public void notifyCarrierNetworkChange(boolean);
- }
-
-}
-
package android.permission {
public final class PermissionControllerManager {
@@ -6144,6 +6150,10 @@
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 +7325,21 @@
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 +7763,7 @@
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
@@ -8127,6 +8153,7 @@
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();
@@ -8278,7 +8305,7 @@
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();
@@ -8362,6 +8389,15 @@
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 +8930,7 @@
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 1f310c3..eaf1fd7 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -376,6 +376,7 @@
}
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();
}
@@ -707,6 +708,7 @@
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 +741,7 @@
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 +3231,7 @@
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/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index 25cd342..6470a04 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -103,8 +103,6 @@
* 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 967aa04..65ba35f 100644
--- a/core/java/android/accounts/AccountAuthenticatorActivity.java
+++ b/core/java/android/accounts/AccountAuthenticatorActivity.java
@@ -32,7 +32,11 @@
* 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 360be35..835769f 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -3121,6 +3121,15 @@
}
@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/IUiModeManager.aidl b/core/java/android/app/IUiModeManager.aidl
index f2c9f61..a3e0845 100644
--- a/core/java/android/app/IUiModeManager.aidl
+++ b/core/java/android/app/IUiModeManager.aidl
@@ -25,7 +25,7 @@
* 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 @@
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/NotificationManager.java b/core/java/android/app/NotificationManager.java
index dd39376..903dd49 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1638,7 +1638,7 @@
@Override
public int hashCode() {
return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders,
- suppressedVisualEffects);
+ suppressedVisualEffects, state);
}
@Override
@@ -1650,10 +1650,10 @@
&& 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 46a128a..29cb3c1 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -157,7 +157,7 @@
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 @@
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 @@
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 46316e1..8324787 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 @@
* 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 @@
* 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 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 @@
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 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 @@
* @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 @@
* 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 566b387..9d152a7 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1734,6 +1734,56 @@
}
/**
+ * 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 dabe0fd..f5aa014 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -324,4 +324,54 @@
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 a3b918d..a12e4da 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -63,6 +63,7 @@
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.provider.MediaStore;
+import android.telephony.TelephonyRegistryManager;
import android.util.AttributeSet;
import android.view.Display;
import android.view.DisplayAdjustments;
@@ -4747,7 +4748,7 @@
/**
* Use with {@link #getSystemService(String)} to retrieve an
- * {@link android.os.telephony.TelephonyRegistryManager}.
+ * {@link TelephonyRegistryManager}.
* @hide
*/
@SystemApi
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index a7eecd7..7538dca 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -753,6 +753,8 @@
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 a93297e..81670cd 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -7368,6 +7368,18 @@
}
/**
+ * @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 672994e..30a3bd4 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -59,6 +59,7 @@
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 @@
PACKAGE_CONFIGURATOR,
PACKAGE_INCIDENT_REPORT_APPROVER,
PACKAGE_APP_PREDICTOR,
+ PACKAGE_TELEPHONY,
})
@Retention(RetentionPolicy.SOURCE)
public @interface KnownPackage {}
@@ -413,6 +415,17 @@
@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 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 dd5c6a5..c77c53f 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -237,6 +237,17 @@
@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 @@
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 @@
if ((level & PermissionInfo.PROTECTION_FLAG_APP_PREDICTOR) != 0) {
protLevel += "|appPredictor";
}
+ if ((level & PermissionInfo.PROTECTION_FLAG_TELEPHONY) != 0) {
+ protLevel += "|telephony";
+ }
return protLevel;
}
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index 5bc9953..990c114 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -25,6 +25,8 @@
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 @@
* @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 @@
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 4e88149..aa0f622 100644
--- a/core/java/android/net/util/MultinetworkPolicyTracker.java
+++ b/core/java/android/net/util/MultinetworkPolicyTracker.java
@@ -94,7 +94,8 @@
}
};
- 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 9af9eda..a99bdabe 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -28,15 +28,14 @@
* 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 @@
*
* 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 @@
* 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/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 82a3c40..391f3a2 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -43,8 +43,6 @@
import android.text.TextUtils;
import android.util.Log;
-import com.android.internal.telephony.PhoneConstants;
-
import java.util.List;
/**
@@ -610,7 +608,7 @@
* 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 @@
* @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 @@
* 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 @@
/**
* 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 9184d6d..eefc1b7 100644
--- a/core/java/android/service/carrier/CarrierService.java
+++ b/core/java/android/service/carrier/CarrierService.java
@@ -22,7 +22,7 @@
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
similarity index 99%
rename from telephony/java/android/telephony/PhoneStateListener.java
rename to core/java/android/telephony/PhoneStateListener.java
index e5bfb4d..2af827e 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -35,8 +35,8 @@
import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.ImsReasonInfo;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.IPhoneStateListener;
+import com.android.internal.annotations.VisibleForTesting;
import dalvik.system.VMRuntime;
diff --git a/telephony/java/android/telephony/Rlog.java b/core/java/android/telephony/Rlog.java
similarity index 100%
rename from telephony/java/android/telephony/Rlog.java
rename to core/java/android/telephony/Rlog.java
diff --git a/core/java/android/os/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
similarity index 73%
rename from core/java/android/os/telephony/TelephonyRegistryManager.java
rename to core/java/android/telephony/TelephonyRegistryManager.java
index b674099..456789fb 100644
--- a/core/java/android/os/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -13,12 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.os.telephony;
+package android.telephony;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.content.Context;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
+import android.os.Binder;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.telephony.Annotation;
@@ -41,8 +49,15 @@
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.telephony.ims.ImsReasonInfo;
+import android.util.Log;
+
+import com.android.internal.telephony.IOnSubscriptionsChangedListener;
import com.android.internal.telephony.ITelephonyRegistry;
+
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
/**
* A centralized place to notify telephony related status changes, e.g, {@link ServiceState} update
@@ -59,9 +74,26 @@
private static final String TAG = "TelephonyRegistryManager";
private static ITelephonyRegistry sRegistry;
+ private final Context mContext;
+
+ /**
+ * A mapping between {@link SubscriptionManager.OnSubscriptionsChangedListener} and
+ * its callback IOnSubscriptionsChangedListener.
+ */
+ private final Map<SubscriptionManager.OnSubscriptionsChangedListener,
+ IOnSubscriptionsChangedListener> mSubscriptionChangedListenerMap = new HashMap<>();
+ /**
+ * A mapping between {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} and
+ * its callback IOnSubscriptionsChangedListener.
+ */
+ private final Map<SubscriptionManager.OnOpportunisticSubscriptionsChangedListener,
+ IOnSubscriptionsChangedListener> mOpportunisticSubscriptionChangedListenerMap
+ = new HashMap<>();
+
/** @hide **/
- public TelephonyRegistryManager() {
+ public TelephonyRegistryManager(@NonNull Context context) {
+ mContext = context;
if (sRegistry == null) {
sRegistry = ITelephonyRegistry.Stub.asInterface(
ServiceManager.getService("telephony.registry"));
@@ -69,6 +101,113 @@
}
/**
+ * Register for changes to the list of active {@link SubscriptionInfo} records or to the
+ * individual records themselves. When a change occurs the onSubscriptionsChanged method of
+ * the listener will be invoked immediately if there has been a notification. The
+ * onSubscriptionChanged method will also be triggered once initially when calling this
+ * function.
+ *
+ * @param listener an instance of {@link SubscriptionManager.OnSubscriptionsChangedListener}
+ * with onSubscriptionsChanged overridden.
+ * @param executor the executor that will execute callbacks.
+ */
+ public void addOnSubscriptionsChangedListener(
+ @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener,
+ @NonNull Executor executor) {
+ IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
+ @Override
+ public void onSubscriptionsChanged () {
+ Log.d(TAG, "onSubscriptionsChangedListener callback received.");
+ executor.execute(() -> listener.onSubscriptionsChanged());
+ }
+ };
+ mSubscriptionChangedListenerMap.put(listener, callback);
+ try {
+ sRegistry.addOnSubscriptionsChangedListener(mContext.getOpPackageName(), callback);
+ } catch (RemoteException ex) {
+ // system server crash
+ }
+ }
+
+ /**
+ * Unregister the {@link SubscriptionManager.OnSubscriptionsChangedListener}. This is not
+ * strictly necessary as the listener will automatically be unregistered if an attempt to
+ * invoke the listener fails.
+ *
+ * @param listener that is to be unregistered.
+ */
+ public void removeOnSubscriptionsChangedListener(
+ @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener) {
+ if (mSubscriptionChangedListenerMap.get(listener) == null) {
+ return;
+ }
+ try {
+ sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(),
+ mSubscriptionChangedListenerMap.get(listener));
+ mSubscriptionChangedListenerMap.remove(listener);
+ } catch (RemoteException ex) {
+ // system server crash
+ }
+ }
+
+ /**
+ * Register for changes to the list of opportunistic subscription records or to the
+ * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged
+ * method of the listener will be invoked immediately if there has been a notification.
+ *
+ * @param listener an instance of
+ * {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} with
+ * onOpportunisticSubscriptionsChanged overridden.
+ * @param executor an Executor that will execute callbacks.
+ */
+ public void addOnOpportunisticSubscriptionsChangedListener(
+ @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener,
+ @NonNull Executor executor) {
+ /**
+ * The callback methods need to be called on the executor thread where
+ * this object was created. If the binder did that for us it'd be nice.
+ */
+ IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
+ @Override
+ public void onSubscriptionsChanged() {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ Log.d(TAG, "onOpportunisticSubscriptionsChanged callback received.");
+ executor.execute(() -> listener.onOpportunisticSubscriptionsChanged());
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ };
+ mOpportunisticSubscriptionChangedListenerMap.put(listener, callback);
+ try {
+ sRegistry.addOnOpportunisticSubscriptionsChangedListener(mContext.getOpPackageName(),
+ callback);
+ } catch (RemoteException ex) {
+ // system server crash
+ }
+ }
+
+ /**
+ * Unregister the {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener}
+ * that is currently listening opportunistic subscriptions change. This is not strictly
+ * necessary as the listener will automatically be unregistered if an attempt to invoke the
+ * listener fails.
+ *
+ * @param listener that is to be unregistered.
+ */
+ public void removeOnOpportunisticSubscriptionsChangedListener(
+ @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener) {
+ try {
+ sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(),
+ mOpportunisticSubscriptionChangedListenerMap.get(listener));
+ mOpportunisticSubscriptionChangedListenerMap.remove(listener);
+ } catch (RemoteException ex) {
+ // system server crash
+ }
+ }
+
+ /**
* Informs the system of an intentional upcoming carrier network change by a carrier app.
* This call only used to allow the system to provide alternative UI while telephony is
* performing an action that may result in intentional, temporary network lack of connectivity.
@@ -98,14 +237,33 @@
* @param slotIndex for which call state changed. Can be derived from subId except when subId is
* invalid.
* @param state latest call state. e.g, offhook, ringing
- * @param incomingNumer incoming phone number.
+ * @param incomingNumber incoming phone number.
*
* @hide
*/
public void notifyCallStateChanged(int subId, int slotIndex, @CallState int state,
- String incomingNumer) {
+ String incomingNumber) {
try {
- sRegistry.notifyCallState(slotIndex, subId, state, incomingNumer);
+ sRegistry.notifyCallState(slotIndex, subId, state, incomingNumber);
+ } catch (RemoteException ex) {
+ // system server crash
+ }
+ }
+
+ /**
+ * Notify call state changed on all subscriptions.
+ *
+ * @param state latest call state. e.g, offhook, ringing
+ * @param incomingNumber incoming phone number.
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ public void notifyCallStateChangedForAllSubscriptions(@CallState int state,
+ @Nullable String incomingNumber) {
+ try {
+ sRegistry.notifyCallStateForAllSubs(state, incomingNumber);
} catch (RemoteException ex) {
// system server crash
}
@@ -545,4 +703,15 @@
}
}
+ /**
+ * @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 7943c61..d44312b 100644
--- a/core/java/com/android/internal/app/DisableCarModeActivity.java
+++ b/core/java/com/android/internal/app/DisableCarModeActivity.java
@@ -33,7 +33,9 @@
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/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl
index 5857642..7dcb12c 100644
--- a/core/java/com/android/internal/compat/IPlatformCompat.aidl
+++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl
@@ -133,7 +133,7 @@
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 @@
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 @@
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 0000000..8a226db
--- /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
similarity index 100%
rename from telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl
rename to 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
similarity index 99%
rename from telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
rename to core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 90019ee..084a3cc 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.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
similarity index 100%
rename from telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
rename to core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 9a90555..9e4c222 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -667,6 +667,8 @@
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 @@
parseCompilerOption("dalvik.vm.dex2oat-threads", dex2oatThreadsBuf, "-j", "-Xcompiler-option");
parseCompilerOption("dalvik.vm.image-dex2oat-threads", dex2oatThreadsImageBuf, "-j",
"-Ximage-compiler-option");
+ parseCompilerOption("dalvik.vm.dex2oat-cpu-set", dex2oatCpuSetBuf, "--cpu-set=",
+ "-Xcompiler-option");
+ parseCompilerOption("dalvik.vm.image-dex2oat-cpu-set", dex2oatCpuSetImageBuf, "--cpu-set=",
+ "-Ximage-compiler-option");
// The runtime will compile a boot image, when necessary, not using installd. Thus, we need to
// pass the instruction-set-features/variant as an image-compiler-option.
diff --git a/core/jni/core_jni_helpers.h b/core/jni/core_jni_helpers.h
index 16ef753..f03f427 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 b8c6cf6..216b87f 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 77fca8f..17045d8 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 6c0fe46..4b4baa9 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 6efa2d6..e729b03 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 0804703..e8cd271 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/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 80f3cc6..9064abf 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -238,6 +238,7 @@
<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 @@
<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 646aa13..c0a0422 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -348,16 +348,6 @@
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 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 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 441ee66..c6515ef 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreAuthenticatedAESCipherSpi.java
@@ -432,7 +432,7 @@
}
@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 3dc884e..17aacb9 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
@@ -210,13 +210,9 @@
}
}
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 e030478..75bea26 100644
--- a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
+++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
@@ -62,7 +62,7 @@
* 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 @@
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 @@
}
@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
similarity index 100%
rename from media/java/android/media/tv/OWNER
rename to media/java/android/media/tv/OWNERS
diff --git a/media/jni/android_media_MediaDataSource.cpp b/media/jni/android_media_MediaDataSource.cpp
index 8c38d88..84a0e0d 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 @@
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 39405d2..378baf4 100644
--- a/media/jni/android_media_MediaDataSource.h
+++ b/media/jni/android_media_MediaDataSource.h
@@ -47,7 +47,6 @@
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 0000000..7728464
--- /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 12972f1..0000000
--- 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 0000000..ede1fab
--- /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 03eb0d9..0000000
--- 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 ea3c1d9..092cbf3 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 @@
}
}
- 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 3da5e76..f7bee30 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 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 047ac59..13fc881 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/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringConfiguration.java
index cf0e3b2..ca9b168 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 @@
/** 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 9c65c0d..30bff35 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 @@
@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 @@
@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 @@
@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 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 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/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 30a3563..d1e4231 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.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.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 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 @@
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 @@
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 @@
}
}
+ /**
+ * 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(int flags) {
+ 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 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 @@
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 @@
}
}
- 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 @@
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/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 83ad4e7..454941c 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -89,6 +89,7 @@
"/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 e5c8ba5..5af1480 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.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 @@
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 6e92e80..d9e4844 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.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.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 @@
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 5255316..0524f91 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 @@
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 c2f4529..5674046 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 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 1f1e8a5..48f08e3 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 @@
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 @@
}
/**
- * 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 @@
& 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 d6ec22b..490cce3 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.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 @@
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 @@
*
* @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 @@
*
* @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 @@
* @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 @@
* 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 @@
*
* <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 @@
}
/**
+ * 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 @@
}
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 @@
*
* @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 @@
}
/**
- * 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 @@
*
* @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 @@
*
* @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 75e2d22..ae5ad7e 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 @@
@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 @@
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 @@
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 b3804c4..acedc36 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 @@
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 2e72fbd..93227bd 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 @@
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 41806ca..08c9426 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 @@
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 8facce1..dbe8367 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.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 @@
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 @@
final List<ActivityIntentInfo> protectedFilters = mProtectedFilters;
mProtectedFilters = null;
- final String setupWizardPackage = sPackageManagerInternal.getKnownPackageName(
- PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM);
+ // expect single setupwizard package
+ final String setupWizardPackage = ArrayUtils.firstOrNull(
+ sPackageManagerInternal.getKnownPackageNames(
+ PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM));
+
if (DEBUG_FILTERS && setupWizardPackage == null) {
Slog.i(TAG, "No setup wizard;"
+ " All protected intents capped to priority 0");
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 56d2258..a77b728 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1430,6 +1430,7 @@
final @Nullable String mConfiguratorPackage;
final @Nullable String mAppPredictionServicePackage;
final @Nullable String mIncidentReportApproverPackage;
+ final @Nullable String[] mTelephonyPackages;
final @NonNull String mServicesSystemSharedLibraryPackageName;
final @NonNull String mSharedSystemSharedLibraryPackageName;
@@ -3146,6 +3147,7 @@
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.
@@ -20786,6 +20788,16 @@
}
@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;
@@ -23934,34 +23946,36 @@
}
@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
@@ -24117,6 +24131,12 @@
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/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 3bc2236..4ecfbfe 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 @@
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/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index 6d22faa..c39dcfe 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 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 f762985..5870986 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 @@
// 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 @@
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 @@
}
}
- 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 6d1f2d3..6a7c622 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 @@
}
}
}
- 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 @@
// 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 @@
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/net/java/android/net/NetworkStackClient.java b/services/net/java/android/net/NetworkStackClient.java
index 69e2406..865e3b8 100644
--- a/services/net/java/android/net/NetworkStackClient.java
+++ b/services/net/java/android/net/NetworkStackClient.java
@@ -103,7 +103,7 @@
// 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/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
index dcab78e..8cd6ef9 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 @@
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/DisconnectCause.java b/telecomm/java/android/telecom/DisconnectCause.java
index ae92464..bebbbd0 100644
--- a/telecomm/java/android/telecom/DisconnectCause.java
+++ b/telecomm/java/android/telecom/DisconnectCause.java
@@ -97,6 +97,14 @@
*/
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
similarity index 100%
rename from telephony/java/com/android/internal/telephony/GsmAlphabet.java
rename to 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 f27b944..087937d 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -1127,8 +1127,9 @@
* 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 @@
*
* <p>Requires {@link android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST} to
* receive.</p>
- * @removed
+ * @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String SMS_EMERGENCY_CB_RECEIVED_ACTION =
- "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED";
+ @SystemApi
+ public static final String ACTION_SMS_EMERGENCY_CB_RECEIVED =
+ "android.provider.action.SMS_EMERGENCY_CB_RECEIVED";
/**
* Broadcast Action: A new CDMA SMS has been received containing Service Category
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 4dad01f..a0aa892 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -809,7 +809,9 @@
/**
* 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 @@
"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 @@
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
similarity index 94%
rename from telephony/java/com/android/internal/telephony/CbGeoUtils.java
rename to telephony/java/android/telephony/CbGeoUtils.java
index 0b73252..f4ce6e7 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 @@
* 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 @@
* @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 @@
* @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 @@
* @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 @@
/**
* The class represents a simple polygon with at least 3 points.
+ * @hide
*/
public static class Polygon implements Geometry {
/**
@@ -239,7 +259,10 @@
}
}
- /** 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 @@
/**
* 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 @@
*
* @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 @@
* {@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 @@
*
* @param str encoded lat/lng string.
* @Return {@link LatLng} object.
+ * @hide
*/
@NonNull
public static LatLng parseLatLngFromString(@NonNull String str) {
@@ -361,6 +388,7 @@
/**
* @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 85110c2..04ec4b6 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -354,6 +354,12 @@
*/
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 @@
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/SmsCbMessage.java b/telephony/java/android/telephony/SmsCbMessage.java
index dc991b9..3e044e5 100644
--- a/telephony/java/android/telephony/SmsCbMessage.java
+++ b/telephony/java/android/telephony/SmsCbMessage.java
@@ -25,9 +25,7 @@
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;
@@ -414,9 +412,8 @@
/**
* 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 54e87af..daeacf8 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -520,7 +520,6 @@
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 @@
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 @@
}
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 @@
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 @@
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 0e1dda7..9d1b7a9 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -49,6 +49,7 @@
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
+import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelUuid;
@@ -61,10 +62,8 @@
import android.util.DisplayMetrics;
import android.util.Log;
-import com.android.internal.telephony.IOnSubscriptionsChangedListener;
import com.android.internal.telephony.ISetOpportunisticDataCallback;
import com.android.internal.telephony.ISub;
-import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.Preconditions;
@@ -931,20 +930,24 @@
OnSubscriptionsChangedListenerHandler(Looper looper) {
super(looper);
}
-
- @Override
- public void handleMessage(Message msg) {
- if (DBG) {
- log("handleMessage: invoke the overriden onSubscriptionsChanged()");
- }
- OnSubscriptionsChangedListener.this.onSubscriptionsChanged();
- }
}
- private final Handler mHandler;
+ /**
+ * Posted executor callback on the handler associated with a given looper.
+ * The looper can be the calling thread's looper or the looper passed from the
+ * constructor {@link #OnSubscriptionsChangedListener(Looper)}.
+ */
+ private final HandlerExecutor mExecutor;
+
+ /**
+ * @hide
+ */
+ public HandlerExecutor getHandlerExecutor() {
+ return mExecutor;
+ }
public OnSubscriptionsChangedListener() {
- mHandler = new OnSubscriptionsChangedListenerHandler();
+ mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler());
}
/**
@@ -953,7 +956,7 @@
* @hide
*/
public OnSubscriptionsChangedListener(Looper looper) {
- mHandler = new OnSubscriptionsChangedListenerHandler(looper);
+ mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler(looper));
}
/**
@@ -965,18 +968,6 @@
if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN");
}
- /**
- * The callback methods need to be called on the handler thread where
- * this object was created. If the binder did that for us it'd be nice.
- */
- IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
- @Override
- public void onSubscriptionsChanged() {
- if (DBG) log("callback: received, sendEmptyMessage(0) to handler");
- mHandler.sendEmptyMessage(0);
- }
- };
-
private void log(String s) {
Rlog.d(LOG_TAG, s);
}
@@ -1018,21 +1009,19 @@
* onSubscriptionsChanged overridden.
*/
public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
+ if (listener == null) return;
String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
if (DBG) {
logd("register OnSubscriptionsChangedListener pkgName=" + pkgName
+ " listener=" + listener);
}
- try {
- // We use the TelephonyRegistry as it runs in the system and thus is always
- // available. Where as SubscriptionController could crash and not be available
- ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
- "telephony.registry"));
- if (tr != null) {
- tr.addOnSubscriptionsChangedListener(pkgName, listener.callback);
- }
- } catch (RemoteException ex) {
- Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex);
+ // We use the TelephonyRegistry as it runs in the system and thus is always
+ // available. Where as SubscriptionController could crash and not be available
+ TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
+ mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+ if (telephonyRegistryManager != null) {
+ telephonyRegistryManager.addOnSubscriptionsChangedListener(listener,
+ listener.mExecutor);
}
}
@@ -1044,21 +1033,18 @@
* @param listener that is to be unregistered.
*/
public void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
+ if (listener == null) return;
String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
if (DBG) {
logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug
+ " listener=" + listener);
}
- try {
- // We use the TelephonyRegistry as it runs in the system and thus is always
- // available where as SubscriptionController could crash and not be available
- ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
- "telephony.registry"));
- if (tr != null) {
- tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback);
- }
- } catch (RemoteException ex) {
- Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex);
+ // We use the TelephonyRegistry as it runs in the system and thus is always
+ // available where as SubscriptionController could crash and not be available
+ TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
+ mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+ if (telephonyRegistryManager != null) {
+ telephonyRegistryManager.removeOnSubscriptionsChangedListener(listener);
}
}
@@ -1077,7 +1063,6 @@
* for #onOpportunisticSubscriptionsChanged to be invoked.
*/
public static class OnOpportunisticSubscriptionsChangedListener {
- private Executor mExecutor;
/**
* Callback invoked when there is any change to any SubscriptionInfo. Typically
* this method would invoke {@link #getActiveSubscriptionInfoList}
@@ -1086,27 +1071,6 @@
if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN");
}
- private void setExecutor(Executor executor) {
- mExecutor = executor;
- }
-
- /**
- * The callback methods need to be called on the handler thread where
- * this object was created. If the binder did that for us it'd be nice.
- */
- IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
- @Override
- public void onSubscriptionsChanged() {
- final long identity = Binder.clearCallingIdentity();
- try {
- if (DBG) log("onOpportunisticSubscriptionsChanged callback received.");
- mExecutor.execute(() -> onOpportunisticSubscriptionsChanged());
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- };
-
private void log(String s) {
Rlog.d(LOG_TAG, s);
}
@@ -1133,18 +1097,13 @@
+ " listener=" + listener);
}
- listener.setExecutor(executor);
-
- try {
- // We use the TelephonyRegistry as it runs in the system and thus is always
- // available. Where as SubscriptionController could crash and not be available
- ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
- "telephony.registry"));
- if (tr != null) {
- tr.addOnOpportunisticSubscriptionsChangedListener(pkgName, listener.callback);
- }
- } catch (RemoteException ex) {
- Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex);
+ // We use the TelephonyRegistry as it runs in the system and thus is always
+ // available where as SubscriptionController could crash and not be available
+ TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
+ mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+ if (telephonyRegistryManager != null) {
+ telephonyRegistryManager.addOnOpportunisticSubscriptionsChangedListener(
+ listener, executor);
}
}
@@ -1164,16 +1123,10 @@
logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug="
+ pkgForDebug + " listener=" + listener);
}
- try {
- // We use the TelephonyRegistry as it runs in the system and thus is always
- // available where as SubscriptionController could crash and not be available
- ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
- "telephony.registry"));
- if (tr != null) {
- tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback);
- }
- } catch (RemoteException ex) {
- Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex);
+ TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
+ mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+ if (telephonyRegistryManager != null) {
+ telephonyRegistryManager.removeOnOpportunisticSubscriptionsChangedListener(listener);
}
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 55212cd..46f5ebb 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -7673,8 +7673,8 @@
*/
@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 +7684,11 @@
* @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) {
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index eb0e2f7..5fd0af5 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -979,25 +979,25 @@
/**
* 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 119f890..e96d082 100644
--- a/telephony/java/android/telephony/ims/feature/RcsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java
@@ -199,12 +199,19 @@
/** @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 b502ee7..2f18049e 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -819,7 +819,7 @@
* @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 c3d490a..5766287 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 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 d85cf15..11bc5de 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 @@
* All relevant header information is now sent as a Parcelable
* {@link android.telephony.SmsCbMessage} object in the "message" extra of the
* {@link android.provider.Telephony.Sms.Intents#SMS_CB_RECEIVED_ACTION} or
- * {@link android.provider.Telephony.Sms.Intents#SMS_EMERGENCY_CB_RECEIVED_ACTION} intent.
+ * {@link android.provider.Telephony.Sms.Intents#ACTION_SMS_EMERGENCY_CB_RECEIVED} intent.
* The raw PDU is no longer sent to SMS CB applications.
*/
public class SmsCbHeader {
diff --git a/tests/PlatformCompatGating/Android.bp b/tests/PlatformCompatGating/Android.bp
new file mode 100644
index 0000000..5e9ef8e
--- /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 0000000..7f14b83
--- /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 0000000..c626848
--- /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 0000000..731be8e
--- /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 0000000..dc317f19
--- /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 0000000..8211ef5
--- /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 0000000..932ec64
--- /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 61f37fd..aad2f3d 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.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_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.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.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 @@
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 @@
"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 @@
// 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 @@
}
// 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 @@
@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 @@
* 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 @@
}
@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 @@
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 @@
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 @@
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 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 @@
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 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 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 @@
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 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 @@
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 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 @@
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 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 @@
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 @@
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 @@
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 @@
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 @@
// 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 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 @@
}
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 @@
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 @@
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 @@
@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 @@
.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 f0453694..42d4cf3 100644
--- a/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
+++ b/tests/net/java/com/android/server/LegacyTypeTrackerTest.kt
@@ -18,6 +18,7 @@
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 @@
@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 @@
}
@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 5f62c08..9e5717b 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 @@
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 1d29a82..4d42a61 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 @@
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 f901c9f..0000000
--- 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 0e33fdd..1e96234 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 @@
"--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 5a5703e..65fc733 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 @@
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 0000000..49ea3d4
--- /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 0000000..23db99e
--- /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 0000000..012e88f
--- /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");
+ }
+
+
+}