Merge "Update hidden API toast message"
diff --git a/api/current.txt b/api/current.txt
index 6232757..cd29286 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6534,6 +6534,7 @@
field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2
field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
field public static final int SKIP_SETUP_WIZARD = 1; // 0x1
+ field public static final int WIPE_EUICC = 4; // 0x4
field public static final int WIPE_EXTERNAL_STORAGE = 1; // 0x1
field public static final int WIPE_RESET_PROTECTION_DATA = 2; // 0x2
}
@@ -9048,6 +9049,7 @@
field public static final java.lang.String DISPLAY_SERVICE = "display";
field public static final java.lang.String DOWNLOAD_SERVICE = "download";
field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
+ field public static final java.lang.String EUICC_SERVICE = "euicc";
field public static final java.lang.String FINGERPRINT_SERVICE = "fingerprint";
field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
@@ -10851,6 +10853,7 @@
field public static final java.lang.String FEATURE_SIP_VOIP = "android.software.sip.voip";
field public static final java.lang.String FEATURE_TELEPHONY = "android.hardware.telephony";
field public static final java.lang.String FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma";
+ field public static final java.lang.String FEATURE_TELEPHONY_EUICC = "android.hardware.telephony.euicc";
field public static final java.lang.String FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm";
field public static final java.lang.String FEATURE_TELEPHONY_MBMS = "android.hardware.telephony.mbms";
field public static final deprecated java.lang.String FEATURE_TELEVISION = "android.hardware.type.television";
@@ -25713,7 +25716,7 @@
field public static final deprecated java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
field public static final java.lang.String ACTION_CAPTIVE_PORTAL_SIGN_IN = "android.net.conn.CAPTIVE_PORTAL";
field public static final java.lang.String ACTION_RESTRICT_BACKGROUND_CHANGED = "android.net.conn.RESTRICT_BACKGROUND_CHANGED";
- field public static final java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
+ field public static final deprecated java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
field public static final deprecated int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1
field public static final java.lang.String EXTRA_CAPTIVE_PORTAL = "android.net.extra.CAPTIVE_PORTAL";
field public static final java.lang.String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL";
@@ -25989,6 +25992,7 @@
field public static final int NET_CAPABILITY_CBS = 5; // 0x5
field public static final int NET_CAPABILITY_DUN = 2; // 0x2
field public static final int NET_CAPABILITY_EIMS = 10; // 0xa
+ field public static final int NET_CAPABILITY_FOREGROUND = 19; // 0x13
field public static final int NET_CAPABILITY_FOTA = 3; // 0x3
field public static final int NET_CAPABILITY_IA = 7; // 0x7
field public static final int NET_CAPABILITY_IMS = 4; // 0x4
@@ -25997,6 +26001,7 @@
field public static final int NET_CAPABILITY_NOT_METERED = 11; // 0xb
field public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; // 0xd
field public static final int NET_CAPABILITY_NOT_ROAMING = 18; // 0x12
+ field public static final int NET_CAPABILITY_NOT_SUSPENDED = 21; // 0x15
field public static final int NET_CAPABILITY_NOT_VPN = 15; // 0xf
field public static final int NET_CAPABILITY_RCS = 8; // 0x8
field public static final int NET_CAPABILITY_SUPL = 1; // 0x1
@@ -35548,6 +35553,13 @@
field public static final java.lang.String ADDRESS = "address";
}
+ public static final class Telephony.CarrierIdentification implements android.provider.BaseColumns {
+ method public static android.net.Uri getUriForSubscriptionId(int);
+ field public static final java.lang.String CID = "carrier_id";
+ field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String NAME = "carrier_name";
+ }
+
public static final class Telephony.Carriers implements android.provider.BaseColumns {
field public static final java.lang.String APN = "apn";
field public static final java.lang.String AUTH_TYPE = "authtype";
@@ -39331,8 +39343,8 @@
method public final void setActive();
method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
method public final void setConnectionCapabilities(int);
- method public final void setConnectionElapsedTime(long);
method public final void setConnectionProperties(int);
+ method public final void setConnectionStartElapsedRealTime(long);
method public final void setConnectionTime(long);
method public final void setDialing();
method public final void setDisconnected(android.telecom.DisconnectCause);
@@ -40768,13 +40780,16 @@
method public java.lang.String getNumber();
method public int getSimSlotIndex();
method public int getSubscriptionId();
+ method public boolean isEmbedded();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.telephony.SubscriptionInfo> CREATOR;
}
public class SubscriptionManager {
method public void addOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
+ method public boolean canManageSubscription(android.telephony.SubscriptionInfo);
method public static android.telephony.SubscriptionManager from(android.content.Context);
+ method public java.util.List<android.telephony.SubscriptionInfo> getAccessibleSubscriptionInfoList();
method public android.telephony.SubscriptionInfo getActiveSubscriptionInfo(int);
method public int getActiveSubscriptionInfoCount();
method public int getActiveSubscriptionInfoCountMax();
@@ -41117,6 +41132,44 @@
}
+package android.telephony.euicc {
+
+ public final class DownloadableSubscription implements android.os.Parcelable {
+ method public int describeContents();
+ method public static android.telephony.euicc.DownloadableSubscription forActivationCode(java.lang.String);
+ method public java.lang.String getConfirmationCode();
+ method public java.lang.String getEncodedActivationCode();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.euicc.DownloadableSubscription> CREATOR;
+ }
+
+ public final class EuiccInfo implements android.os.Parcelable {
+ ctor public EuiccInfo(java.lang.String);
+ method public int describeContents();
+ method public java.lang.String getOsVersion();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccInfo> CREATOR;
+ }
+
+ public class EuiccManager {
+ method public void deleteSubscription(int, android.app.PendingIntent);
+ method public void downloadSubscription(android.telephony.euicc.DownloadableSubscription, boolean, android.app.PendingIntent);
+ method public java.lang.String getEid();
+ method public android.telephony.euicc.EuiccInfo getEuiccInfo();
+ method public boolean isEnabled();
+ method public void startResolutionActivity(android.app.Activity, int, android.content.Intent, android.app.PendingIntent) throws android.content.IntentSender.SendIntentException;
+ method public void switchToSubscription(int, android.app.PendingIntent);
+ field public static final java.lang.String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS = "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
+ field public static final java.lang.String ACTION_NOTIFY_CARRIER_SETUP_INCOMPLETE = "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE";
+ field public static final int EMBEDDED_SUBSCRIPTION_RESULT_ERROR = 2; // 0x2
+ field public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0; // 0x0
+ field public static final int EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR = 1; // 0x1
+ field public static final java.lang.String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE";
+ field public static final java.lang.String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon";
+ }
+
+}
+
package android.telephony.gsm {
public class GsmCellLocation extends android.telephony.CellLocation {
diff --git a/api/system-current.txt b/api/system-current.txt
index 47a0ce1..56b5923 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -20,6 +20,7 @@
field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
field public static final deprecated java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
field public static final java.lang.String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH";
+ field public static final java.lang.String BIND_EUICC_SERVICE = "android.permission.BIND_EUICC_SERVICE";
field public static final java.lang.String BIND_IMS_SERVICE = "android.permission.BIND_IMS_SERVICE";
field public static final java.lang.String BIND_KEYGUARD_APPWIDGET = "android.permission.BIND_KEYGUARD_APPWIDGET";
field public static final java.lang.String BIND_NETWORK_RECOMMENDATION_SERVICE = "android.permission.BIND_NETWORK_RECOMMENDATION_SERVICE";
@@ -172,6 +173,7 @@
field public static final java.lang.String USER_ACTIVITY = "android.permission.USER_ACTIVITY";
field public static final java.lang.String WRITE_APN_SETTINGS = "android.permission.WRITE_APN_SETTINGS";
field public static final java.lang.String WRITE_DREAM_STATE = "android.permission.WRITE_DREAM_STATE";
+ field public static final java.lang.String WRITE_EMBEDDED_SUBSCRIPTIONS = "android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS";
field public static final java.lang.String WRITE_GSERVICES = "android.permission.WRITE_GSERVICES";
field public static final java.lang.String WRITE_MEDIA_STORAGE = "android.permission.WRITE_MEDIA_STORAGE";
field public static final java.lang.String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS";
@@ -695,6 +697,7 @@
method public abstract void sendOrderedBroadcast(android.content.Intent, java.lang.String, android.os.Bundle, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle);
field public static final java.lang.String BACKUP_SERVICE = "backup";
field public static final java.lang.String CONTEXTHUB_SERVICE = "contexthub";
+ field public static final java.lang.String EUICC_CARD_SERVICE = "euicc_card";
field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control";
field public static final java.lang.String NETWORK_SCORE_SERVICE = "network_score";
field public static final java.lang.String OEM_LOCK_SERVICE = "oem_lock";
@@ -3506,6 +3509,7 @@
public static final class Settings.Global extends android.provider.Settings.NameValueTable {
method public static boolean putString(android.content.ContentResolver, java.lang.String, java.lang.String, java.lang.String, boolean);
method public static void resetToDefaults(android.content.ContentResolver, java.lang.String);
+ field public static final java.lang.String DEFAULT_SM_DP_PLUS = "default_sm_dp_plus";
field public static final java.lang.String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update";
field public static final java.lang.String THEATER_MODE_ON = "theater_mode_on";
field public static final java.lang.String WEBVIEW_MULTIPROCESS = "webview_multiprocess";
@@ -3548,6 +3552,125 @@
}
+package android.service.euicc {
+
+ public final class EuiccProfileInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public android.service.carrier.CarrierIdentifier getCarrierIdentifier();
+ method public java.lang.String getIccid();
+ method public java.lang.String getNickname();
+ method public int getPolicyRules();
+ method public int getProfileClass();
+ method public java.lang.String getProfileName();
+ method public java.lang.String getServiceProviderName();
+ method public int getState();
+ method public java.util.List<android.telephony.UiccAccessRule> getUiccAccessRules();
+ method public boolean hasPolicyRule(int);
+ method public boolean hasPolicyRules();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.euicc.EuiccProfileInfo> CREATOR;
+ field public static final int POLICY_RULE_DELETE_AFTER_DISABLING = 4; // 0x4
+ field public static final int POLICY_RULE_DO_NOT_DELETE = 2; // 0x2
+ field public static final int POLICY_RULE_DO_NOT_DISABLE = 1; // 0x1
+ field public static final int PROFILE_CLASS_OPERATIONAL = 2; // 0x2
+ field public static final int PROFILE_CLASS_PROVISIONING = 1; // 0x1
+ field public static final int PROFILE_CLASS_TESTING = 0; // 0x0
+ field public static final int PROFILE_STATE_DISABLED = 0; // 0x0
+ field public static final int PROFILE_STATE_ENABLED = 1; // 0x1
+ }
+
+ public static final class EuiccProfileInfo.Builder {
+ ctor public EuiccProfileInfo.Builder(java.lang.String);
+ ctor public EuiccProfileInfo.Builder(android.service.euicc.EuiccProfileInfo);
+ method public android.service.euicc.EuiccProfileInfo build();
+ method public android.service.euicc.EuiccProfileInfo.Builder setCarrierIdentifier(android.service.carrier.CarrierIdentifier);
+ method public android.service.euicc.EuiccProfileInfo.Builder setIccid(java.lang.String);
+ method public android.service.euicc.EuiccProfileInfo.Builder setNickname(java.lang.String);
+ method public android.service.euicc.EuiccProfileInfo.Builder setPolicyRules(int);
+ method public android.service.euicc.EuiccProfileInfo.Builder setProfileClass(int);
+ method public android.service.euicc.EuiccProfileInfo.Builder setProfileName(java.lang.String);
+ method public android.service.euicc.EuiccProfileInfo.Builder setServiceProviderName(java.lang.String);
+ method public android.service.euicc.EuiccProfileInfo.Builder setState(int);
+ method public android.service.euicc.EuiccProfileInfo.Builder setUiccAccessRule(java.util.List<android.telephony.UiccAccessRule>);
+ }
+
+ public static abstract class EuiccProfileInfo.PolicyRule implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract class EuiccProfileInfo.ProfileClass implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract class EuiccProfileInfo.ProfileState implements java.lang.annotation.Annotation {
+ }
+
+ public abstract class EuiccService extends android.app.Service {
+ ctor public EuiccService();
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract int onDeleteSubscription(int, java.lang.String);
+ method public abstract int onDownloadSubscription(int, android.telephony.euicc.DownloadableSubscription, boolean, boolean);
+ method public abstract int onEraseSubscriptions(int);
+ method public abstract android.service.euicc.GetDefaultDownloadableSubscriptionListResult onGetDefaultDownloadableSubscriptionList(int, boolean);
+ method public abstract android.service.euicc.GetDownloadableSubscriptionMetadataResult onGetDownloadableSubscriptionMetadata(int, android.telephony.euicc.DownloadableSubscription, boolean);
+ method public abstract java.lang.String onGetEid(int);
+ method public abstract android.telephony.euicc.EuiccInfo onGetEuiccInfo(int);
+ method public abstract android.service.euicc.GetEuiccProfileInfoListResult onGetEuiccProfileInfoList(int);
+ method public abstract int onGetOtaStatus(int);
+ method public abstract int onRetainSubscriptionsForFactoryReset(int);
+ method public abstract void onStartOtaIfNecessary(int, android.service.euicc.EuiccService.OtaStatusChangedCallback);
+ method public abstract int onSwitchToSubscription(int, java.lang.String, boolean);
+ method public abstract int onUpdateSubscriptionNickname(int, java.lang.String, java.lang.String);
+ field public static final java.lang.String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS = "android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
+ field public static final java.lang.String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION = "android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
+ field public static final java.lang.String ACTION_RESOLVE_CONFIRMATION_CODE = "android.service.euicc.action.RESOLVE_CONFIRMATION_CODE";
+ field public static final java.lang.String ACTION_RESOLVE_DEACTIVATE_SIM = "android.service.euicc.action.RESOLVE_DEACTIVATE_SIM";
+ field public static final java.lang.String ACTION_RESOLVE_NO_PRIVILEGES = "android.service.euicc.action.RESOLVE_NO_PRIVILEGES";
+ field public static final java.lang.String CATEGORY_EUICC_UI = "android.service.euicc.category.EUICC_UI";
+ field public static final java.lang.String EUICC_SERVICE_INTERFACE = "android.service.euicc.EuiccService";
+ field public static final java.lang.String EXTRA_RESOLUTION_CALLING_PACKAGE = "android.service.euicc.extra.RESOLUTION_CALLING_PACKAGE";
+ field public static final java.lang.String EXTRA_RESOLUTION_CONFIRMATION_CODE = "android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE";
+ field public static final java.lang.String EXTRA_RESOLUTION_CONFIRMATION_CODE_RETRIED = "android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE_RETRIED";
+ field public static final java.lang.String EXTRA_RESOLUTION_CONSENT = "android.service.euicc.extra.RESOLUTION_CONSENT";
+ field public static final int RESULT_FIRST_USER = 1; // 0x1
+ field public static final int RESULT_MUST_DEACTIVATE_SIM = -1; // 0xffffffff
+ field public static final int RESULT_NEED_CONFIRMATION_CODE = -2; // 0xfffffffe
+ field public static final int RESULT_OK = 0; // 0x0
+ }
+
+ public static abstract class EuiccService.OtaStatusChangedCallback {
+ ctor public EuiccService.OtaStatusChangedCallback();
+ method public abstract void onOtaStatusChanged(int);
+ }
+
+ public final class GetDefaultDownloadableSubscriptionListResult implements android.os.Parcelable {
+ ctor public GetDefaultDownloadableSubscriptionListResult(int, android.telephony.euicc.DownloadableSubscription[]);
+ method public int describeContents();
+ method public java.util.List<android.telephony.euicc.DownloadableSubscription> getDownloadableSubscriptions();
+ method public int getResult();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.euicc.GetDefaultDownloadableSubscriptionListResult> CREATOR;
+ }
+
+ public final class GetDownloadableSubscriptionMetadataResult implements android.os.Parcelable {
+ ctor public GetDownloadableSubscriptionMetadataResult(int, android.telephony.euicc.DownloadableSubscription);
+ method public int describeContents();
+ method public android.telephony.euicc.DownloadableSubscription getDownloadableSubscription();
+ method public int getResult();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.euicc.GetDownloadableSubscriptionMetadataResult> CREATOR;
+ }
+
+ public final class GetEuiccProfileInfoListResult implements android.os.Parcelable {
+ ctor public GetEuiccProfileInfoListResult(int, android.service.euicc.EuiccProfileInfo[], boolean);
+ method public int describeContents();
+ method public boolean getIsRemovable();
+ method public java.util.List<android.service.euicc.EuiccProfileInfo> getProfiles();
+ method public int getResult();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.euicc.GetEuiccProfileInfoListResult> CREATOR;
+ }
+
+}
+
package android.service.notification {
public final class Adjustment implements android.os.Parcelable {
@@ -4066,8 +4189,14 @@
field public static final int RESULT_SYSTEM_ERROR = 15; // 0xf
}
+ public class SubscriptionInfo implements android.os.Parcelable {
+ method public java.util.List<android.telephony.UiccAccessRule> getAccessRules();
+ }
+
public class SubscriptionManager {
+ method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList();
method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
+ method public void requestEmbeddedSubscriptionInfoListRefresh();
method public void setSubscriptionPlans(int, java.util.List<android.telephony.SubscriptionPlan>);
}
@@ -4186,6 +4315,16 @@
field public static final int SIM_STATE_PRESENT = 11; // 0xb
}
+ public final class UiccAccessRule implements android.os.Parcelable {
+ ctor public UiccAccessRule(byte[], java.lang.String, long);
+ method public int describeContents();
+ method public int getCarrierPrivilegeStatus(android.content.pm.PackageInfo);
+ method public int getCarrierPrivilegeStatus(android.content.pm.Signature, java.lang.String);
+ method public java.lang.String getPackageName();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.UiccAccessRule> CREATOR;
+ }
+
public class UiccSlotInfo implements android.os.Parcelable {
ctor public UiccSlotInfo(boolean, boolean, java.lang.String, int, int);
method public int describeContents();
@@ -4296,6 +4435,125 @@
}
+package android.telephony.euicc {
+
+ public final class DownloadableSubscription implements android.os.Parcelable {
+ method public java.util.List<android.telephony.UiccAccessRule> getAccessRules();
+ method public java.lang.String getCarrierName();
+ }
+
+ public static final class DownloadableSubscription.Builder {
+ ctor public DownloadableSubscription.Builder();
+ ctor public DownloadableSubscription.Builder(android.telephony.euicc.DownloadableSubscription);
+ method public android.telephony.euicc.DownloadableSubscription build();
+ method public android.telephony.euicc.DownloadableSubscription.Builder setAccessRules(java.util.List<android.telephony.UiccAccessRule>);
+ method public android.telephony.euicc.DownloadableSubscription.Builder setCarrierName(java.lang.String);
+ method public android.telephony.euicc.DownloadableSubscription.Builder setConfirmationCode(java.lang.String);
+ method public android.telephony.euicc.DownloadableSubscription.Builder setEncodedActivationCode(java.lang.String);
+ }
+
+ public class EuiccCardManager {
+ method public void authenticateServer(java.lang.String, java.lang.String, byte[], byte[], byte[], byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+ method public void cancelSession(java.lang.String, byte[], int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+ method public void deleteProfile(java.lang.String, java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+ method public void disableProfile(java.lang.String, java.lang.String, boolean, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+ method public void listNotifications(java.lang.String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification[]>);
+ method public void loadBoundProfilePackage(java.lang.String, byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+ method public void prepareDownload(java.lang.String, byte[], byte[], byte[], byte[], java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+ method public void removeNotificationFromList(java.lang.String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+ method public void requestAllProfiles(java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo[]>);
+ method public void requestDefaultSmdpAddress(java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.String>);
+ method public void requestEuiccChallenge(java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+ method public void requestEuiccInfo1(java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+ method public void requestEuiccInfo2(java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<byte[]>);
+ method public void requestProfile(java.lang.String, java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo>);
+ method public void requestRulesAuthTable(java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccRulesAuthTable>);
+ method public void requestSmdsAddress(java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.String>);
+ method public void resetMemory(java.lang.String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+ method public void retrieveNotification(java.lang.String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification>);
+ method public void retrieveNotificationList(java.lang.String, int, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.telephony.euicc.EuiccNotification[]>);
+ method public void setDefaultSmdpAddress(java.lang.String, java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+ method public void setNickname(java.lang.String, java.lang.String, java.lang.String, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<java.lang.Void>);
+ method public void switchToProfile(java.lang.String, java.lang.String, boolean, java.util.concurrent.Executor, android.telephony.euicc.EuiccCardManager.ResultCallback<android.service.euicc.EuiccProfileInfo>);
+ field public static final int CANCEL_REASON_END_USER_REJECTED = 0; // 0x0
+ field public static final int CANCEL_REASON_POSTPONED = 1; // 0x1
+ field public static final int CANCEL_REASON_PPR_NOT_ALLOWED = 3; // 0x3
+ field public static final int CANCEL_REASON_TIMEOUT = 2; // 0x2
+ field public static final int RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES = 2; // 0x2
+ field public static final int RESET_OPTION_DELETE_OPERATIONAL_PROFILES = 1; // 0x1
+ field public static final int RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS = 4; // 0x4
+ field public static final int RESULT_OK = 0; // 0x0
+ field public static final int RESULT_UNKNOWN_ERROR = -1; // 0xffffffff
+ }
+
+ public static abstract class EuiccCardManager.CancelReason implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract class EuiccCardManager.ResetOption implements java.lang.annotation.Annotation {
+ }
+
+ public static abstract interface EuiccCardManager.ResultCallback<T> {
+ method public abstract void onComplete(int, T);
+ }
+
+ public class EuiccManager {
+ method public void continueOperation(android.content.Intent, android.os.Bundle);
+ method public void getDefaultDownloadableSubscriptionList(android.app.PendingIntent);
+ method public void getDownloadableSubscriptionMetadata(android.telephony.euicc.DownloadableSubscription, android.app.PendingIntent);
+ method public int getOtaStatus();
+ field public static final java.lang.String ACTION_OTA_STATUS_CHANGED = "android.telephony.euicc.action.OTA_STATUS_CHANGED";
+ field public static final java.lang.String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION = "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
+ field public static final int EUICC_OTA_FAILED = 2; // 0x2
+ field public static final int EUICC_OTA_IN_PROGRESS = 1; // 0x1
+ field public static final int EUICC_OTA_NOT_NEEDED = 4; // 0x4
+ field public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5; // 0x5
+ field public static final int EUICC_OTA_SUCCEEDED = 3; // 0x3
+ field public static final java.lang.String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
+ field public static final java.lang.String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS";
+ }
+
+ public static abstract class EuiccManager.OtaStatus implements java.lang.annotation.Annotation {
+ }
+
+ public final class EuiccNotification implements android.os.Parcelable {
+ ctor public EuiccNotification(int, java.lang.String, int, byte[]);
+ method public int describeContents();
+ method public byte[] getData();
+ method public int getEvent();
+ method public int getSeq();
+ method public java.lang.String getTargetAddr();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final int ALL_EVENTS = 15; // 0xf
+ field public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccNotification> CREATOR;
+ field public static final int EVENT_DELETE = 8; // 0x8
+ field public static final int EVENT_DISABLE = 4; // 0x4
+ field public static final int EVENT_ENABLE = 2; // 0x2
+ field public static final int EVENT_INSTALL = 1; // 0x1
+ }
+
+ public static abstract class EuiccNotification.Event implements java.lang.annotation.Annotation {
+ }
+
+ public final class EuiccRulesAuthTable implements android.os.Parcelable {
+ method public int describeContents();
+ method public int findIndex(int, android.service.carrier.CarrierIdentifier);
+ method public boolean hasPolicyRuleFlag(int, int);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.euicc.EuiccRulesAuthTable> CREATOR;
+ field public static final int POLICY_RULE_FLAG_CONSENT_REQUIRED = 1; // 0x1
+ }
+
+ public static final class EuiccRulesAuthTable.Builder {
+ ctor public EuiccRulesAuthTable.Builder(int);
+ method public android.telephony.euicc.EuiccRulesAuthTable.Builder add(int, java.util.List<android.service.carrier.CarrierIdentifier>, int);
+ method public android.telephony.euicc.EuiccRulesAuthTable build();
+ }
+
+ public static abstract class EuiccRulesAuthTable.PolicyRuleFlag implements java.lang.annotation.Annotation {
+ }
+
+}
+
package android.telephony.ims {
public final class ImsCallForwardInfo implements android.os.Parcelable {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 121b58a..d1500a8 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3134,9 +3134,6 @@
/**
* Flag for {@link #wipeData(int)}: also erase the device's eUICC data.
- *
- * TODO(b/35851809): make this public.
- * @hide
*/
public static final int WIPE_EUICC = 0x0004;
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 6c8fe2e..dc76152 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -2303,6 +2303,9 @@
} else if (profile == BluetoothProfile.HID_DEVICE) {
BluetoothHidDevice hidDevice = new BluetoothHidDevice(context, listener);
return true;
+ } else if (profile == BluetoothProfile.HEARING_AID) {
+ BluetoothHearingAid hearingAid = new BluetoothHearingAid(context, listener);
+ return true;
} else {
return false;
}
@@ -2385,6 +2388,9 @@
BluetoothHidDevice hidDevice = (BluetoothHidDevice) proxy;
hidDevice.close();
break;
+ case BluetoothProfile.HEARING_AID:
+ BluetoothHearingAid hearingAid = (BluetoothHearingAid) proxy;
+ hearingAid.close();
}
}
diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java
new file mode 100644
index 0000000..647e0d0
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothHearingAid.java
@@ -0,0 +1,693 @@
+/*
+ * Copyright 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 android.bluetooth;
+
+import android.Manifest;
+import android.annotation.RequiresPermission;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * This class provides the public APIs to control the Bluetooth Hearing Aid
+ * profile.
+ *
+ * <p>BluetoothHearingAid is a proxy object for controlling the Bluetooth Hearing Aid
+ * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
+ * the BluetoothHearingAid proxy object.
+ *
+ * <p> Each method is protected with its appropriate permission.
+ * @hide
+ */
+public final class BluetoothHearingAid implements BluetoothProfile {
+ private static final String TAG = "BluetoothHearingAid";
+ private static final boolean DBG = false;
+ private static final boolean VDBG = false;
+
+ /**
+ * Intent used to broadcast the change in connection state of the Hearing Aid
+ * profile.
+ *
+ * <p>This intent will have 3 extras:
+ * <ul>
+ * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+ * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+ * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+ * </ul>
+ *
+ * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+ * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
+ * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+ * receive.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_CONNECTION_STATE_CHANGED =
+ "android.bluetooth.hearingaid.profile.action.CONNECTION_STATE_CHANGED";
+
+ /**
+ * Intent used to broadcast the change in the Playing state of the Hearing Aid
+ * profile.
+ *
+ * <p>This intent will have 3 extras:
+ * <ul>
+ * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+ * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile. </li>
+ * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+ * </ul>
+ *
+ * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+ * {@link #STATE_PLAYING}, {@link #STATE_NOT_PLAYING},
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+ * receive.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_PLAYING_STATE_CHANGED =
+ "android.bluetooth.hearingaid.profile.action.PLAYING_STATE_CHANGED";
+
+ /**
+ * Intent used to broadcast the selection of a connected device as active.
+ *
+ * <p>This intent will have one extra:
+ * <ul>
+ * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
+ * be null if no device is active. </li>
+ * </ul>
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+ * receive.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_ACTIVE_DEVICE_CHANGED =
+ "android.bluetooth.hearingaid.profile.action.ACTIVE_DEVICE_CHANGED";
+
+ /**
+ * Hearing Aid device is streaming music. This state can be one of
+ * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
+ * {@link #ACTION_PLAYING_STATE_CHANGED} intent.
+ */
+ public static final int STATE_PLAYING = 10;
+
+ /**
+ * Hearing Aid device is NOT streaming music. This state can be one of
+ * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
+ * {@link #ACTION_PLAYING_STATE_CHANGED} intent.
+ */
+ public static final int STATE_NOT_PLAYING = 11;
+
+ /** This device represents Left Hearing Aid. */
+ public static final int SIDE_LEFT = IBluetoothHearingAid.SIDE_LEFT;
+
+ /** This device represents Right Hearing Aid. */
+ public static final int SIDE_RIGHT = IBluetoothHearingAid.SIDE_RIGHT;
+
+ /** This device is Monaural. */
+ public static final int MODE_MONAURAL = IBluetoothHearingAid.MODE_MONAURAL;
+
+ /** This device is Binaural (should receive only left or right audio). */
+ public static final int MODE_BINAURAL = IBluetoothHearingAid.MODE_BINAURAL;
+
+ /** Can't read ClientID for this device */
+ public static final long HI_SYNC_ID_INVALID = IBluetoothHearingAid.HI_SYNC_ID_INVALID;
+
+ private Context mContext;
+ private ServiceListener mServiceListener;
+ private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
+ @GuardedBy("mServiceLock")
+ private IBluetoothHearingAid mService;
+ private BluetoothAdapter mAdapter;
+
+ private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
+ new IBluetoothStateChangeCallback.Stub() {
+ public void onBluetoothStateChange(boolean up) {
+ if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
+ if (!up) {
+ if (VDBG) Log.d(TAG, "Unbinding service...");
+ try {
+ mServiceLock.writeLock().lock();
+ mService = null;
+ mContext.unbindService(mConnection);
+ } catch (Exception re) {
+ Log.e(TAG, "", re);
+ } finally {
+ mServiceLock.writeLock().unlock();
+ }
+ } else {
+ try {
+ mServiceLock.readLock().lock();
+ if (mService == null) {
+ if (VDBG) Log.d(TAG, "Binding service...");
+ doBind();
+ }
+ } catch (Exception re) {
+ Log.e(TAG, "", re);
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+ }
+ };
+
+ /**
+ * Create a BluetoothHearingAid proxy object for interacting with the local
+ * Bluetooth Hearing Aid service.
+ */
+ /*package*/ BluetoothHearingAid(Context context, ServiceListener l) {
+ mContext = context;
+ mServiceListener = l;
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
+ IBluetoothManager mgr = mAdapter.getBluetoothManager();
+ if (mgr != null) {
+ try {
+ mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ }
+
+ doBind();
+ }
+
+ void doBind() {
+ Intent intent = new Intent(IBluetoothHearingAid.class.getName());
+ ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
+ intent.setComponent(comp);
+ if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+ android.os.Process.myUserHandle())) {
+ Log.e(TAG, "Could not bind to Bluetooth Hearing Aid Service with " + intent);
+ return;
+ }
+ }
+
+ /*package*/ void close() {
+ mServiceListener = null;
+ IBluetoothManager mgr = mAdapter.getBluetoothManager();
+ if (mgr != null) {
+ try {
+ mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
+ } catch (Exception e) {
+ Log.e(TAG, "", e);
+ }
+ }
+
+ try {
+ mServiceLock.writeLock().lock();
+ if (mService != null) {
+ mService = null;
+ mContext.unbindService(mConnection);
+ }
+ } catch (Exception re) {
+ Log.e(TAG, "", re);
+ } finally {
+ mServiceLock.writeLock().unlock();
+ }
+ }
+
+ @Override
+ public void finalize() {
+ // The empty finalize needs to be kept or the
+ // cts signature tests would fail.
+ }
+
+ /**
+ * Initiate connection to a profile of the remote bluetooth device.
+ *
+ * <p> This API returns false in scenarios like the profile on the
+ * device is already connected or Bluetooth is not turned on.
+ * When this API returns true, it is guaranteed that
+ * connection state intent for the profile will be broadcasted with
+ * the state. Users can get the connection state of the profile
+ * from this intent.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+ * permission.
+ *
+ * @param device Remote Bluetooth Device
+ * @return false on immediate error, true otherwise
+ * @hide
+ */
+ public boolean connect(BluetoothDevice device) {
+ if (DBG) log("connect(" + device + ")");
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled() && isValidDevice(device)) {
+ return mService.connect(device);
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Initiate disconnection from a profile
+ *
+ * <p> This API will return false in scenarios like the profile on the
+ * Bluetooth device is not in connected state etc. When this API returns,
+ * true, it is guaranteed that the connection state change
+ * intent will be broadcasted with the state. Users can get the
+ * disconnection state of the profile from this intent.
+ *
+ * <p> If the disconnection is initiated by a remote device, the state
+ * will transition from {@link #STATE_CONNECTED} to
+ * {@link #STATE_DISCONNECTED}. If the disconnect is initiated by the
+ * host (local) device the state will transition from
+ * {@link #STATE_CONNECTED} to state {@link #STATE_DISCONNECTING} to
+ * state {@link #STATE_DISCONNECTED}. The transition to
+ * {@link #STATE_DISCONNECTING} can be used to distinguish between the
+ * two scenarios.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+ * permission.
+ *
+ * @param device Remote Bluetooth Device
+ * @return false on immediate error, true otherwise
+ * @hide
+ */
+ public boolean disconnect(BluetoothDevice device) {
+ if (DBG) log("disconnect(" + device + ")");
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled() && isValidDevice(device)) {
+ return mService.disconnect(device);
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<BluetoothDevice> getConnectedDevices() {
+ if (VDBG) log("getConnectedDevices()");
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled()) {
+ return mService.getConnectedDevices();
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return new ArrayList<BluetoothDevice>();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return new ArrayList<BluetoothDevice>();
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+ if (VDBG) log("getDevicesMatchingStates()");
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled()) {
+ return mService.getDevicesMatchingConnectionStates(states);
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return new ArrayList<BluetoothDevice>();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return new ArrayList<BluetoothDevice>();
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getConnectionState(BluetoothDevice device) {
+ if (VDBG) log("getState(" + device + ")");
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ return mService.getConnectionState(device);
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return BluetoothProfile.STATE_DISCONNECTED;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return BluetoothProfile.STATE_DISCONNECTED;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Set priority of the profile
+ *
+ * <p> The device should already be paired.
+ * Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
+ * {@link #PRIORITY_OFF},
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
+ * permission.
+ *
+ * @param device Paired bluetooth device
+ * @param priority
+ * @return true if priority is set, false on error
+ * @hide
+ */
+ public boolean setPriority(BluetoothDevice device, int priority) {
+ if (DBG) log("setPriority(" + device + ", " + priority + ")");
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ if (priority != BluetoothProfile.PRIORITY_OFF
+ && priority != BluetoothProfile.PRIORITY_ON) {
+ return false;
+ }
+ return mService.setPriority(device, priority);
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Get the priority of the profile.
+ *
+ * <p> The priority can be any of:
+ * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
+ * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
+ *
+ * @param device Bluetooth device
+ * @return priority of the device
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public int getPriority(BluetoothDevice device) {
+ if (VDBG) log("getPriority(" + device + ")");
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ return mService.getPriority(device);
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return BluetoothProfile.PRIORITY_OFF;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return BluetoothProfile.PRIORITY_OFF;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Helper for converting a state to a string.
+ *
+ * For debug use only - strings are not internationalized.
+ *
+ * @hide
+ */
+ public static String stateToString(int state) {
+ switch (state) {
+ case STATE_DISCONNECTED:
+ return "disconnected";
+ case STATE_CONNECTING:
+ return "connecting";
+ case STATE_CONNECTED:
+ return "connected";
+ case STATE_DISCONNECTING:
+ return "disconnecting";
+ case STATE_PLAYING:
+ return "playing";
+ case STATE_NOT_PLAYING:
+ return "not playing";
+ default:
+ return "<unknown state " + state + ">";
+ }
+ }
+
+ /**
+ * Get the volume of the device.
+ *
+ * <p> The volume is between -128 dB (mute) to 0 dB.
+ *
+ * @return volume of the hearing aid device.
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public int getVolume() {
+ if (VDBG) {
+ log("getVolume()");
+ }
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled()) {
+ return mService.getVolume();
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return 0;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return 0;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Tells remote device to adjust volume. Uses the following values:
+ * <ul>
+ * <li>{@link AudioManager#ADJUST_LOWER}</li>
+ * <li>{@link AudioManager#ADJUST_RAISE}</li>
+ * <li>{@link AudioManager#ADJUST_MUTE}</li>
+ * <li>{@link AudioManager#ADJUST_UNMUTE}</li>
+ * </ul>
+ *
+ * @param direction One of the supported adjust values.
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public void adjustVolume(int direction) {
+ if (DBG) log("adjustVolume(" + direction + ")");
+
+ try {
+ mServiceLock.readLock().lock();
+
+ if (mService == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ return;
+ }
+
+ if (!isEnabled()) return;
+
+ mService.adjustVolume(direction);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Tells remote device to set an absolute volume.
+ *
+ * @param volume Absolute volume to be set on remote
+ * @hide
+ */
+ public void setVolume(int volume) {
+ if (DBG) Log.d(TAG, "setVolume(" + volume + ")");
+
+ try {
+ mServiceLock.readLock().lock();
+ if (mService == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ return;
+ }
+
+ if (!isEnabled()) return;
+
+ mService.setVolume(volume);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Get the CustomerId of the device.
+ *
+ * @param device Bluetooth device
+ * @return the CustomerId of the device
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public long getHiSyncId(BluetoothDevice device) {
+ if (VDBG) {
+ log("getCustomerId(" + device + ")");
+ }
+ try {
+ mServiceLock.readLock().lock();
+ if (mService == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ return HI_SYNC_ID_INVALID;
+ }
+
+ if (!isEnabled() || !isValidDevice(device)) return HI_SYNC_ID_INVALID;
+
+ return mService.getHiSyncId(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return HI_SYNC_ID_INVALID;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Get the side of the device.
+ *
+ * @param device Bluetooth device.
+ * @return SIDE_LEFT or SIDE_RIGHT
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public int getDeviceSide(BluetoothDevice device) {
+ if (VDBG) {
+ log("getDeviceSide(" + device + ")");
+ }
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ return mService.getDeviceSide(device);
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return SIDE_LEFT;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return SIDE_LEFT;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Get the mode of the device.
+ *
+ * @param device Bluetooth device
+ * @return MODE_MONAURAL or MODE_BINAURAL
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public int getDeviceMode(BluetoothDevice device) {
+ if (VDBG) {
+ log("getDeviceMode(" + device + ")");
+ }
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ return mService.getDeviceMode(device);
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return MODE_MONAURAL;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return MODE_MONAURAL;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ private final ServiceConnection mConnection = new ServiceConnection() {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ if (DBG) Log.d(TAG, "Proxy object connected");
+ try {
+ mServiceLock.writeLock().lock();
+ mService = IBluetoothHearingAid.Stub.asInterface(Binder.allowBlocking(service));
+ } finally {
+ mServiceLock.writeLock().unlock();
+ }
+
+ if (mServiceListener != null) {
+ mServiceListener.onServiceConnected(BluetoothProfile.HEARING_AID,
+ BluetoothHearingAid.this);
+ }
+ }
+
+ public void onServiceDisconnected(ComponentName className) {
+ if (DBG) Log.d(TAG, "Proxy object disconnected");
+ try {
+ mServiceLock.writeLock().lock();
+ mService = null;
+ } finally {
+ mServiceLock.writeLock().unlock();
+ }
+ if (mServiceListener != null) {
+ mServiceListener.onServiceDisconnected(BluetoothProfile.HEARING_AID);
+ }
+ }
+ };
+
+ private boolean isEnabled() {
+ if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
+ return false;
+ }
+
+ private boolean isValidDevice(BluetoothDevice device) {
+ if (device == null) return false;
+
+ if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
+ return false;
+ }
+
+ private static void log(String msg) {
+ Log.d(TAG, msg);
+ }
+}
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index 0e2263f..656188f 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -165,12 +165,19 @@
public static final int OPP = 20;
/**
+ * Hearing Aid Device
+ *
+ * @hide
+ */
+ int HEARING_AID = 21;
+
+ /**
* Max profile ID. This value should be updated whenever a new profile is added to match
* the largest value assigned to a profile.
*
* @hide
*/
- public static final int MAX_PROFILE_ID = 20;
+ int MAX_PROFILE_ID = 21;
/**
* Default priority for devices that we try to auto-connect to and
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 76cb3f5..0a0d214 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -79,6 +79,9 @@
ParcelUuid.fromString("00001132-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid SAP =
ParcelUuid.fromString("0000112D-0000-1000-8000-00805F9B34FB");
+ /* TODO: b/69623109 update this value. It will change to 16bit UUID!! */
+ public static final ParcelUuid HearingAid =
+ ParcelUuid.fromString("7312C48F-22CC-497F-85FD-A0616A3B9E05");
public static final ParcelUuid BASE_UUID =
ParcelUuid.fromString("00000000-0000-1000-8000-00805F9B34FB");
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 2859326..d135758 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3583,10 +3583,8 @@
*
* @see #getSystemService
* @see android.telephony.euicc.EuiccManager
- * TODO(b/35851809): Unhide this API.
- * @hide
*/
- public static final String EUICC_SERVICE = "euicc_service";
+ public static final String EUICC_SERVICE = "euicc";
/**
* Use with {@link #getSystemService(String)} to retrieve a
@@ -3594,10 +3592,10 @@
*
* @see #getSystemService(String)
* @see android.telephony.euicc.EuiccCardManager
- * TODO(b/35851809): Make this a SystemApi.
* @hide
*/
- public static final String EUICC_CARD_SERVICE = "euicc_card_service";
+ @SystemApi
+ public static final String EUICC_CARD_SERVICE = "euicc_card";
/**
* Use with {@link #getSystemService(String)} to retrieve a
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 89751da..e7bf974 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2078,8 +2078,6 @@
/**
* Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device
* supports embedded subscriptions on eUICCs.
- * TODO(b/35851809): Make this public.
- * @hide
*/
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_TELEPHONY_EUICC = "android.hardware.telephony.euicc";
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 11d338d..2e70132 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -112,8 +112,14 @@
* <p/>
* For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY
* is set to {@code true} if there are no connected networks at all.
+ *
+ * @deprecated apps should use the more versatile {@link #requestNetwork},
+ * {@link #registerNetworkCallback} or {@link #registerDefaultNetworkCallback}
+ * functions instead for faster and more detailed updates about the network
+ * changes they care about.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @Deprecated
public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
/**
@@ -2685,6 +2691,32 @@
* satisfying the request changes.
*
* @param network The {@link Network} of the satisfying network.
+ * @param networkCapabilities The {@link NetworkCapabilities} of the satisfying network.
+ * @param linkProperties The {@link LinkProperties} of the satisfying network.
+ * @hide
+ */
+ public void onAvailable(Network network, NetworkCapabilities networkCapabilities,
+ LinkProperties linkProperties) {
+ // Internally only this method is called when a new network is available, and
+ // it calls the callback in the same way and order that older versions used
+ // to call so as not to change the behavior.
+ onAvailable(network);
+ if (!networkCapabilities.hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)) {
+ onNetworkSuspended(network);
+ }
+ onCapabilitiesChanged(network, networkCapabilities);
+ onLinkPropertiesChanged(network, linkProperties);
+ }
+
+ /**
+ * Called when the framework connects and has declared a new network ready for use.
+ * This callback may be called more than once if the {@link Network} that is
+ * satisfying the request changes. This will always immediately be followed by a
+ * call to {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} then by a
+ * call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}.
+ *
+ * @param network The {@link Network} of the satisfying network.
*/
public void onAvailable(Network network) {}
@@ -2727,7 +2759,8 @@
* changes capabilities but still satisfies the stated need.
*
* @param network The {@link Network} whose capabilities have changed.
- * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this network.
+ * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this
+ * network.
*/
public void onCapabilitiesChanged(Network network,
NetworkCapabilities networkCapabilities) {}
@@ -2743,7 +2776,7 @@
/**
* Called when the network the framework connected to for this request
- * goes into {@link NetworkInfo.DetailedState.SUSPENDED}.
+ * goes into {@link NetworkInfo.State#SUSPENDED}.
* This generally means that while the TCP connections are still live,
* temporarily network data fails to transfer. Specifically this is used
* on cellular networks to mask temporary outages when driving through
@@ -2754,9 +2787,8 @@
/**
* Called when the network the framework connected to for this request
- * returns from a {@link NetworkInfo.DetailedState.SUSPENDED} state.
- * This should always be preceeded by a matching {@code onNetworkSuspended}
- * call.
+ * returns from a {@link NetworkInfo.State#SUSPENDED} state. This should always be
+ * preceded by a matching {@link NetworkCallback#onNetworkSuspended} call.
* @hide
*/
public void onNetworkResumed(Network network) {}
@@ -2865,7 +2897,9 @@
break;
}
case CALLBACK_AVAILABLE: {
- callback.onAvailable(network);
+ NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
+ LinkProperties lp = getObject(message, LinkProperties.class);
+ callback.onAvailable(network, cap, lp);
break;
}
case CALLBACK_LOSING: {
diff --git a/core/java/android/net/IpSecConfig.java b/core/java/android/net/IpSecConfig.java
index 6a262e2..8599f47 100644
--- a/core/java/android/net/IpSecConfig.java
+++ b/core/java/android/net/IpSecConfig.java
@@ -218,6 +218,25 @@
@VisibleForTesting
public IpSecConfig() {}
+ /** Copy constructor */
+ @VisibleForTesting
+ public IpSecConfig(IpSecConfig c) {
+ mMode = c.mMode;
+ mSourceAddress = c.mSourceAddress;
+ mDestinationAddress = c.mDestinationAddress;
+ mNetwork = c.mNetwork;
+ mSpiResourceId = c.mSpiResourceId;
+ mEncryption = c.mEncryption;
+ mAuthentication = c.mAuthentication;
+ mAuthenticatedEncryption = c.mAuthenticatedEncryption;
+ mEncapType = c.mEncapType;
+ mEncapSocketResourceId = c.mEncapSocketResourceId;
+ mEncapRemotePort = c.mEncapRemotePort;
+ mNattKeepaliveInterval = c.mNattKeepaliveInterval;
+ mMarkValue = c.mMarkValue;
+ mMarkMask = c.mMarkMask;
+ }
+
private IpSecConfig(Parcel in) {
mMode = in.readInt();
mSourceAddress = in.readString();
diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java
index 38759a9..60e96f9 100644
--- a/core/java/android/net/IpSecTransform.java
+++ b/core/java/android/net/IpSecTransform.java
@@ -84,9 +84,11 @@
@Retention(RetentionPolicy.SOURCE)
public @interface EncapType {}
- private IpSecTransform(Context context, IpSecConfig config) {
+ /** @hide */
+ @VisibleForTesting
+ public IpSecTransform(Context context, IpSecConfig config) {
mContext = context;
- mConfig = config;
+ mConfig = new IpSecConfig(config);
mResourceId = INVALID_RESOURCE_ID;
}
@@ -143,6 +145,18 @@
}
/**
+ * Equals method used for testing
+ *
+ * @hide
+ */
+ @VisibleForTesting
+ public static boolean equals(IpSecTransform lhs, IpSecTransform rhs) {
+ if (lhs == null || rhs == null) return (lhs == rhs);
+ return IpSecConfig.equals(lhs.getConfig(), rhs.getConfig())
+ && lhs.mResourceId == rhs.mResourceId;
+ }
+
+ /**
* Deactivate this {@code IpSecTransform} and free allocated resources.
*
* <p>Deactivating a transform while it is still applied to a socket will result in errors on
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index e81ed9a..bc4d955 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -116,6 +116,7 @@
NET_CAPABILITY_NOT_ROAMING,
NET_CAPABILITY_FOREGROUND,
NET_CAPABILITY_NOT_CONGESTED,
+ NET_CAPABILITY_NOT_SUSPENDED,
})
public @interface NetCapability { }
@@ -239,7 +240,6 @@
/**
* Indicates that this network is available for use by apps, and not a network that is being
* kept up in the background to facilitate fast network switching.
- * @hide
*/
public static final int NET_CAPABILITY_FOREGROUND = 19;
@@ -252,8 +252,20 @@
*/
public static final int NET_CAPABILITY_NOT_CONGESTED = 20;
+ /**
+ * Indicates that this network is not currently suspended.
+ * <p>
+ * When a network is suspended, the network's IP addresses and any connections
+ * established on the network remain valid, but the network is temporarily unable
+ * to transfer data. This can happen, for example, if a cellular network experiences
+ * a temporary loss of signal, such as when driving through a tunnel, etc.
+ * A network with this capability is not suspended, so is expected to be able to
+ * transfer data.
+ */
+ public static final int NET_CAPABILITY_NOT_SUSPENDED = 21;
+
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
- private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_CONGESTED;
+ private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_SUSPENDED;
/**
* Network capabilities that are expected to be mutable, i.e., can change while a particular
@@ -262,12 +274,13 @@
private static final long MUTABLE_CAPABILITIES =
// TRUSTED can change when user explicitly connects to an untrusted network in Settings.
// http://b/18206275
- (1 << NET_CAPABILITY_TRUSTED) |
- (1 << NET_CAPABILITY_VALIDATED) |
- (1 << NET_CAPABILITY_CAPTIVE_PORTAL) |
- (1 << NET_CAPABILITY_NOT_ROAMING) |
- (1 << NET_CAPABILITY_FOREGROUND) |
- (1 << NET_CAPABILITY_NOT_CONGESTED);
+ (1 << NET_CAPABILITY_TRUSTED)
+ | (1 << NET_CAPABILITY_VALIDATED)
+ | (1 << NET_CAPABILITY_CAPTIVE_PORTAL)
+ | (1 << NET_CAPABILITY_NOT_ROAMING)
+ | (1 << NET_CAPABILITY_FOREGROUND)
+ | (1 << NET_CAPABILITY_NOT_CONGESTED)
+ | (1 << NET_CAPABILITY_NOT_SUSPENDED);
/**
* Network capabilities that are not allowed in NetworkRequests. This exists because the
@@ -1276,6 +1289,7 @@
case NET_CAPABILITY_NOT_ROAMING: return "NOT_ROAMING";
case NET_CAPABILITY_FOREGROUND: return "FOREGROUND";
case NET_CAPABILITY_NOT_CONGESTED: return "NOT_CONGESTED";
+ case NET_CAPABILITY_NOT_SUSPENDED: return "NOT_SUSPENDED";
default: return Integer.toString(capability);
}
}
diff --git a/core/java/android/net/OWNERS b/core/java/android/net/OWNERS
index 3a40cf4..3cd37bf 100644
--- a/core/java/android/net/OWNERS
+++ b/core/java/android/net/OWNERS
@@ -1,3 +1,5 @@
+set noparent
+
ek@google.com
jsharkey@android.com
jchalard@google.com
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 670f794..4a97640 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -61,18 +61,27 @@
/**
* The name of the socket used to communicate with the primary zygote.
*/
- private final String mSocket;
+ private final LocalSocketAddress mSocket;
/**
* The name of the secondary (alternate ABI) zygote socket.
*/
- private final String mSecondarySocket;
+ private final LocalSocketAddress mSecondarySocket;
public ZygoteProcess(String primarySocket, String secondarySocket) {
+ this(new LocalSocketAddress(primarySocket, LocalSocketAddress.Namespace.RESERVED),
+ new LocalSocketAddress(secondarySocket, LocalSocketAddress.Namespace.RESERVED));
+ }
+
+ public ZygoteProcess(LocalSocketAddress primarySocket, LocalSocketAddress secondarySocket) {
mSocket = primarySocket;
mSecondarySocket = secondarySocket;
}
+ public LocalSocketAddress getPrimarySocketAddress() {
+ return mSocket;
+ }
+
/**
* State for communicating with the zygote process.
*/
@@ -92,14 +101,13 @@
this.abiList = abiList;
}
- public static ZygoteState connect(String socketAddress) throws IOException {
+ public static ZygoteState connect(LocalSocketAddress address) throws IOException {
DataInputStream zygoteInputStream = null;
BufferedWriter zygoteWriter = null;
final LocalSocket zygoteSocket = new LocalSocket();
try {
- zygoteSocket.connect(new LocalSocketAddress(socketAddress,
- LocalSocketAddress.Namespace.RESERVED));
+ zygoteSocket.connect(address);
zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream());
@@ -115,8 +123,8 @@
}
String abiListString = getAbiList(zygoteWriter, zygoteInputStream);
- Log.i("Zygote", "Process: zygote socket " + socketAddress + " opened, supported ABIS: "
- + abiListString);
+ Log.i("Zygote", "Process: zygote socket " + address.getNamespace() + "/"
+ + address.getName() + " opened, supported ABIS: " + abiListString);
return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
Arrays.asList(abiListString.split(",")));
@@ -514,9 +522,19 @@
* @param socketName The name of the socket to connect to.
*/
public static void waitForConnectionToZygote(String socketName) {
+ final LocalSocketAddress address =
+ new LocalSocketAddress(socketName, LocalSocketAddress.Namespace.RESERVED);
+ waitForConnectionToZygote(address);
+ }
+
+ /**
+ * Try connecting to the Zygote over and over again until we hit a time-out.
+ * @param address The name of the socket to connect to.
+ */
+ public static void waitForConnectionToZygote(LocalSocketAddress address) {
for (int n = 20; n >= 0; n--) {
try {
- final ZygoteState zs = ZygoteState.connect(socketName);
+ final ZygoteState zs = ZygoteState.connect(address);
zs.close();
return;
} catch (IOException ioe) {
@@ -529,6 +547,6 @@
} catch (InterruptedException ie) {
}
}
- Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket " + socketName);
+ Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket " + address.getName());
}
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7ad4373..5dd4681 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7838,9 +7838,8 @@
*
* @see android.service.euicc.EuiccService
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
public static final String DEFAULT_SM_DP_PLUS = "default_sm_dp_plus";
/**
diff --git a/core/java/android/service/euicc/EuiccProfileInfo.java b/core/java/android/service/euicc/EuiccProfileInfo.java
index 8e752d1..cb4f104 100644
--- a/core/java/android/service/euicc/EuiccProfileInfo.java
+++ b/core/java/android/service/euicc/EuiccProfileInfo.java
@@ -17,6 +17,7 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.carrier.CarrierIdentifier;
@@ -26,15 +27,15 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
+import java.util.List;
import java.util.Objects;
/**
* Information about an embedded profile (subscription) on an eUICC.
*
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+@SystemApi
public final class EuiccProfileInfo implements Parcelable {
/** Profile policy rules (bit mask) */
@@ -44,6 +45,7 @@
POLICY_RULE_DO_NOT_DELETE,
POLICY_RULE_DELETE_AFTER_DISABLING
})
+ /** @hide */
public @interface PolicyRule {}
/** Once this profile is enabled, it cannot be disabled. */
public static final int POLICY_RULE_DO_NOT_DISABLE = 1;
@@ -60,6 +62,7 @@
PROFILE_CLASS_OPERATIONAL,
PROFILE_CLASS_UNSET
})
+ /** @hide */
public @interface ProfileClass {}
/** Testing profiles */
public static final int PROFILE_CLASS_TESTING = 0;
@@ -80,6 +83,7 @@
PROFILE_STATE_ENABLED,
PROFILE_STATE_UNSET
})
+ /** @hide */
public @interface ProfileState {}
/** Disabled profiles */
public static final int PROFILE_STATE_DISABLED = 0;
@@ -92,34 +96,34 @@
public static final int PROFILE_STATE_UNSET = -1;
/** The iccid of the subscription. */
- public final String iccid;
+ private final String mIccid;
/** An optional nickname for the subscription. */
- public final @Nullable String nickname;
+ private final @Nullable String mNickname;
/** The service provider name for the subscription. */
- public final String serviceProviderName;
+ private final String mServiceProviderName;
/** The profile name for the subscription. */
- public final String profileName;
+ private final String mProfileName;
/** Profile class for the subscription. */
- @ProfileClass public final int profileClass;
+ @ProfileClass private final int mProfileClass;
/** The profile state of the subscription. */
- @ProfileState public final int state;
+ @ProfileState private final int mState;
/** The operator Id of the subscription. */
- public final CarrierIdentifier carrierIdentifier;
+ private final CarrierIdentifier mCarrierIdentifier;
/** The policy rules of the subscription. */
- @PolicyRule public final int policyRules;
+ @PolicyRule private final int mPolicyRules;
/**
* Optional access rules defining which apps can manage this subscription. If unset, only the
* platform can manage it.
*/
- public final @Nullable UiccAccessRule[] accessRules;
+ private final @Nullable UiccAccessRule[] mAccessRules;
public static final Creator<EuiccProfileInfo> CREATOR = new Creator<EuiccProfileInfo>() {
@Override
@@ -144,51 +148,51 @@
if (!TextUtils.isDigitsOnly(iccid)) {
throw new IllegalArgumentException("iccid contains invalid characters: " + iccid);
}
- this.iccid = iccid;
- this.accessRules = accessRules;
- this.nickname = nickname;
+ this.mIccid = iccid;
+ this.mAccessRules = accessRules;
+ this.mNickname = nickname;
- this.serviceProviderName = null;
- this.profileName = null;
- this.profileClass = PROFILE_CLASS_UNSET;
- this.state = PROFILE_CLASS_UNSET;
- this.carrierIdentifier = null;
- this.policyRules = 0;
+ this.mServiceProviderName = null;
+ this.mProfileName = null;
+ this.mProfileClass = PROFILE_CLASS_UNSET;
+ this.mState = PROFILE_STATE_UNSET;
+ this.mCarrierIdentifier = null;
+ this.mPolicyRules = 0;
}
private EuiccProfileInfo(Parcel in) {
- iccid = in.readString();
- nickname = in.readString();
- serviceProviderName = in.readString();
- profileName = in.readString();
- profileClass = in.readInt();
- state = in.readInt();
+ mIccid = in.readString();
+ mNickname = in.readString();
+ mServiceProviderName = in.readString();
+ mProfileName = in.readString();
+ mProfileClass = in.readInt();
+ mState = in.readInt();
byte exist = in.readByte();
if (exist == (byte) 1) {
- carrierIdentifier = CarrierIdentifier.CREATOR.createFromParcel(in);
+ mCarrierIdentifier = CarrierIdentifier.CREATOR.createFromParcel(in);
} else {
- carrierIdentifier = null;
+ mCarrierIdentifier = null;
}
- policyRules = in.readInt();
- accessRules = in.createTypedArray(UiccAccessRule.CREATOR);
+ mPolicyRules = in.readInt();
+ mAccessRules = in.createTypedArray(UiccAccessRule.CREATOR);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(iccid);
- dest.writeString(nickname);
- dest.writeString(serviceProviderName);
- dest.writeString(profileName);
- dest.writeInt(profileClass);
- dest.writeInt(state);
- if (carrierIdentifier != null) {
+ dest.writeString(mIccid);
+ dest.writeString(mNickname);
+ dest.writeString(mServiceProviderName);
+ dest.writeString(mProfileName);
+ dest.writeInt(mProfileClass);
+ dest.writeInt(mState);
+ if (mCarrierIdentifier != null) {
dest.writeByte((byte) 1);
- carrierIdentifier.writeToParcel(dest, flags);
+ mCarrierIdentifier.writeToParcel(dest, flags);
} else {
dest.writeByte((byte) 0);
}
- dest.writeInt(policyRules);
- dest.writeTypedArray(accessRules, flags);
+ dest.writeInt(mPolicyRules);
+ dest.writeTypedArray(mAccessRules, flags);
}
@Override
@@ -198,45 +202,50 @@
/** The builder to build a new {@link EuiccProfileInfo} instance. */
public static final class Builder {
- public String iccid;
- public UiccAccessRule[] accessRules;
- public String nickname;
- public String serviceProviderName;
- public String profileName;
- @ProfileClass public int profileClass;
- @ProfileState public int state;
- public CarrierIdentifier carrierIdentifier;
- @PolicyRule public int policyRules;
+ private String mIccid;
+ private List<UiccAccessRule> mAccessRules;
+ private String mNickname;
+ private String mServiceProviderName;
+ private String mProfileName;
+ @ProfileClass private int mProfileClass;
+ @ProfileState private int mState;
+ private CarrierIdentifier mCarrierIdentifier;
+ @PolicyRule private int mPolicyRules;
- public Builder() {}
+ public Builder(String value) {
+ if (!TextUtils.isDigitsOnly(value)) {
+ throw new IllegalArgumentException("iccid contains invalid characters: " + value);
+ }
+ mIccid = value;
+ }
public Builder(EuiccProfileInfo baseProfile) {
- iccid = baseProfile.iccid;
- nickname = baseProfile.nickname;
- serviceProviderName = baseProfile.serviceProviderName;
- profileName = baseProfile.profileName;
- profileClass = baseProfile.profileClass;
- state = baseProfile.state;
- carrierIdentifier = baseProfile.carrierIdentifier;
- policyRules = baseProfile.policyRules;
- accessRules = baseProfile.accessRules;
+ mIccid = baseProfile.mIccid;
+ mNickname = baseProfile.mNickname;
+ mServiceProviderName = baseProfile.mServiceProviderName;
+ mProfileName = baseProfile.mProfileName;
+ mProfileClass = baseProfile.mProfileClass;
+ mState = baseProfile.mState;
+ mCarrierIdentifier = baseProfile.mCarrierIdentifier;
+ mPolicyRules = baseProfile.mPolicyRules;
+ mAccessRules = Arrays.asList(baseProfile.mAccessRules);
}
/** Builds the profile instance. */
public EuiccProfileInfo build() {
- if (iccid == null) {
+ if (mIccid == null) {
throw new IllegalStateException("ICCID must be set for a profile.");
}
return new EuiccProfileInfo(
- iccid,
- nickname,
- serviceProviderName,
- profileName,
- profileClass,
- state,
- carrierIdentifier,
- policyRules,
- accessRules);
+ mIccid,
+ mNickname,
+ mServiceProviderName,
+ mProfileName,
+ mProfileClass,
+ mState,
+ mCarrierIdentifier,
+ mPolicyRules,
+ mAccessRules);
}
/** Sets the iccId of the subscription. */
@@ -244,55 +253,55 @@
if (!TextUtils.isDigitsOnly(value)) {
throw new IllegalArgumentException("iccid contains invalid characters: " + value);
}
- iccid = value;
+ mIccid = value;
return this;
}
/** Sets the nickname of the subscription. */
public Builder setNickname(String value) {
- nickname = value;
+ mNickname = value;
return this;
}
/** Sets the service provider name of the subscription. */
public Builder setServiceProviderName(String value) {
- serviceProviderName = value;
+ mServiceProviderName = value;
return this;
}
/** Sets the profile name of the subscription. */
public Builder setProfileName(String value) {
- profileName = value;
+ mProfileName = value;
return this;
}
/** Sets the profile class of the subscription. */
public Builder setProfileClass(@ProfileClass int value) {
- profileClass = value;
+ mProfileClass = value;
return this;
}
/** Sets the state of the subscription. */
public Builder setState(@ProfileState int value) {
- state = value;
+ mState = value;
return this;
}
/** Sets the carrier identifier of the subscription. */
public Builder setCarrierIdentifier(CarrierIdentifier value) {
- carrierIdentifier = value;
+ mCarrierIdentifier = value;
return this;
}
/** Sets the policy rules of the subscription. */
public Builder setPolicyRules(@PolicyRule int value) {
- policyRules = value;
+ mPolicyRules = value;
return this;
}
/** Sets the access rules of the subscription. */
- public Builder setUiccAccessRule(@Nullable UiccAccessRule[] value) {
- accessRules = value;
+ public Builder setUiccAccessRule(@Nullable List<UiccAccessRule> value) {
+ mAccessRules = value;
return this;
}
}
@@ -306,75 +315,81 @@
@ProfileState int state,
CarrierIdentifier carrierIdentifier,
@PolicyRule int policyRules,
- @Nullable UiccAccessRule[] accessRules) {
- this.iccid = iccid;
- this.nickname = nickname;
- this.serviceProviderName = serviceProviderName;
- this.profileName = profileName;
- this.profileClass = profileClass;
- this.state = state;
- this.carrierIdentifier = carrierIdentifier;
- this.policyRules = policyRules;
- this.accessRules = accessRules;
+ @Nullable List<UiccAccessRule> accessRules) {
+ this.mIccid = iccid;
+ this.mNickname = nickname;
+ this.mServiceProviderName = serviceProviderName;
+ this.mProfileName = profileName;
+ this.mProfileClass = profileClass;
+ this.mState = state;
+ this.mCarrierIdentifier = carrierIdentifier;
+ this.mPolicyRules = policyRules;
+ if (accessRules != null && accessRules.size() > 0) {
+ this.mAccessRules = accessRules.toArray(new UiccAccessRule[accessRules.size()]);
+ } else {
+ this.mAccessRules = null;
+ }
}
/** Gets the ICCID string. */
public String getIccid() {
- return iccid;
+ return mIccid;
}
/** Gets the access rules. */
@Nullable
- public UiccAccessRule[] getUiccAccessRules() {
- return accessRules;
+ public List<UiccAccessRule> getUiccAccessRules() {
+ if (mAccessRules == null) return null;
+ return Arrays.asList(mAccessRules);
}
/** Gets the nickname. */
+ @Nullable
public String getNickname() {
- return nickname;
+ return mNickname;
}
/** Gets the service provider name. */
public String getServiceProviderName() {
- return serviceProviderName;
+ return mServiceProviderName;
}
/** Gets the profile name. */
public String getProfileName() {
- return profileName;
+ return mProfileName;
}
/** Gets the profile class. */
@ProfileClass
public int getProfileClass() {
- return profileClass;
+ return mProfileClass;
}
/** Gets the state of the subscription. */
@ProfileState
public int getState() {
- return state;
+ return mState;
}
/** Gets the carrier identifier. */
public CarrierIdentifier getCarrierIdentifier() {
- return carrierIdentifier;
+ return mCarrierIdentifier;
}
/** Gets the policy rules. */
@PolicyRule
public int getPolicyRules() {
- return policyRules;
+ return mPolicyRules;
}
/** Returns whether any policy rule exists. */
public boolean hasPolicyRules() {
- return policyRules != 0;
+ return mPolicyRules != 0;
}
/** Checks whether a certain policy rule exists. */
public boolean hasPolicyRule(@PolicyRule int policy) {
- return (policyRules & policy) != 0;
+ return (mPolicyRules & policy) != 0;
}
@Override
@@ -387,50 +402,50 @@
}
EuiccProfileInfo that = (EuiccProfileInfo) obj;
- return Objects.equals(iccid, that.iccid)
- && Objects.equals(nickname, that.nickname)
- && Objects.equals(serviceProviderName, that.serviceProviderName)
- && Objects.equals(profileName, that.profileName)
- && profileClass == that.profileClass
- && state == that.state
- && Objects.equals(carrierIdentifier, that.carrierIdentifier)
- && policyRules == that.policyRules
- && Arrays.equals(accessRules, that.accessRules);
+ return Objects.equals(mIccid, that.mIccid)
+ && Objects.equals(mNickname, that.mNickname)
+ && Objects.equals(mServiceProviderName, that.mServiceProviderName)
+ && Objects.equals(mProfileName, that.mProfileName)
+ && mProfileClass == that.mProfileClass
+ && mState == that.mState
+ && Objects.equals(mCarrierIdentifier, that.mCarrierIdentifier)
+ && mPolicyRules == that.mPolicyRules
+ && Arrays.equals(mAccessRules, that.mAccessRules);
}
@Override
public int hashCode() {
int result = 1;
- result = 31 * result + Objects.hashCode(iccid);
- result = 31 * result + Objects.hashCode(nickname);
- result = 31 * result + Objects.hashCode(serviceProviderName);
- result = 31 * result + Objects.hashCode(profileName);
- result = 31 * result + profileClass;
- result = 31 * result + state;
- result = 31 * result + Objects.hashCode(carrierIdentifier);
- result = 31 * result + policyRules;
- result = 31 * result + Arrays.hashCode(accessRules);
+ result = 31 * result + Objects.hashCode(mIccid);
+ result = 31 * result + Objects.hashCode(mNickname);
+ result = 31 * result + Objects.hashCode(mServiceProviderName);
+ result = 31 * result + Objects.hashCode(mProfileName);
+ result = 31 * result + mProfileClass;
+ result = 31 * result + mState;
+ result = 31 * result + Objects.hashCode(mCarrierIdentifier);
+ result = 31 * result + mPolicyRules;
+ result = 31 * result + Arrays.hashCode(mAccessRules);
return result;
}
@Override
public String toString() {
return "EuiccProfileInfo (nickname="
- + nickname
+ + mNickname
+ ", serviceProviderName="
- + serviceProviderName
+ + mServiceProviderName
+ ", profileName="
- + profileName
+ + mProfileName
+ ", profileClass="
- + profileClass
+ + mProfileClass
+ ", state="
- + state
+ + mState
+ ", CarrierIdentifier="
- + carrierIdentifier.toString()
+ + mCarrierIdentifier.toString()
+ ", policyRules="
- + policyRules
+ + mPolicyRules
+ ", accessRules="
- + Arrays.toString(accessRules)
+ + Arrays.toString(mAccessRules)
+ ")";
}
}
diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java
index be85800..b87faef 100644
--- a/core/java/android/service/euicc/EuiccService.java
+++ b/core/java/android/service/euicc/EuiccService.java
@@ -17,6 +17,7 @@
import android.annotation.CallSuper;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
@@ -41,8 +42,11 @@
* <p>To implement the LPA backend, you must extend this class and declare this service in your
* manifest file. The service must require the
* {@link android.Manifest.permission#BIND_EUICC_SERVICE} permission and include an intent filter
- * with the {@link #EUICC_SERVICE_INTERFACE} action. The priority of the intent filter must be set
- * to a non-zero value in case multiple implementations are present on the device. For example:
+ * with the {@link #EUICC_SERVICE_INTERFACE} action. It's suggested that the priority of the intent
+ * filter to be set to a non-zero value in case multiple implementations are present on the device.
+ * See the below example. Note that there will be problem if two LPAs are present and they have the
+ * same priority.
+ * Example:
*
* <pre>{@code
* <service android:name=".MyEuiccService"
@@ -65,9 +69,9 @@
* filter with the appropriate action, the {@link #CATEGORY_EUICC_UI} category, and a non-zero
* priority.
*
- * TODO(b/35851809): Make this a SystemApi.
* @hide
*/
+@SystemApi
public abstract class EuiccService extends Service {
/** Action which must be included in this service's intent filter. */
public static final String EUICC_SERVICE_INTERFACE = "android.service.euicc.EuiccService";
@@ -77,7 +81,10 @@
// LUI actions. These are passthroughs of the corresponding EuiccManager actions.
- /** @see android.telephony.euicc.EuiccManager#ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS */
+ /**
+ * @see android.telephony.euicc.EuiccManager#ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS
+ * The difference is this one is used by system to bring up the LUI.
+ */
public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS =
"android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
/** @see android.telephony.euicc.EuiccManager#ACTION_PROVISION_EMBEDDED_SUBSCRIPTION */
@@ -88,7 +95,10 @@
// require user interaction.
// TODO(b/33075886): Define extras for any input parameters to these dialogs once they are
// more scoped out.
- /** Alert the user that this action will result in an active SIM being deactivated. */
+ /**
+ * Alert the user that this action will result in an active SIM being deactivated.
+ * To implement the LUI triggered by the system, you need to define this in AndroidManifest.xml.
+ */
public static final String ACTION_RESOLVE_DEACTIVATE_SIM =
"android.service.euicc.action.RESOLVE_DEACTIVATE_SIM";
/**
@@ -102,7 +112,11 @@
public static final String ACTION_RESOLVE_CONFIRMATION_CODE =
"android.service.euicc.action.RESOLVE_CONFIRMATION_CODE";
- /** Intent extra set for resolution requests containing the package name of the calling app. */
+ /**
+ * Intent extra set for resolution requests containing the package name of the calling app.
+ * This is used by the above actions including ACTION_RESOLVE_DEACTIVATE_SIM,
+ * ACTION_RESOLVE_NO_PRIVILEGES and ACTION_RESOLVE_CONFIRMATION_CODE.
+ */
public static final String EXTRA_RESOLUTION_CALLING_PACKAGE =
"android.service.euicc.extra.RESOLUTION_CALLING_PACKAGE";
@@ -136,10 +150,18 @@
RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_CONFIRMATION_CODE);
}
- /** Boolean extra for resolution actions indicating whether the user granted consent. */
- public static final String RESOLUTION_EXTRA_CONSENT = "consent";
- /** String extra for resolution actions indicating the carrier confirmation code. */
- public static final String RESOLUTION_EXTRA_CONFIRMATION_CODE = "confirmation_code";
+ /**
+ * Boolean extra for resolution actions indicating whether the user granted consent.
+ * This is used and set by the implementation and used in {@code EuiccOperation}.
+ */
+ public static final String EXTRA_RESOLUTION_CONSENT =
+ "android.service.euicc.extra.RESOLUTION_CONSENT";
+ /**
+ * String extra for resolution actions indicating the carrier confirmation code.
+ * This is used and set by the implementation and used in {@code EuiccOperation}.
+ */
+ public static final String EXTRA_RESOLUTION_CONFIRMATION_CODE =
+ "android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE";
private final IEuiccService.Stub mStubWrapper;
@@ -199,9 +221,9 @@
*
* @see IEuiccService#startOtaIfNecessary
*/
- public interface OtaStatusChangedCallback {
+ public abstract static class OtaStatusChangedCallback {
/** Called when OTA status is changed. */
- void onOtaStatusChanged(int status);
+ public abstract void onOtaStatusChanged(int status);
}
/**
@@ -238,8 +260,7 @@
/**
* Populate {@link DownloadableSubscription} metadata for the given downloadable subscription.
*
- * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
- * but is here to future-proof the APIs.
+ * @param slotId ID of the SIM slot to use for the operation.
* @param subscription A subscription whose metadata needs to be populated.
* @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the
* eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM)}
@@ -267,8 +288,7 @@
/**
* Download the given subscription.
*
- * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
- * but is here to future-proof the APIs.
+ * @param slotId ID of the SIM slot to use for the operation.
* @param subscription The subscription to download.
* @param switchAfterDownload If true, the subscription should be enabled upon successful
* download.
@@ -286,8 +306,7 @@
/**
* Return a list of all @link EuiccProfileInfo}s.
*
- * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
- * but is here to future-proof the APIs.
+ * @param slotId ID of the SIM slot to use for the operation.
* @return The result of the operation.
* @see android.telephony.SubscriptionManager#getAvailableSubscriptionInfoList
* @see android.telephony.SubscriptionManager#getAccessibleSubscriptionInfoList
@@ -297,8 +316,7 @@
/**
* Return info about the eUICC chip/device.
*
- * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
- * but is here to future-proof the APIs.
+ * @param slotId ID of the SIM slot to use for the operation.
* @return the {@link EuiccInfo} for the eUICC chip/device.
* @see android.telephony.euicc.EuiccManager#getEuiccInfo
*/
@@ -310,8 +328,7 @@
* <p>If the subscription is currently active, it should be deactivated first (equivalent to a
* physical SIM being ejected).
*
- * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
- * but is here to future-proof the APIs.
+ * @param slotId ID of the SIM slot to use for the operation.
* @param iccid the ICCID of the subscription to delete.
* @return the result of the delete operation. May be one of the predefined {@code RESULT_}
* constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
@@ -322,8 +339,7 @@
/**
* Switch to the given subscription.
*
- * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
- * but is here to future-proof the APIs.
+ * @param slotId ID of the SIM slot to use for the operation.
* @param iccid the ICCID of the subscription to enable. May be null, in which case the current
* profile should be deactivated and no profile should be activated to replace it - this is
* equivalent to a physical SIM being ejected.
@@ -340,8 +356,7 @@
/**
* Update the nickname of the given subscription.
*
- * @param slotId ID of the SIM slot to use for the operation. This is currently not populated
- * but is here to future-proof the APIs.
+ * @param slotId ID of the SIM slot to use for the operation.
* @param iccid the ICCID of the subscription to update.
* @param nickname the new nickname to apply.
* @return the result of the update operation. May be one of the predefined {@code RESULT_}
diff --git a/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java b/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java
index 5a24492..e2171ae 100644
--- a/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java
+++ b/core/java/android/service/euicc/GetDefaultDownloadableSubscriptionListResult.java
@@ -16,16 +16,19 @@
package android.service.euicc;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.euicc.DownloadableSubscription;
+import java.util.Arrays;
+import java.util.List;
+
/**
* Result of a {@link EuiccService#onGetDefaultDownloadableSubscriptionList} operation.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+@SystemApi
public final class GetDefaultDownloadableSubscriptionListResult implements Parcelable {
public static final Creator<GetDefaultDownloadableSubscriptionListResult> CREATOR =
@@ -42,20 +45,35 @@
};
/**
- * Result of the operation.
+ * @hide
+ * @deprecated - Do no use. Use getResult() instead.
+ */
+ @Deprecated
+ public final int result;
+
+ @Nullable
+ private final DownloadableSubscription[] mSubscriptions;
+
+ /**
+ * Gets the result of the operation.
*
* <p>May be one of the predefined {@code RESULT_} constants in EuiccService or any
* implementation-specific code starting with {@link EuiccService#RESULT_FIRST_USER}.
*/
- public final int result;
+ public int getResult() {
+ return result;
+ }
/**
- * The available {@link DownloadableSubscription}s (with filled-in metadata).
+ * Gets the available {@link DownloadableSubscription}s (with filled-in metadata).
*
* <p>Only non-null if {@link #result} is {@link EuiccService#RESULT_OK}.
*/
@Nullable
- public final DownloadableSubscription[] subscriptions;
+ public List<DownloadableSubscription> getDownloadableSubscriptions() {
+ if (mSubscriptions == null) return null;
+ return Arrays.asList(mSubscriptions);
+ }
/**
* Construct a new {@link GetDefaultDownloadableSubscriptionListResult}.
@@ -70,25 +88,25 @@
@Nullable DownloadableSubscription[] subscriptions) {
this.result = result;
if (this.result == EuiccService.RESULT_OK) {
- this.subscriptions = subscriptions;
+ this.mSubscriptions = subscriptions;
} else {
if (subscriptions != null) {
throw new IllegalArgumentException(
"Error result with non-null subscriptions: " + result);
}
- this.subscriptions = null;
+ this.mSubscriptions = null;
}
}
private GetDefaultDownloadableSubscriptionListResult(Parcel in) {
this.result = in.readInt();
- this.subscriptions = in.createTypedArray(DownloadableSubscription.CREATOR);
+ this.mSubscriptions = in.createTypedArray(DownloadableSubscription.CREATOR);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(result);
- dest.writeTypedArray(subscriptions, flags);
+ dest.writeTypedArray(mSubscriptions, flags);
}
@Override
diff --git a/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java b/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java
index de8a307..1edb539 100644
--- a/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java
+++ b/core/java/android/service/euicc/GetDownloadableSubscriptionMetadataResult.java
@@ -16,6 +16,7 @@
package android.service.euicc;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.euicc.DownloadableSubscription;
@@ -23,9 +24,8 @@
/**
* Result of a {@link EuiccService#onGetDownloadableSubscriptionMetadata} operation.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+@SystemApi
public final class GetDownloadableSubscriptionMetadataResult implements Parcelable {
public static final Creator<GetDownloadableSubscriptionMetadataResult> CREATOR =
@@ -42,20 +42,34 @@
};
/**
- * Result of the operation.
+ * @hide
+ * @deprecated - Do no use. Use getResult() instead.
+ */
+ @Deprecated
+ public final int result;
+
+ @Nullable
+ private final DownloadableSubscription mSubscription;
+
+ /**
+ * Gets the result of the operation.
*
* <p>May be one of the predefined {@code RESULT_} constants in EuiccService or any
* implementation-specific code starting with {@link EuiccService#RESULT_FIRST_USER}.
*/
- public final int result;
+ public int getResult() {
+ return result;
+ }
/**
- * The {@link DownloadableSubscription} with filled-in metadata.
+ * Gets the {@link DownloadableSubscription} with filled-in metadata.
*
* <p>Only non-null if {@link #result} is {@link EuiccService#RESULT_OK}.
*/
@Nullable
- public final DownloadableSubscription subscription;
+ public DownloadableSubscription getDownloadableSubscription() {
+ return mSubscription;
+ }
/**
* Construct a new {@link GetDownloadableSubscriptionMetadataResult}.
@@ -70,25 +84,25 @@
@Nullable DownloadableSubscription subscription) {
this.result = result;
if (this.result == EuiccService.RESULT_OK) {
- this.subscription = subscription;
+ this.mSubscription = subscription;
} else {
if (subscription != null) {
throw new IllegalArgumentException(
"Error result with non-null subscription: " + result);
}
- this.subscription = null;
+ this.mSubscription = null;
}
}
private GetDownloadableSubscriptionMetadataResult(Parcel in) {
this.result = in.readInt();
- this.subscription = in.readTypedObject(DownloadableSubscription.CREATOR);
+ this.mSubscription = in.readTypedObject(DownloadableSubscription.CREATOR);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(result);
- dest.writeTypedObject(this.subscription, flags);
+ dest.writeTypedObject(this.mSubscription, flags);
}
@Override
diff --git a/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java b/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java
index 7ad8488..464d136 100644
--- a/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java
+++ b/core/java/android/service/euicc/GetEuiccProfileInfoListResult.java
@@ -16,15 +16,18 @@
package android.service.euicc;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.Arrays;
+import java.util.List;
+
/**
* Result of a {@link EuiccService#onGetEuiccProfileInfoList} operation.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+@SystemApi
public final class GetEuiccProfileInfoListResult implements Parcelable {
public static final Creator<GetEuiccProfileInfoListResult> CREATOR =
@@ -41,19 +44,38 @@
};
/**
- * Result of the operation.
+ * @hide
+ * @deprecated - Do no use. Use getResult() instead.
+ */
+ @Deprecated
+ public final int result;
+
+ @Nullable
+ private final EuiccProfileInfo[] mProfiles;
+
+ private final boolean mIsRemovable;
+
+ /**
+ * Gets the result of the operation.
*
* <p>May be one of the predefined {@code RESULT_} constants in EuiccService or any
* implementation-specific code starting with {@link EuiccService#RESULT_FIRST_USER}.
*/
- public final int result;
+ public int getResult() {
+ return result;
+ }
- /** The profile list (only upon success). */
+ /** Gets the profile list (only upon success). */
@Nullable
- public final EuiccProfileInfo[] profiles;
+ public List<EuiccProfileInfo> getProfiles() {
+ if (mProfiles == null) return null;
+ return Arrays.asList(mProfiles);
+ }
- /** Whether the eUICC is removable. */
- public final boolean isRemovable;
+ /** Gets whether the eUICC is removable. */
+ public boolean getIsRemovable() {
+ return mIsRemovable;
+ }
/**
* Construct a new {@link GetEuiccProfileInfoListResult}.
@@ -71,30 +93,29 @@
public GetEuiccProfileInfoListResult(
int result, @Nullable EuiccProfileInfo[] profiles, boolean isRemovable) {
this.result = result;
- this.isRemovable = isRemovable;
+ this.mIsRemovable = isRemovable;
if (this.result == EuiccService.RESULT_OK) {
- this.profiles = profiles;
+ this.mProfiles = profiles;
} else {
if (profiles != null) {
throw new IllegalArgumentException(
"Error result with non-null profiles: " + result);
}
- this.profiles = null;
+ this.mProfiles = null;
}
-
}
private GetEuiccProfileInfoListResult(Parcel in) {
this.result = in.readInt();
- this.profiles = in.createTypedArray(EuiccProfileInfo.CREATOR);
- this.isRemovable = in.readBoolean();
+ this.mProfiles = in.createTypedArray(EuiccProfileInfo.CREATOR);
+ this.mIsRemovable = in.readBoolean();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(result);
- dest.writeTypedArray(profiles, flags);
- dest.writeBoolean(isRemovable);
+ dest.writeTypedArray(mProfiles, flags);
+ dest.writeBoolean(mIsRemovable);
}
@Override
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 03e5667..89d63f6 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -55,8 +55,8 @@
public static final int DISABLE_VERIFIER = 1 << 9;
/** Only use oat files located in /system. Otherwise use dex/jar/apk . */
public static final int ONLY_USE_SYSTEM_OAT_FILES = 1 << 10;
- /** Do not enfore hidden API access restrictions. */
- public static final int DISABLE_HIDDEN_API_CHECKS = 1 << 11;
+ /** Do enfore hidden API access restrictions. */
+ public static final int ENABLE_HIDDEN_API_CHECKS = 1 << 11;
/** Force generation of native debugging information for backtraces. */
public static final int DEBUG_GENERATE_MINI_DEBUG_INFO = 1 << 12;
@@ -162,9 +162,6 @@
*/
public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
- // SystemServer is always allowed to use hidden APIs.
- runtimeFlags |= DISABLE_HIDDEN_API_CHECKS;
-
VM_HOOKS.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 89a70fc..21f1fb6 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -98,10 +98,6 @@
private static final String SOCKET_NAME_ARG = "--socket-name=";
- /* Dexopt flag to disable hidden API access checks when dexopting SystemServer.
- * Must be kept in sync with com.android.server.pm.Installer. */
- private static final int DEXOPT_DISABLE_HIDDEN_API_CHECKS = 1 << 10;
-
/**
* Used to pre-load resources.
*/
@@ -569,10 +565,7 @@
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
final String packageName = "*";
final String outputPath = null;
- // Dexopt with a flag which lifts restrictions on hidden API usage.
- // Offending methods would otherwise be re-verified at runtime and
- // we want to avoid the performance overhead of that.
- final int dexFlags = DEXOPT_DISABLE_HIDDEN_API_CHECKS;
+ final int dexFlags = 0;
final String compilerFilter = systemServerFilter;
final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
final String seInfo = null;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b165ab1..ae49070 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -173,6 +173,10 @@
<protected-broadcast
android:name="android.bluetooth.headsetclient.profile.action.LAST_VTAG" />
<protected-broadcast
+ android:name="android.bluetooth.hearingaid.profile.action.CONNECTION_STATE_CHANGED" />
+ <protected-broadcast
+ android:name="android.bluetooth.hearingaid.profile.action.PLAYING_STATE_CHANGED" />
+ <protected-broadcast
android:name="android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED" />
<protected-broadcast
android:name="android.bluetooth.a2dp.profile.action.ACTIVE_DEVICE_CHANGED" />
@@ -1774,19 +1778,20 @@
<permission android:name="android.permission.BIND_TELEPHONY_NETWORK_SERVICE"
android:protectionLevel="signature" />
- <!-- Allows an application to manage embedded subscriptions (those on a eUICC) through
- EuiccManager APIs.
+ <!-- @SystemApi Allows an application to manage embedded subscriptions (those on a eUICC)
+ through EuiccManager APIs.
<p>Protection level: signature|privileged|development
- TODO(b/35851809): Mark this as a SystemApi and remove com. prefix.
- @hide -->
- <permission android:name="com.android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
+ @hide
+ -->
+ <permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
android:protectionLevel="signature|privileged|development" />
- <!-- Must be required by an EuiccService to ensure that only the system can bind to it.
+ <!-- @SystemApi Must be required by an EuiccService to ensure that only the system can bind to
+ it.
<p>Protection level: signature
- TODO(b/35851809): Mark this as a SystemApi and remove com. prefix.
- @hide -->
- <permission android:name="com.android.permission.BIND_EUICC_SERVICE"
+ @hide
+ -->
+ <permission android:name="android.permission.BIND_EUICC_SERVICE"
android:protectionLevel="signature" />
<!-- ================================== -->
diff --git a/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java b/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java
index 1e3ddf3..e69d1e7 100644
--- a/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java
+++ b/core/tests/coretests/src/android/service/euicc/EuiccProfileInfoTest.java
@@ -30,14 +30,15 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Arrays;
+
@SmallTest
@RunWith(AndroidJUnit4.class)
public class EuiccProfileInfoTest {
@Test
public void testWriteToParcel() {
EuiccProfileInfo p =
- new EuiccProfileInfo.Builder()
- .setIccid("21430000000000006587")
+ new EuiccProfileInfo.Builder("21430000000000006587")
.setNickname("profile nickname")
.setServiceProviderName("service provider")
.setProfileName("profile name")
@@ -50,9 +51,7 @@
"45"))
.setPolicyRules(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE)
.setUiccAccessRule(
- new UiccAccessRule[] {
- new UiccAccessRule(new byte[] {}, "package", 12345L)
- })
+ Arrays.asList(new UiccAccessRule(new byte[] {}, "package", 12345L)))
.build();
Parcel parcel = Parcel.obtain();
@@ -68,8 +67,7 @@
@Test
public void testWriteToParcelNullCarrierId() {
EuiccProfileInfo p =
- new EuiccProfileInfo.Builder()
- .setIccid("21430000000000006587")
+ new EuiccProfileInfo.Builder("21430000000000006587")
.setNickname("profile nickname")
.setServiceProviderName("service provider")
.setProfileName("profile name")
@@ -77,9 +75,8 @@
.setState(EuiccProfileInfo.PROFILE_STATE_ENABLED)
.setPolicyRules(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE)
.setUiccAccessRule(
- new UiccAccessRule[] {
- new UiccAccessRule(new byte[] {}, "package", 12345L)
- })
+ Arrays.asList(new UiccAccessRule(new byte[] {}, "package", 12345L))
+ )
.build();
Parcel parcel = Parcel.obtain();
@@ -95,8 +92,7 @@
@Test
public void testBuilderAndGetters() {
EuiccProfileInfo p =
- new EuiccProfileInfo.Builder()
- .setIccid("21430000000000006587")
+ new EuiccProfileInfo.Builder("21430000000000006587")
.setNickname("profile nickname")
.setProfileName("profile name")
.setServiceProviderName("service provider")
@@ -108,10 +104,7 @@
.setState(EuiccProfileInfo.PROFILE_STATE_ENABLED)
.setProfileClass(EuiccProfileInfo.PROFILE_CLASS_OPERATIONAL)
.setPolicyRules(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE)
- .setUiccAccessRule(
- new UiccAccessRule[] {
- new UiccAccessRule(new byte[0], null, 0)
- })
+ .setUiccAccessRule(Arrays.asList(new UiccAccessRule(new byte[0], null, 0)))
.build();
assertEquals("21430000000000006587", p.getIccid());
@@ -130,14 +123,13 @@
assertFalse(p.hasPolicyRule(EuiccProfileInfo.POLICY_RULE_DO_NOT_DISABLE));
assertArrayEquals(
new UiccAccessRule[] {new UiccAccessRule(new byte[0], null, 0)},
- p.getUiccAccessRules());
+ p.getUiccAccessRules().toArray());
}
@Test
public void testBuilder_BasedOnAnotherProfile() {
EuiccProfileInfo p =
- new EuiccProfileInfo.Builder()
- .setIccid("21430000000000006587")
+ new EuiccProfileInfo.Builder("21430000000000006587")
.setNickname("profile nickname")
.setProfileName("profile name")
.setServiceProviderName("service provider")
@@ -150,9 +142,7 @@
.setProfileClass(EuiccProfileInfo.PROFILE_CLASS_OPERATIONAL)
.setPolicyRules(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE)
.setUiccAccessRule(
- new UiccAccessRule[] {
- new UiccAccessRule(new byte[0], null, 0)
- })
+ Arrays.asList(new UiccAccessRule(new byte[] {}, "package", 12345L)))
.build();
EuiccProfileInfo copied = new EuiccProfileInfo.Builder(p).build();
@@ -164,8 +154,7 @@
@Test
public void testEqualsHashCode() {
EuiccProfileInfo p =
- new EuiccProfileInfo.Builder()
- .setIccid("21430000000000006587")
+ new EuiccProfileInfo.Builder("21430000000000006587")
.setNickname("profile nickname")
.setProfileName("profile name")
.setServiceProviderName("service provider")
@@ -177,10 +166,7 @@
.setState(EuiccProfileInfo.PROFILE_STATE_ENABLED)
.setProfileClass(EuiccProfileInfo.PROFILE_STATE_ENABLED)
.setPolicyRules(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE)
- .setUiccAccessRule(
- new UiccAccessRule[] {
- new UiccAccessRule(new byte[0], null, 0)
- })
+ .setUiccAccessRule(Arrays.asList(new UiccAccessRule(new byte[0], null, 0)))
.build();
assertTrue(p.equals(p));
@@ -229,13 +215,13 @@
}
@Test(expected = IllegalStateException.class)
- public void testBuilderBuild_NoIccid() {
- new EuiccProfileInfo.Builder().build();
+ public void testBuilderBuild_IllegalIccid() {
+ new EuiccProfileInfo.Builder("abc").build();
}
@Test(expected = IllegalArgumentException.class)
public void testBuilderSetOperatorMccMnc_Illegal() {
- new EuiccProfileInfo.Builder()
+ new EuiccProfileInfo.Builder("21430000000000006587")
.setCarrierIdentifier(new CarrierIdentifier(new byte[] {1, 2, 3, 4}, null, null));
}
diff --git a/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.mk b/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.mk
index 994131a..9b9e811 100644
--- a/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.mk
+++ b/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.mk
@@ -29,13 +29,10 @@
LOCAL_SRC_FILES:= \
native.cpp
-# All of the shard libraries we link against.
-LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_LDLIBS := -llog
LOCAL_CFLAGS += -Wall -Wextra -Werror
-# Also need the JNI headers.
-LOCAL_C_INCLUDES += \
- $(JNI_H_INCLUDE)
+LOCAL_SDK_VERSION := current
include $(BUILD_SHARED_LIBRARY)
diff --git a/core/tests/hosttests/test-apps/SharedUid/32/jni/native.cpp b/core/tests/hosttests/test-apps/SharedUid/32/jni/native.cpp
index 99cf587..fe32454 100644
--- a/core/tests/hosttests/test-apps/SharedUid/32/jni/native.cpp
+++ b/core/tests/hosttests/test-apps/SharedUid/32/jni/native.cpp
@@ -15,12 +15,15 @@
*/
#define LOG_TAG "pmtest32 native.cpp"
-#include <utils/Log.h>
+#include <android/log.h>
#include <stdio.h>
#include "jni.h"
+#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+
static jint
add(JNIEnv */* env */, jobject /* thiz */, jint a, jint b) {
int result = a + b;
diff --git a/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.mk b/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.mk
index 6c2679b..600a5d1 100644
--- a/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.mk
+++ b/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.mk
@@ -30,14 +30,10 @@
LOCAL_SRC_FILES:= \
native.cpp
-# All of the shared libraries we link against.
-LOCAL_SHARED_LIBRARIES := \
- libutils liblog
+LOCAL_LDLIBS := -llog
LOCAL_CFLAGS += -Wall -Wextra -Werror
-# Also need the JNI headers.
-LOCAL_C_INCLUDES += \
- $(JNI_H_INCLUDE)
+LOCAL_SDK_VERSION := current
include $(BUILD_SHARED_LIBRARY)
diff --git a/core/tests/hosttests/test-apps/SharedUid/64/jni/native.cpp b/core/tests/hosttests/test-apps/SharedUid/64/jni/native.cpp
index 0b6d750..ad9e746 100644
--- a/core/tests/hosttests/test-apps/SharedUid/64/jni/native.cpp
+++ b/core/tests/hosttests/test-apps/SharedUid/64/jni/native.cpp
@@ -15,12 +15,15 @@
*/
#define LOG_TAG "pmtest64 native.cpp"
-#include <utils/Log.h>
+#include <android/log.h>
#include <stdio.h>
#include "jni.h"
+#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+
static jint
add(JNIEnv */* env */, jobject /* thiz */, jint a, jint b) {
int result = a + b;
diff --git a/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.mk b/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.mk
index d668f29..8e9ac6b 100644
--- a/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.mk
+++ b/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.mk
@@ -29,14 +29,10 @@
LOCAL_SRC_FILES:= \
native.cpp
-# All of the shard libraries we link against.
LOCAL_LDLIBS = -llog
-LOCAL_SHARED_LIBRARIES := liblog
LOCAL_CFLAGS += -Wall -Wextra -Werror
-# Also need the JNI headers.
-LOCAL_C_INCLUDES += \
- $(JNI_H_INCLUDE)
+LOCAL_SDK_VERSION := current
include $(BUILD_SHARED_LIBRARY)
diff --git a/core/tests/hosttests/test-apps/SharedUid/dual/jni/native.cpp b/core/tests/hosttests/test-apps/SharedUid/dual/jni/native.cpp
index 3947e21..5c5088f 100644
--- a/core/tests/hosttests/test-apps/SharedUid/dual/jni/native.cpp
+++ b/core/tests/hosttests/test-apps/SharedUid/dual/jni/native.cpp
@@ -15,12 +15,15 @@
*/
#define LOG_TAG "pmtestdual native.cpp"
-#include <utils/Log.h>
+#include <android/log.h>
#include <stdio.h>
#include "jni.h"
+#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+
static jint
add(JNIEnv */* env */, jobject /* thiz */, jint a, jint b) {
int result = a + b;
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 6974bbb..16c2b68 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -165,7 +165,7 @@
<permission name="android.permission.UPDATE_LOCK"/>
<permission name="android.permission.WRITE_APN_SETTINGS"/>
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
- <permission name="com.android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
+ <permission name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
<permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
<permission name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
</privapp-permissions>
@@ -348,6 +348,7 @@
<permission name="android.permission.WRITE_DREAM_STATE"/>
<permission name="android.permission.WRITE_MEDIA_STORAGE"/>
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+ <permission name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
</privapp-permissions>
<privapp-permissions package="com.android.tv">
diff --git a/native/android/OWNERS b/native/android/OWNERS
new file mode 100644
index 0000000..11d4be4
--- /dev/null
+++ b/native/android/OWNERS
@@ -0,0 +1,11 @@
+set noparent
+
+per-file libandroid_net.map.txt=ek@google.com
+per-file libandroid_net.map.txt=jchalard@google.com
+per-file libandroid_net.map.txt=lorenzo@google.com
+per-file libandroid_net.map.txt=satk@google.com
+
+per-file net.c=ek@google.com
+per-file net.c=jchalard@google.com
+per-file net.c=lorenzo@google.com
+per-file net.c=satk@google.com
diff --git a/packages/SettingsLib/res/drawable/ic_bt_hearing_aid.xml b/packages/SettingsLib/res/drawable/ic_bt_hearing_aid.xml
new file mode 100644
index 0000000..e14c99b
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_bt_hearing_aid.xml
@@ -0,0 +1,24 @@
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M17,20c-0.29,0 -0.56,-0.06 -0.76,-0.15 -0.71,-0.37 -1.21,-0.88 -1.71,-2.38 -0.51,-1.56 -1.47,-2.29 -2.39,-3 -0.79,-0.61 -1.61,-1.24 -2.32,-2.53C9.29,10.98 9,9.93 9,9c0,-2.8 2.2,-5 5,-5s5,2.2 5,5h2c0,-3.93 -3.07,-7 -7,-7S7,5.07 7,9c0,1.26 0.38,2.65 1.07,3.9 0.91,1.65 1.98,2.48 2.85,3.15 0.81,0.62 1.39,1.07 1.71,2.05 0.6,1.82 1.37,2.84 2.73,3.55 0.51,0.23 1.07,0.35 1.64,0.35 2.21,0 4,-1.79 4,-4h-2c0,1.1 -0.9,2 -2,2zM7.64,2.64L6.22,1.22C4.23,3.21 3,5.96 3,9s1.23,5.79 3.22,7.78l1.41,-1.41C6.01,13.74 5,11.49 5,9s1.01,-4.74 2.64,-6.36zM11.5,9c0,1.38 1.12,2.5 2.5,2.5s2.5,-1.12 2.5,-2.5 -1.12,-2.5 -2.5,-2.5 -2.5,1.12 -2.5,2.5z"/>
+</vector>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 74a6c64..428f0b8 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -177,6 +177,11 @@
<!-- Bluetooth settings. Similar to bluetooth_profile_a2dp_high_quality, but used when the device supports high quality audio but we don't know which codec that will be used. -->
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec">HD audio</string>
+ <!-- Bluetooth settings. The user-visible string that is used whenever referring to the Hearing Aid profile. -->
+ <string name="bluetooth_profile_hearing_aid">Hearing Aid</string>
+ <!-- Bluetooth settings. Connection options screen. The summary for the Hearing Aid checkbox preference when Hearing Aid is connected. -->
+ <string name="bluetooth_hearing_aid_profile_summary_connected">Connected to Hearing Aid</string>
+
<!-- Bluetooth settings. Connection options screen. The summary for the A2DP checkbox preference when A2DP is connected. -->
<string name="bluetooth_a2dp_profile_summary_connected">Connected to media audio</string>
<!-- Bluetooth settings. Connection options screen. The summary for the headset checkbox preference when headset is connected. -->
@@ -214,6 +219,8 @@
for the HID checkbox preference that describes how checking it
will set the HID profile as preferred. -->
<string name="bluetooth_hid_profile_summary_use_for">Use for input</string>
+ <!-- Bluetooth settings. Connection options screen. The summary for the Hearing Aid checkbox preference that describes how checking it will set the Hearing Aid profile as preferred. -->
+ <string name="bluetooth_hearing_aid_profile_summary_use_for">Use for Hearing Aid</string>
<!-- Button text for accepting an incoming pairing request. [CHAR LIMIT=20] -->
<string name="bluetooth_pairing_accept">Pair</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
new file mode 100644
index 0000000..8f9e4635
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
@@ -0,0 +1,235 @@
+/*
+ * 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.settingslib.bluetooth;
+
+import android.bluetooth.BluetoothHearingAid;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothCodecConfig;
+import android.bluetooth.BluetoothCodecStatus;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothUuid;
+import android.content.Context;
+import android.os.ParcelUuid;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settingslib.R;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class HearingAidProfile implements LocalBluetoothProfile {
+ private static final String TAG = "HearingAidProfile";
+ private static boolean V = true;
+
+ private Context mContext;
+
+ private BluetoothHearingAid mService;
+ private boolean mIsProfileReady;
+
+ private final LocalBluetoothAdapter mLocalAdapter;
+ private final CachedBluetoothDeviceManager mDeviceManager;
+
+ static final String NAME = "HearingAid";
+ private final LocalBluetoothProfileManager mProfileManager;
+
+ // Order of this profile in device profiles list
+ private static final int ORDINAL = 1;
+
+ // These callbacks run on the main thread.
+ private final class HearingAidServiceListener
+ implements BluetoothProfile.ServiceListener {
+
+ public void onServiceConnected(int profile, BluetoothProfile proxy) {
+ if (V) Log.d(TAG,"Bluetooth service connected");
+ mService = (BluetoothHearingAid) proxy;
+ // We just bound to the service, so refresh the UI for any connected HearingAid devices.
+ List<BluetoothDevice> deviceList = mService.getConnectedDevices();
+ while (!deviceList.isEmpty()) {
+ BluetoothDevice nextDevice = deviceList.remove(0);
+ CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice);
+ // we may add a new device here, but generally this should not happen
+ if (device == null) {
+ Log.w(TAG, "HearingAidProfile found new device: " + nextDevice);
+ device = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, nextDevice);
+ }
+ device.onProfileStateChanged(HearingAidProfile.this, BluetoothProfile.STATE_CONNECTED);
+ device.refresh();
+ }
+ mIsProfileReady=true;
+ }
+
+ public void onServiceDisconnected(int profile) {
+ if (V) Log.d(TAG,"Bluetooth service disconnected");
+ mIsProfileReady=false;
+ }
+ }
+
+ public boolean isProfileReady() {
+ return mIsProfileReady;
+ }
+
+ HearingAidProfile(Context context, LocalBluetoothAdapter adapter,
+ CachedBluetoothDeviceManager deviceManager,
+ LocalBluetoothProfileManager profileManager) {
+ mContext = context;
+ mLocalAdapter = adapter;
+ mDeviceManager = deviceManager;
+ mProfileManager = profileManager;
+ mLocalAdapter.getProfileProxy(context, new HearingAidServiceListener(),
+ BluetoothProfile.HEARING_AID);
+ }
+
+ public boolean isConnectable() {
+ return true;
+ }
+
+ public boolean isAutoConnectable() {
+ return true;
+ }
+
+ public List<BluetoothDevice> getConnectedDevices() {
+ if (mService == null) return new ArrayList<BluetoothDevice>(0);
+ return mService.getDevicesMatchingConnectionStates(
+ new int[] {BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.STATE_CONNECTING,
+ BluetoothProfile.STATE_DISCONNECTING});
+ }
+
+ public boolean connect(BluetoothDevice device) {
+ if (mService == null) return false;
+ return mService.connect(device);
+ }
+
+ public boolean disconnect(BluetoothDevice device) {
+ if (mService == null) return false;
+ // Downgrade priority as user is disconnecting the hearing aid.
+ if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
+ mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+ }
+ return mService.disconnect(device);
+ }
+
+ public int getConnectionStatus(BluetoothDevice device) {
+ if (mService == null) {
+ return BluetoothProfile.STATE_DISCONNECTED;
+ }
+ return mService.getConnectionState(device);
+ }
+
+ public boolean isPreferred(BluetoothDevice device) {
+ if (mService == null) return false;
+ return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+ }
+
+ public int getPreferred(BluetoothDevice device) {
+ if (mService == null) return BluetoothProfile.PRIORITY_OFF;
+ return mService.getPriority(device);
+ }
+
+ public void setPreferred(BluetoothDevice device, boolean preferred) {
+ if (mService == null) return;
+ if (preferred) {
+ if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
+ mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+ }
+ } else {
+ mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+ }
+ }
+
+ public int getVolume() {
+ if (mService == null) {
+ return 0;
+ }
+ return mService.getVolume();
+ }
+
+ public void setVolume(int volume) {
+ if (mService == null) {
+ return;
+ }
+ mService.setVolume(volume);
+ }
+
+ public long getHiSyncId(BluetoothDevice device) {
+ if (mService == null) {
+ return BluetoothHearingAid.HI_SYNC_ID_INVALID;
+ }
+ return mService.getHiSyncId(device);
+ }
+
+ public int getDeviceSide(BluetoothDevice device) {
+ if (mService == null) {
+ return BluetoothHearingAid.SIDE_LEFT;
+ }
+ return mService.getDeviceSide(device);
+ }
+
+ public int getDeviceMode(BluetoothDevice device) {
+ if (mService == null) {
+ return BluetoothHearingAid.MODE_MONAURAL;
+ }
+ return mService.getDeviceMode(device);
+ }
+
+ public String toString() {
+ return NAME;
+ }
+
+ public int getOrdinal() {
+ return ORDINAL;
+ }
+
+ public int getNameResource(BluetoothDevice device) {
+ return R.string.bluetooth_profile_hearing_aid;
+ }
+
+ public int getSummaryResourceForDevice(BluetoothDevice device) {
+ int state = getConnectionStatus(device);
+ switch (state) {
+ case BluetoothProfile.STATE_DISCONNECTED:
+ return R.string.bluetooth_hearing_aid_profile_summary_use_for;
+
+ case BluetoothProfile.STATE_CONNECTED:
+ return R.string.bluetooth_hearing_aid_profile_summary_connected;
+
+ default:
+ return Utils.getConnectionStateSummary(state);
+ }
+ }
+
+ public int getDrawableResource(BluetoothClass btClass) {
+ return R.drawable.ic_bt_hearing_aid;
+ }
+
+ protected void finalize() {
+ if (V) Log.d(TAG, "finalize()");
+ if (mService != null) {
+ try {
+ BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.HEARING_AID,
+ mService);
+ mService = null;
+ }catch (Throwable t) {
+ Log.w(TAG, "Error cleaning up Hearing Aid proxy", t);
+ }
+ }
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 991d922..34a099c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -21,6 +21,7 @@
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHeadsetClient;
+import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothHidHost;
import android.bluetooth.BluetoothMap;
import android.bluetooth.BluetoothMapClient;
@@ -91,6 +92,7 @@
private final PbapServerProfile mPbapProfile;
private final boolean mUsePbapPce;
private final boolean mUseMapClient;
+ private HearingAidProfile mHearingAidProfile;
/**
* Mapping from profile name, e.g. "HEADSET" to profile object.
@@ -143,10 +145,14 @@
//Create PBAP server profile
if(DEBUG) Log.d(TAG, "Adding local PBAP profile");
+
mPbapProfile = new PbapServerProfile(context);
addProfile(mPbapProfile, PbapServerProfile.NAME,
BluetoothPbap.ACTION_CONNECTION_STATE_CHANGED);
+ mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager, this);
+ addProfile(mHearingAidProfile, HearingAidProfile.NAME,
+ BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
if (DEBUG) Log.d(TAG, "LocalBluetoothProfileManager construction complete");
}
@@ -254,6 +260,18 @@
"Warning: PBAP Client profile was previously added but the UUID is now missing.");
}
+ //Hearing Aid Client
+ if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HearingAid)) {
+ if (mHearingAidProfile == null) {
+ if(DEBUG) Log.d(TAG, "Adding local Hearing Aid profile");
+ mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager, this);
+ addProfile(mHearingAidProfile, HearingAidProfile.NAME,
+ BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+ }
+ } else if (mHearingAidProfile != null) {
+ Log.w(TAG, "Warning: Hearing Aid profile was previously added but the UUID is now missing.");
+ }
+
mEventManager.registerProfileIntentReceiver();
// There is no local SDP record for HID and Settings app doesn't control PBAP Server.
@@ -416,6 +434,10 @@
return mMapClientProfile;
}
+ public HearingAidProfile getHearingAidProfile() {
+ return mHearingAidProfile;
+ }
+
/**
* Fill in a list of LocalBluetoothProfile objects that are supported by
* the local device and the remote device.
@@ -515,6 +537,12 @@
removedProfiles.remove(mPbapClientProfile);
}
+ if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HearingAid) &&
+ mHearingAidProfile != null) {
+ profiles.add(mHearingAidProfile);
+ removedProfiles.remove(mHearingAidProfile);
+ }
+
if (DEBUG) {
Log.d(TAG,"New Profiles" + profiles.toString());
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 87971cb..9268c8f 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -108,7 +108,7 @@
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<!-- Keyguard -->
- <uses-permission android:name="com.android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" />
+ <uses-permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" />
<uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index bff5c10..fd2ef18 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -30,6 +30,7 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
@@ -1260,11 +1261,7 @@
for (Network network : networks) {
nai = getNetworkAgentInfoForNetwork(network);
nc = getNetworkCapabilitiesInternal(nai);
- // nc is a copy of the capabilities in nai, so it's fine to mutate it
- // TODO : don't remove the UIDs when communicating with processes
- // that have the NETWORK_SETTINGS permission.
if (nc != null) {
- nc.setSingleUid(userId);
result.put(network, nc);
}
}
@@ -1332,7 +1329,9 @@
if (nai != null) {
synchronized (nai) {
if (nai.networkCapabilities != null) {
- return new NetworkCapabilities(nai.networkCapabilities);
+ // TODO : don't remove the UIDs when communicating with processes
+ // that have the NETWORK_SETTINGS permission.
+ return networkCapabilitiesWithoutUids(nai.networkCapabilities);
}
}
}
@@ -1345,6 +1344,10 @@
return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));
}
+ private NetworkCapabilities networkCapabilitiesWithoutUids(NetworkCapabilities nc) {
+ return new NetworkCapabilities(nc).setUids(null);
+ }
+
@Override
public NetworkState[] getAllNetworkState() {
// Require internal since we're handing out IMSI details
@@ -1354,6 +1357,10 @@
for (Network network : getAllNetworks()) {
final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
if (nai != null) {
+ // TODO (b/73321673) : NetworkState contains a copy of the
+ // NetworkCapabilities, which may contain UIDs of apps to which the
+ // network applies. Should the UIDs be cleared so as not to leak or
+ // interfere ?
result.add(nai.getNetworkState());
}
}
@@ -4497,10 +4504,12 @@
lp.ensureDirectlyConnectedRoutes();
// TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
// satisfies mDefaultRequest.
+ final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
- new Network(reserveNetId()), new NetworkInfo(networkInfo), lp,
- new NetworkCapabilities(networkCapabilities), currentScore,
+ new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore,
mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this);
+ // Make sure the network capabilities reflect what the agent info says.
+ nai.networkCapabilities = mixInCapabilities(nai, nc);
synchronized (this) {
nai.networkMonitor.systemReady = mSystemReady;
}
@@ -4729,6 +4738,11 @@
} else {
newNc.addCapability(NET_CAPABILITY_FOREGROUND);
}
+ if (nai.isSuspended()) {
+ newNc.removeCapability(NET_CAPABILITY_NOT_SUSPENDED);
+ } else {
+ newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
+ }
return newNc;
}
@@ -4909,7 +4923,7 @@
releasePendingNetworkRequestWithDelay(pendingIntent);
}
- private static void callCallbackForRequest(NetworkRequestInfo nri,
+ private void callCallbackForRequest(NetworkRequestInfo nri,
NetworkAgentInfo networkAgent, int notificationType, int arg1) {
if (nri.messenger == null) {
return; // Default request has no msgr
@@ -4922,16 +4936,19 @@
putParcelable(bundle, networkAgent.network);
}
switch (notificationType) {
+ case ConnectivityManager.CALLBACK_AVAILABLE: {
+ putParcelable(bundle, new NetworkCapabilities(networkAgent.networkCapabilities));
+ putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
+ break;
+ }
case ConnectivityManager.CALLBACK_LOSING: {
msg.arg1 = arg1;
break;
}
case ConnectivityManager.CALLBACK_CAP_CHANGED: {
+ // networkAgent can't be null as it has been accessed a few lines above.
final NetworkCapabilities nc =
- new NetworkCapabilities(networkAgent.networkCapabilities);
- // TODO : don't remove the UIDs when communicating with processes
- // that have the NETWORK_SETTINGS permission.
- nc.setSingleUid(nri.mUid);
+ networkCapabilitiesWithoutUids(networkAgent.networkCapabilities);
putParcelable(bundle, nc);
break;
}
@@ -5464,6 +5481,10 @@
if (networkAgent.getCurrentScore() != oldScore) {
rematchAllNetworksAndRequests(networkAgent, oldScore);
}
+ updateCapabilities(networkAgent.getCurrentScore(), networkAgent,
+ networkAgent.networkCapabilities);
+ // TODO (b/73132094) : remove this call once the few users of onSuspended and
+ // onResumed have been removed.
notifyNetworkCallbacks(networkAgent, (state == NetworkInfo.State.SUSPENDED ?
ConnectivityManager.CALLBACK_SUSPENDED :
ConnectivityManager.CALLBACK_RESUMED));
@@ -5500,14 +5521,6 @@
}
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, 0);
- // Whether a network is currently suspended is also an important
- // element of state to be transferred (it would not otherwise be
- // delivered by any currently available mechanism).
- if (nai.networkInfo.getState() == NetworkInfo.State.SUSPENDED) {
- callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_SUSPENDED, 0);
- }
- callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_CAP_CHANGED, 0);
- callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_IP_CHANGED, 0);
}
private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 6747be3..5e5eacb 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -64,6 +64,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.NoSuchElementException;
/**
* Since phone process can be restarted, this class provides a centralized place
@@ -90,6 +91,8 @@
IBinder binder;
+ TelephonyRegistryDeathRecipient deathRecipient;
+
IPhoneStateListener callback;
IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback;
@@ -251,6 +254,21 @@
}
};
+ private class TelephonyRegistryDeathRecipient implements IBinder.DeathRecipient {
+
+ private final IBinder binder;
+
+ TelephonyRegistryDeathRecipient(IBinder binder) {
+ this.binder = binder;
+ }
+
+ @Override
+ public void binderDied() {
+ if (DBG) log("binderDied " + binder);
+ remove(binder);
+ }
+ }
+
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -378,23 +396,14 @@
}
}
- Record r;
synchronized (mRecords) {
// register
- find_and_add: {
- IBinder b = callback.asBinder();
- final int N = mRecords.size();
- for (int i = 0; i < N; i++) {
- r = mRecords.get(i);
- if (b == r.binder) {
- break find_and_add;
- }
- }
- r = new Record();
- r.binder = b;
- mRecords.add(r);
- if (DBG) log("listen oscl: add new record");
+ IBinder b = callback.asBinder();
+ Record r = add(b);
+
+ if (r == null) {
+ return;
}
r.onSubscriptionsChangedListenerCallback = callback;
@@ -496,20 +505,11 @@
synchronized (mRecords) {
// register
- Record r;
- find_and_add: {
- IBinder b = callback.asBinder();
- final int N = mRecords.size();
- for (int i = 0; i < N; i++) {
- r = mRecords.get(i);
- if (b == r.binder) {
- break find_and_add;
- }
- }
- r = new Record();
- r.binder = b;
- mRecords.add(r);
- if (DBG) log("listen: add new record");
+ IBinder b = callback.asBinder();
+ Record r = add(b);
+
+ if (r == null) {
+ return;
}
r.callback = callback;
@@ -697,16 +697,57 @@
return record.canReadPhoneState ? mCallIncomingNumber[phoneId] : "";
}
+ private Record add(IBinder binder) {
+ Record r;
+
+ synchronized (mRecords) {
+ final int N = mRecords.size();
+ for (int i = 0; i < N; i++) {
+ r = mRecords.get(i);
+ if (binder == r.binder) {
+ // Already existed.
+ return r;
+ }
+ }
+ r = new Record();
+ r.binder = binder;
+ r.deathRecipient = new TelephonyRegistryDeathRecipient(binder);
+
+ try {
+ binder.linkToDeath(r.deathRecipient, 0);
+ } catch (RemoteException e) {
+ if (VDBG) log("LinkToDeath remote exception sending to r=" + r + " e=" + e);
+ // Binder already died. Return null.
+ return null;
+ }
+
+ mRecords.add(r);
+ if (DBG) log("add new record");
+ }
+
+ return r;
+ }
+
private void remove(IBinder binder) {
synchronized (mRecords) {
final int recordCount = mRecords.size();
for (int i = 0; i < recordCount; i++) {
- if (mRecords.get(i).binder == binder) {
+ Record r = mRecords.get(i);
+ if (r.binder == binder) {
if (DBG) {
- Record r = mRecords.get(i);
- log("remove: binder=" + binder + "r.callingPackage" + r.callingPackage
- + "r.callback" + r.callback);
+ log("remove: binder=" + binder + " r.callingPackage " + r.callingPackage
+ + " r.callback " + r.callback);
}
+
+ if (r.deathRecipient != null) {
+ try {
+ binder.unlinkToDeath(r.deathRecipient, 0);
+ } catch (NoSuchElementException e) {
+ if (VDBG) log("UnlinkToDeath NoSuchElementException sending to r="
+ + r + " e=" + e);
+ }
+ }
+
mRecords.remove(i);
return;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c69af6c8..0cce2d9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3891,10 +3891,10 @@
runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
}
- if (app.info.isAllowedToUseHiddenApi()) {
- // This app is allowed to use undocumented and private APIs. Set
- // up its runtime with the appropriate flag.
- runtimeFlags |= Zygote.DISABLE_HIDDEN_API_CHECKS;
+ if (!app.info.isAllowedToUseHiddenApi()) {
+ // This app is not allowed to use undocumented and private APIs.
+ // Set up its runtime with the appropriate flag.
+ runtimeFlags |= Zygote.ENABLE_HIDDEN_API_CHECKS;
}
String invokeWith = null;
@@ -17481,6 +17481,7 @@
final long myTotalPss = mi.getTotalPss();
final long myTotalSwapPss = mi.getTotalSwappedOutPss();
totalPss += myTotalPss;
+ totalSwapPss += myTotalSwapPss;
nativeProcTotalPss += myTotalPss;
MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 85b70ca..a24f97e 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -392,6 +392,15 @@
return !isVPN() && numForegroundNetworkRequests() == 0 && mNumBackgroundNetworkRequests > 0;
}
+ /**
+ * Returns whether this network is currently suspended. A network is suspended if it is still
+ * connected but data temporarily fails to transfer. See {@link NetworkInfo.State#SUSPENDED}
+ * and {@link NetworkCapabilities#NET_CAPABILITY_NOT_SUSPENDED}.
+ */
+ public boolean isSuspended() {
+ return networkInfo.getState() == NetworkInfo.State.SUSPENDED;
+ }
+
// Does this network satisfy request?
public boolean satisfies(NetworkRequest request) {
return created &&
@@ -458,7 +467,7 @@
public NetworkState getNetworkState() {
synchronized (this) {
- // Network objects are outwardly immutable so there is no point to duplicating.
+ // Network objects are outwardly immutable so there is no point in duplicating.
// Duplicating also precludes sharing socket factories and connection pools.
final String subscriberId = (networkMisc != null) ? networkMisc.subscriberId : null;
return new NetworkState(new NetworkInfo(networkInfo),
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 2cd128d..9194682 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -58,9 +58,8 @@
public static final int DEXOPT_STORAGE_DE = 1 << 8;
/** Indicates that dexopt is invoked from the background service. */
public static final int DEXOPT_IDLE_BACKGROUND_JOB = 1 << 9;
- /* Indicates that dexopt should not restrict access to private APIs.
- * Must be kept in sync with com.android.internal.os.ZygoteInit. */
- public static final int DEXOPT_DISABLE_HIDDEN_API_CHECKS = 1 << 10;
+ /** Indicates that dexopt should restrict access to private APIs. */
+ public static final int DEXOPT_ENABLE_HIDDEN_API_CHECKS = 1 << 10;
// NOTE: keep in sync with installd
public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 8;
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 1f219c1..77fe8bc 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -55,7 +55,7 @@
import static com.android.server.pm.Installer.DEXOPT_STORAGE_CE;
import static com.android.server.pm.Installer.DEXOPT_STORAGE_DE;
import static com.android.server.pm.Installer.DEXOPT_IDLE_BACKGROUND_JOB;
-import static com.android.server.pm.Installer.DEXOPT_DISABLE_HIDDEN_API_CHECKS;
+import static com.android.server.pm.Installer.DEXOPT_ENABLE_HIDDEN_API_CHECKS;
import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
@@ -510,11 +510,9 @@
boolean isProfileGuidedFilter = isProfileGuidedCompilerFilter(compilerFilter);
boolean isPublic = !info.isForwardLocked() && !isProfileGuidedFilter;
int profileFlag = isProfileGuidedFilter ? DEXOPT_PROFILE_GUIDED : 0;
- // System apps are invoked with a runtime flag which exempts them from
- // restrictions on hidden API usage. We dexopt with the same runtime flag
- // otherwise offending methods would have to be re-verified at runtime
- // and we want to avoid the performance overhead of that.
- int hiddenApiFlag = info.isAllowedToUseHiddenApi() ? DEXOPT_DISABLE_HIDDEN_API_CHECKS : 0;
+ // Some apps are executed with restrictions on hidden API usage. If this app is one
+ // of them, pass a flag to dexopt to enable the same restrictions during compilation.
+ int hiddenApiFlag = info.isAllowedToUseHiddenApi() ? 0 : DEXOPT_ENABLE_HIDDEN_API_CHECKS;
int dexFlags =
(isPublic ? DEXOPT_PUBLIC : 0)
| (debuggable ? DEXOPT_DEBUGGABLE : 0)
@@ -636,8 +634,8 @@
if ((flags & DEXOPT_IDLE_BACKGROUND_JOB) == DEXOPT_IDLE_BACKGROUND_JOB) {
flagsList.add("idle_background_job");
}
- if ((flags & DEXOPT_DISABLE_HIDDEN_API_CHECKS) == DEXOPT_DISABLE_HIDDEN_API_CHECKS) {
- flagsList.add("disable_hidden_api_checks");
+ if ((flags & DEXOPT_ENABLE_HIDDEN_API_CHECKS) == DEXOPT_ENABLE_HIDDEN_API_CHECKS) {
+ flagsList.add("enable_hidden_api_checks");
}
return String.join(",", flagsList);
diff --git a/services/core/java/com/android/server/updates/CarrierIdInstallReceiver.java b/services/core/java/com/android/server/updates/CarrierIdInstallReceiver.java
new file mode 100644
index 0000000..0450816
--- /dev/null
+++ b/services/core/java/com/android/server/updates/CarrierIdInstallReceiver.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.updates;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.provider.Telephony;
+import android.util.Log;
+
+public class CarrierIdInstallReceiver extends ConfigUpdateInstallReceiver {
+
+ public CarrierIdInstallReceiver() {
+ super("/data/misc/carrierid", "carrier_list.pb", "metadata/", "version");
+ }
+
+ @Override
+ protected void postInstall(Context context, Intent intent) {
+ ContentResolver resolver = context.getContentResolver();
+ resolver.update(Uri.withAppendedPath(Telephony.CarrierIdentification.All.CONTENT_URI,
+ "update_db"), new ContentValues(), null, null);
+ }
+}
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 5fcff18..024bd30 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -29,7 +29,6 @@
import java.util.Collections;
import java.util.List;
import java.util.Locale;
-import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -82,7 +81,7 @@
private int mConnectionProperties;
private String mDisconnectMessage;
private long mConnectTimeMillis = CONNECT_TIME_NOT_SPECIFIED;
- private long mConnectElapsedTimeMillis = CONNECT_TIME_NOT_SPECIFIED;
+ private long mConnectionStartElapsedRealTime = CONNECT_TIME_NOT_SPECIFIED;
private StatusHints mStatusHints;
private Bundle mExtras;
private Set<String> mPreviousExtraKeys;
@@ -584,30 +583,36 @@
}
/**
- * Sets the connection start time of the {@code Conference}. Should be specified in wall-clock
- * time returned by {@link System#currentTimeMillis()}.
+ * Sets the connection start time of the {@code Conference}. This is used in the call log to
+ * indicate the date and time when the conference took place.
+ * <p>
+ * Should be specified in wall-clock time returned by {@link System#currentTimeMillis()}.
* <p>
* When setting the connection time, you should always set the connection elapsed time via
- * {@link #setConnectionElapsedTime(long)}.
+ * {@link #setConnectionStartElapsedRealTime(long)} to ensure the duration is reflected.
*
- * @param connectionTimeMillis The connection time, in milliseconds.
+ * @param connectionTimeMillis The connection time, in milliseconds, as returned by
+ * {@link System#currentTimeMillis()}.
*/
public final void setConnectionTime(long connectionTimeMillis) {
mConnectTimeMillis = connectionTimeMillis;
}
/**
- * Sets the elapsed time since system boot when the {@link Conference} was connected.
- * This is used to determine the duration of the {@link Conference}.
+ * Sets the start time of the {@link Conference} which is the basis for the determining the
+ * duration of the {@link Conference}.
* <p>
- * When setting the connection elapsed time, you should always set the connection time via
+ * You should use a value returned by {@link SystemClock#elapsedRealtime()} to ensure that time
+ * zone changes do not impact the conference duration.
+ * <p>
+ * When setting this, you should also set the connection time via
* {@link #setConnectionTime(long)}.
*
- * @param connectionElapsedTime The connection time, as measured by
+ * @param connectionStartElapsedRealTime The connection time, as measured by
* {@link SystemClock#elapsedRealtime()}.
*/
- public final void setConnectionElapsedTime(long connectionElapsedTime) {
- mConnectElapsedTimeMillis = connectionElapsedTime;
+ public final void setConnectionStartElapsedRealTime(long connectionStartElapsedRealTime) {
+ mConnectionStartElapsedRealTime = connectionStartElapsedRealTime;
}
/**
@@ -642,8 +647,8 @@
* @return The elapsed time at which the {@link Conference} was connected.
* @hide
*/
- public final long getConnectElapsedTime() {
- return mConnectElapsedTimeMillis;
+ public final long getConnectionStartElapsedRealTime() {
+ return mConnectionStartElapsedRealTime;
}
/**
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 86d56b5..69cc3de 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -2298,7 +2298,7 @@
*
* @hide
*/
- public final void setConnectElapsedTimeMillis(long connectElapsedTimeMillis) {
+ public final void setConnectionStartElapsedRealTime(long connectElapsedTimeMillis) {
mConnectElapsedTimeMillis = connectElapsedTimeMillis;
}
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 2ea7e65..46d6b42 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -21,7 +21,6 @@
import android.content.ComponentName;
import android.content.Intent;
import android.net.Uri;
-import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -2007,7 +2006,7 @@
null : conference.getVideoProvider().getInterface(),
conference.getVideoState(),
conference.getConnectTimeMillis(),
- conference.getConnectElapsedTime(),
+ conference.getConnectionStartElapsedRealTime(),
conference.getStatusHints(),
conference.getExtras());
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 38408fe..77413d9c 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -17,6 +17,7 @@
package android.telephony;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -34,6 +35,8 @@
import android.util.DisplayMetrics;
import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
/**
* A Parcelable class for Subscription Information.
@@ -332,12 +335,7 @@
return this.mCountryIso;
}
- /**
- * @return whether the subscription is an embedded one.
- * @hide
- *
- * TODO(b/35851809): Make this public.
- */
+ /** @return whether the subscription is an embedded one. */
public boolean isEmbedded() {
return this.mIsEmbedded;
}
@@ -351,9 +349,9 @@
* @return whether the app is authorized to manage this subscription per its metadata.
* @throws UnsupportedOperationException if this subscription is not embedded.
* @hide
- *
- * TODO(b/35851809): Make this public.
+ * @deprecated - Do not use.
*/
+ @Deprecated
public boolean canManageSubscription(Context context) {
return canManageSubscription(context, context.getPackageName());
}
@@ -367,7 +365,9 @@
* @return whether the app is authorized to manage this subscription per its metadata.
* @throws UnsupportedOperationException if this subscription is not embedded.
* @hide
+ * @deprecated - Do not use.
*/
+ @Deprecated
public boolean canManageSubscription(Context context, String packageName) {
if (!isEmbedded()) {
throw new UnsupportedOperationException("Not an embedded subscription");
@@ -395,14 +395,14 @@
* @return the {@link UiccAccessRule}s dictating who is authorized to manage this subscription.
* @throws UnsupportedOperationException if this subscription is not embedded.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
- public @Nullable UiccAccessRule[] getAccessRules() {
+ @SystemApi
+ public @Nullable List<UiccAccessRule> getAccessRules() {
if (!isEmbedded()) {
throw new UnsupportedOperationException("Not an embedded subscription");
}
- return mAccessRules;
+ if (mAccessRules == null) return null;
+ return Arrays.asList(mAccessRules);
}
/**
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 1fae04b..30e75b9 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -23,6 +23,8 @@
import android.annotation.SystemService;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.net.INetworkPolicyManager;
@@ -751,10 +753,13 @@
* if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
* then by {@link SubscriptionInfo#getSubscriptionId}.
* </ul>
- * @hide
*
- * TODO(b/35851809): Make this a SystemApi.
+ * <p>
+ * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
+ * for #getAvailableSubscriptionInfoList to be invoked.
+ * @hide
*/
+ @SystemApi
public List<SubscriptionInfo> getAvailableSubscriptionInfoList() {
List<SubscriptionInfo> result = null;
@@ -792,9 +797,6 @@
* if the list is non-empty the list is sorted by {@link SubscriptionInfo#getSimSlotIndex}
* then by {@link SubscriptionInfo#getSubscriptionId}.
* </ul>
- * @hide
- *
- * TODO(b/35851809): Make this public.
*/
public List<SubscriptionInfo> getAccessibleSubscriptionInfoList() {
List<SubscriptionInfo> result = null;
@@ -820,9 +822,8 @@
*
* <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
public void requestEmbeddedSubscriptionInfoListRefresh() {
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -1668,4 +1669,51 @@
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Checks whether the app with the given context is authorized to manage the given subscription
+ * according to its metadata. Only supported for embedded subscriptions (if
+ * {@code SubscriptionInfo#isEmbedded} returns true).
+ *
+ * @param info The subscription to check.
+ * @return whether the app is authorized to manage this subscription per its metadata.
+ * @throws UnsupportedOperationException if this subscription is not embedded.
+ */
+ public boolean canManageSubscription(SubscriptionInfo info) {
+ return canManageSubscription(info, mContext.getPackageName());
+ }
+
+ /**
+ * Checks whether the given app is authorized to manage the given subscription according to its
+ * metadata. Only supported for embedded subscriptions (if {@code SubscriptionInfo#isEmbedded}
+ * returns true).
+ *
+ * @param info The subscription to check.
+ * @param packageName Package name of the app to check.
+ * @return whether the app is authorized to manage this subscription per its metadata.
+ * @throws UnsupportedOperationException if this subscription is not embedded.
+ * @hide
+ */
+ public boolean canManageSubscription(SubscriptionInfo info, String packageName) {
+ if (!info.isEmbedded()) {
+ throw new UnsupportedOperationException("Not an embedded subscription");
+ }
+ if (info.getAccessRules() == null) {
+ return false;
+ }
+ PackageManager packageManager = mContext.getPackageManager();
+ PackageInfo packageInfo;
+ try {
+ packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new IllegalArgumentException("Unknown package: " + packageName, e);
+ }
+ for (UiccAccessRule rule : info.getAccessRules()) {
+ if (rule.getCarrierPrivilegeStatus(packageInfo)
+ == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/telephony/java/android/telephony/Telephony.java b/telephony/java/android/telephony/Telephony.java
index 8c45724..63263bd 100644
--- a/telephony/java/android/telephony/Telephony.java
+++ b/telephony/java/android/telephony/Telephony.java
@@ -33,6 +33,7 @@
import android.telephony.ServiceState;
import android.telephony.SmsMessage;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Patterns;
@@ -3345,73 +3346,118 @@
}
/**
- * Contains carrier identification information.
- * @hide
+ * Contains carrier identification information for the current subscriptions.
+ * @see SubscriptionManager#getActiveSubscriptionIdList()
*/
public static final class CarrierIdentification implements BaseColumns {
/**
- * Numeric operator ID (as String). {@code MCC + MNC}
- * <P>Type: TEXT </P>
+ * Not instantiable.
+ * @hide
*/
- public static final String MCCMNC = "mccmnc";
+ private CarrierIdentification() {}
/**
- * Group id level 1 (as String).
- * <P>Type: TEXT </P>
+ * The {@code content://} style URI for this provider.
*/
- public static final String GID1 = "gid1";
+ public static final Uri CONTENT_URI = Uri.parse("content://carrier_identification");
/**
- * Group id level 2 (as String).
- * <P>Type: TEXT </P>
+ * The authority string for the CarrierIdentification Provider
+ * @hide
*/
- public static final String GID2 = "gid2";
+ public static final String AUTHORITY = "carrier_identification";
+
/**
- * Public Land Mobile Network name.
- * <P>Type: TEXT </P>
+ * Generates a content {@link Uri} used to receive updates on carrier identity change
+ * on the given subscriptionId
+ * <p>
+ * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
+ * carrier identity {@link TelephonyManager#getAndroidCarrierIdForSubscription()}
+ * while your app is running. You can also use a {@link JobService} to ensure your app
+ * is notified of changes to the {@link Uri} even when it is not running.
+ * Note, however, that using a {@link JobService} does not guarantee timely delivery of
+ * updates to the {@link Uri}.
+ *
+ * @param subscriptionId the subscriptionId to receive updates on
+ * @return the Uri used to observe carrier identity changes
*/
- public static final String PLMN = "plmn";
+ public static Uri getUriForSubscriptionId(int subscriptionId) {
+ return CONTENT_URI.buildUpon().appendEncodedPath(
+ String.valueOf(subscriptionId)).build();
+ }
/**
- * Prefix xpattern of IMSI (International Mobile Subscriber Identity).
- * <P>Type: TEXT </P>
- */
- public static final String IMSI_PREFIX_XPATTERN = "imsi_prefix_xpattern";
-
- /**
- * Service Provider Name.
- * <P>Type: TEXT </P>
- */
- public static final String SPN = "spn";
-
- /**
- * Prefer APN name.
- * <P>Type: TEXT </P>
- */
- public static final String APN = "apn";
-
- /**
- * Prefix of Integrated Circuit Card Identifier.
- * <P>Type: TEXT </P>
- */
- public static final String ICCID_PREFIX = "iccid_prefix";
-
- /**
- * User facing carrier name.
+ * A user facing carrier name.
+ * @see TelephonyManager#getAndroidCarrierNameForSubscription()
* <P>Type: TEXT </P>
*/
public static final String NAME = "carrier_name";
/**
* A unique carrier id
+ * @see TelephonyManager#getAndroidCarrierIdForSubscription()
* <P>Type: INTEGER </P>
*/
public static final String CID = "carrier_id";
/**
- * The {@code content://} URI for this table.
+ * Contains mappings between matching rules with carrier id for all carriers.
+ * @hide
*/
- public static final Uri CONTENT_URI = Uri.parse("content://carrier_identification");
+ public static final class All implements BaseColumns {
+ /**
+ * Numeric operator ID (as String). {@code MCC + MNC}
+ * <P>Type: TEXT </P>
+ */
+ public static final String MCCMNC = "mccmnc";
+
+ /**
+ * Group id level 1 (as String).
+ * <P>Type: TEXT </P>
+ */
+ public static final String GID1 = "gid1";
+
+ /**
+ * Group id level 2 (as String).
+ * <P>Type: TEXT </P>
+ */
+ public static final String GID2 = "gid2";
+
+ /**
+ * Public Land Mobile Network name.
+ * <P>Type: TEXT </P>
+ */
+ public static final String PLMN = "plmn";
+
+ /**
+ * Prefix xpattern of IMSI (International Mobile Subscriber Identity).
+ * <P>Type: TEXT </P>
+ */
+ public static final String IMSI_PREFIX_XPATTERN = "imsi_prefix_xpattern";
+
+ /**
+ * Service Provider Name.
+ * <P>Type: TEXT </P>
+ */
+ public static final String SPN = "spn";
+
+ /**
+ * Prefer APN name.
+ * <P>Type: TEXT </P>
+ */
+ public static final String APN = "apn";
+
+ /**
+ * Prefix of Integrated Circuit Card Identifier.
+ * <P>Type: TEXT </P>
+ */
+ public static final String ICCID_PREFIX = "iccid_prefix";
+
+ /**
+ * The {@code content://} URI for this table.
+ */
+ public static final Uri CONTENT_URI = Uri.parse("content://carrier_identification/all");
+ }
}
}
diff --git a/telephony/java/android/telephony/UiccAccessRule.java b/telephony/java/android/telephony/UiccAccessRule.java
index 3937201..c3f8a19 100644
--- a/telephony/java/android/telephony/UiccAccessRule.java
+++ b/telephony/java/android/telephony/UiccAccessRule.java
@@ -16,6 +16,7 @@
package android.telephony;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.content.pm.PackageInfo;
import android.content.pm.Signature;
import android.os.Parcel;
@@ -39,9 +40,8 @@
* specification.
*
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+@SystemApi
public final class UiccAccessRule implements Parcelable {
private static final String TAG = "UiccAccessRule";
diff --git a/telephony/java/android/telephony/euicc/DownloadableSubscription.java b/telephony/java/android/telephony/euicc/DownloadableSubscription.java
index 01041c8..88db22b 100644
--- a/telephony/java/android/telephony/euicc/DownloadableSubscription.java
+++ b/telephony/java/android/telephony/euicc/DownloadableSubscription.java
@@ -16,18 +16,17 @@
package android.telephony.euicc;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.UiccAccessRule;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import com.android.internal.util.Preconditions;
-/**
- * Information about a subscription which is available for download.
- *
- * TODO(b/35851809): Make this public.
- * @hide
- */
+/** Information about a subscription which is available for download. */
public final class DownloadableSubscription implements Parcelable {
public static final Creator<DownloadableSubscription> CREATOR =
@@ -46,11 +45,12 @@
/**
* Activation code. May be null for subscriptions which are not based on activation codes, e.g.
* to download a default subscription assigned to this device.
+ * Should use getEncodedActivationCode() instead.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
+ * @deprecated - Do not use. This will be private. Use getEncodedActivationCode() instead.
*/
@Nullable
+ @Deprecated
public final String encodedActivationCode;
@Nullable private String confirmationCode;
@@ -58,8 +58,16 @@
// see getCarrierName and setCarrierName
@Nullable
private String carrierName;
+
// see getAccessRules and setAccessRules
- private UiccAccessRule[] accessRules;
+ @Nullable
+ private List<UiccAccessRule> accessRules;
+
+ /** Gets the activation code. */
+ @Nullable
+ public String getEncodedActivationCode() {
+ return encodedActivationCode;
+ }
/** @hide */
private DownloadableSubscription(String encodedActivationCode) {
@@ -70,7 +78,59 @@
encodedActivationCode = in.readString();
confirmationCode = in.readString();
carrierName = in.readString();
- accessRules = in.createTypedArray(UiccAccessRule.CREATOR);
+ accessRules = new ArrayList<UiccAccessRule>();
+ in.readTypedList(accessRules, UiccAccessRule.CREATOR);
+ }
+
+ private DownloadableSubscription(String encodedActivationCode, String confirmationCode,
+ String carrierName, List<UiccAccessRule> accessRules) {
+ this.encodedActivationCode = encodedActivationCode;
+ this.confirmationCode = confirmationCode;
+ this.carrierName = carrierName;
+ this.accessRules = accessRules;
+ }
+
+ /** @hide */
+ @SystemApi
+ public static final class Builder {
+ @Nullable private String encodedActivationCode;
+ @Nullable private String confirmationCode;
+ @Nullable private String carrierName;
+ List<UiccAccessRule> accessRules;
+
+ public Builder() {}
+
+ public Builder(DownloadableSubscription baseSubscription) {
+ encodedActivationCode = baseSubscription.getEncodedActivationCode();
+ confirmationCode = baseSubscription.getConfirmationCode();
+ carrierName = baseSubscription.getCarrierName();
+ accessRules = baseSubscription.getAccessRules();
+ }
+
+ public DownloadableSubscription build() {
+ return new DownloadableSubscription(encodedActivationCode, confirmationCode,
+ carrierName, accessRules);
+ }
+
+ public Builder setEncodedActivationCode(String value) {
+ encodedActivationCode = value;
+ return this;
+ }
+
+ public Builder setConfirmationCode(String value) {
+ confirmationCode = value;
+ return this;
+ }
+
+ public Builder setCarrierName(String value) {
+ carrierName = value;
+ return this;
+ }
+
+ public Builder setAccessRules(List<UiccAccessRule> value) {
+ accessRules = value;
+ return this;
+ }
}
/**
@@ -87,7 +147,10 @@
/**
* Sets the confirmation code.
+ * @hide
+ * @deprecated - Do not use.
*/
+ @Deprecated
public void setConfirmationCode(String confirmationCode) {
this.confirmationCode = confirmationCode;
}
@@ -103,9 +166,9 @@
/**
* Set the user-visible carrier name.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
+ * @deprecated - Do not use.
*/
+ @Deprecated
public void setCarrierName(String carrierName) {
this.carrierName = carrierName;
}
@@ -117,44 +180,51 @@
* those created with {@link #forActivationCode}). May be populated with
* {@link EuiccManager#getDownloadableSubscriptionMetadata}.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
@Nullable
public String getCarrierName() {
return carrierName;
}
/**
- * Returns the {@link UiccAccessRule}s dictating access to this subscription.
+ * Returns the {@link UiccAccessRule}s in list dictating access to this subscription.
*
* <p>Only present for downloadable subscriptions that were queried from a server (as opposed to
* those created with {@link #forActivationCode}). May be populated with
* {@link EuiccManager#getDownloadableSubscriptionMetadata}.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
- public UiccAccessRule[] getAccessRules() {
+ @SystemApi
+ public List<UiccAccessRule> getAccessRules() {
return accessRules;
}
/**
* Set the {@link UiccAccessRule}s dictating access to this subscription.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
+ * @deprecated - Do not use.
*/
- public void setAccessRules(UiccAccessRule[] accessRules) {
+ @Deprecated
+ public void setAccessRules(List<UiccAccessRule> accessRules) {
this.accessRules = accessRules;
}
+ /**
+ * @hide
+ * @deprecated - Do not use.
+ */
+ @Deprecated
+ public void setAccessRules(UiccAccessRule[] accessRules) {
+ this.accessRules = Arrays.asList(accessRules);
+ }
+
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(encodedActivationCode);
dest.writeString(confirmationCode);
dest.writeString(carrierName);
- dest.writeTypedArray(accessRules, flags);
+ dest.writeTypedList(accessRules);
}
@Override
diff --git a/telephony/java/android/telephony/euicc/EuiccCardManager.java b/telephony/java/android/telephony/euicc/EuiccCardManager.java
index a1a6a5a..6be7725 100644
--- a/telephony/java/android/telephony/euicc/EuiccCardManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccCardManager.java
@@ -17,6 +17,7 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -49,14 +50,13 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
/**
* EuiccCardManager is the application interface to an eSIM card.
- *
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+@SystemApi
public class EuiccCardManager {
private static final String TAG = "EuiccCardManager";
@@ -68,6 +68,7 @@
CANCEL_REASON_TIMEOUT,
CANCEL_REASON_PPR_NOT_ALLOWED
})
+ /** @hide */
public @interface CancelReason {}
/**
@@ -96,6 +97,7 @@
RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES,
RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS
})
+ /** @hide */
public @interface ResetOption {}
/** Deletes all operational profiles. */
@@ -143,18 +145,20 @@
}
/**
- * Gets all the profiles on eUicc.
+ * Requests all the profiles on eUicc.
*
* @param cardId The Id of the eUICC.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code and all the profiles.
*/
- public void getAllProfiles(String cardId, ResultCallback<EuiccProfileInfo[]> callback) {
+ public void requestAllProfiles(String cardId, Executor executor,
+ ResultCallback<EuiccProfileInfo[]> callback) {
try {
getIEuiccCardController().getAllProfiles(mContext.getOpPackageName(), cardId,
new IGetAllProfilesCallback.Stub() {
@Override
public void onComplete(int resultCode, EuiccProfileInfo[] profiles) {
- callback.onComplete(resultCode, profiles);
+ executor.execute(() -> callback.onComplete(resultCode, profiles));
}
});
} catch (RemoteException e) {
@@ -164,19 +168,21 @@
}
/**
- * Gets the profile of the given iccid.
+ * Requests the profile of the given iccid.
*
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code and profile.
*/
- public void getProfile(String cardId, String iccid, ResultCallback<EuiccProfileInfo> callback) {
+ public void requestProfile(String cardId, String iccid, Executor executor,
+ ResultCallback<EuiccProfileInfo> callback) {
try {
getIEuiccCardController().getProfile(mContext.getOpPackageName(), cardId, iccid,
new IGetProfileCallback.Stub() {
@Override
public void onComplete(int resultCode, EuiccProfileInfo profile) {
- callback.onComplete(resultCode, profile);
+ executor.execute(() -> callback.onComplete(resultCode, profile));
}
});
} catch (RemoteException e) {
@@ -191,16 +197,17 @@
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile.
* @param refresh Whether sending the REFRESH command to modem.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code.
*/
- public void disableProfile(String cardId, String iccid, boolean refresh,
+ public void disableProfile(String cardId, String iccid, boolean refresh, Executor executor,
ResultCallback<Void> callback) {
try {
getIEuiccCardController().disableProfile(mContext.getOpPackageName(), cardId, iccid,
refresh, new IDisableProfileCallback.Stub() {
@Override
public void onComplete(int resultCode) {
- callback.onComplete(resultCode, null);
+ executor.execute(() -> callback.onComplete(resultCode, null));
}
});
} catch (RemoteException e) {
@@ -216,16 +223,17 @@
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile to switch to.
* @param refresh Whether sending the REFRESH command to modem.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code and the EuiccProfileInfo enabled.
*/
- public void switchToProfile(String cardId, String iccid, boolean refresh,
+ public void switchToProfile(String cardId, String iccid, boolean refresh, Executor executor,
ResultCallback<EuiccProfileInfo> callback) {
try {
getIEuiccCardController().switchToProfile(mContext.getOpPackageName(), cardId, iccid,
refresh, new ISwitchToProfileCallback.Stub() {
@Override
public void onComplete(int resultCode, EuiccProfileInfo profile) {
- callback.onComplete(resultCode, profile);
+ executor.execute(() -> callback.onComplete(resultCode, profile));
}
});
} catch (RemoteException e) {
@@ -240,16 +248,17 @@
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile.
* @param nickname The nickname of the profile.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code.
*/
- public void setNickname(String cardId, String iccid, String nickname,
+ public void setNickname(String cardId, String iccid, String nickname, Executor executor,
ResultCallback<Void> callback) {
try {
getIEuiccCardController().setNickname(mContext.getOpPackageName(), cardId, iccid,
nickname, new ISetNicknameCallback.Stub() {
@Override
public void onComplete(int resultCode) {
- callback.onComplete(resultCode, null);
+ executor.execute(() -> callback.onComplete(resultCode, null));
}
});
} catch (RemoteException e) {
@@ -263,15 +272,17 @@
*
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code.
*/
- public void deleteProfile(String cardId, String iccid, ResultCallback<Void> callback) {
+ public void deleteProfile(String cardId, String iccid, Executor executor,
+ ResultCallback<Void> callback) {
try {
getIEuiccCardController().deleteProfile(mContext.getOpPackageName(), cardId, iccid,
new IDeleteProfileCallback.Stub() {
@Override
public void onComplete(int resultCode) {
- callback.onComplete(resultCode, null);
+ executor.execute(() -> callback.onComplete(resultCode, null));
}
});
} catch (RemoteException e) {
@@ -286,15 +297,17 @@
* @param cardId The Id of the eUICC.
* @param options Bits of the options of resetting which parts of the eUICC memory. See
* EuiccCard for details.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code.
*/
- public void resetMemory(String cardId, @ResetOption int options, ResultCallback<Void> callback) {
+ public void resetMemory(String cardId, @ResetOption int options, Executor executor,
+ ResultCallback<Void> callback) {
try {
getIEuiccCardController().resetMemory(mContext.getOpPackageName(), cardId, options,
new IResetMemoryCallback.Stub() {
@Override
public void onComplete(int resultCode) {
- callback.onComplete(resultCode, null);
+ executor.execute(() -> callback.onComplete(resultCode, null));
}
});
} catch (RemoteException e) {
@@ -304,18 +317,20 @@
}
/**
- * Gets the default SM-DP+ address from eUICC.
+ * Requests the default SM-DP+ address from eUICC.
*
* @param cardId The Id of the eUICC.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code and the default SM-DP+ address.
*/
- public void getDefaultSmdpAddress(String cardId, ResultCallback<String> callback) {
+ public void requestDefaultSmdpAddress(String cardId, Executor executor,
+ ResultCallback<String> callback) {
try {
getIEuiccCardController().getDefaultSmdpAddress(mContext.getOpPackageName(), cardId,
new IGetDefaultSmdpAddressCallback.Stub() {
@Override
public void onComplete(int resultCode, String address) {
- callback.onComplete(resultCode, address);
+ executor.execute(() -> callback.onComplete(resultCode, address));
}
});
} catch (RemoteException e) {
@@ -325,18 +340,20 @@
}
/**
- * Gets the SM-DS address from eUICC.
+ * Requests the SM-DS address from eUICC.
*
* @param cardId The Id of the eUICC.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code and the SM-DS address.
*/
- public void getSmdsAddress(String cardId, ResultCallback<String> callback) {
+ public void requestSmdsAddress(String cardId, Executor executor,
+ ResultCallback<String> callback) {
try {
getIEuiccCardController().getSmdsAddress(mContext.getOpPackageName(), cardId,
new IGetSmdsAddressCallback.Stub() {
@Override
public void onComplete(int resultCode, String address) {
- callback.onComplete(resultCode, address);
+ executor.execute(() -> callback.onComplete(resultCode, address));
}
});
} catch (RemoteException e) {
@@ -350,16 +367,18 @@
*
* @param cardId The Id of the eUICC.
* @param defaultSmdpAddress The default SM-DP+ address to set.
+ * @param executor The executor through which the callback should be invode.
* @param callback The callback to get the result code.
*/
- public void setDefaultSmdpAddress(String cardId, String defaultSmdpAddress, ResultCallback<Void> callback) {
+ public void setDefaultSmdpAddress(String cardId, String defaultSmdpAddress, Executor executor,
+ ResultCallback<Void> callback) {
try {
getIEuiccCardController().setDefaultSmdpAddress(mContext.getOpPackageName(), cardId,
defaultSmdpAddress,
new ISetDefaultSmdpAddressCallback.Stub() {
@Override
public void onComplete(int resultCode) {
- callback.onComplete(resultCode, null);
+ executor.execute(() -> callback.onComplete(resultCode, null));
}
});
} catch (RemoteException e) {
@@ -369,18 +388,20 @@
}
/**
- * Gets Rules Authorisation Table.
+ * Requests Rules Authorisation Table.
*
* @param cardId The Id of the eUICC.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and the rule authorisation table.
*/
- public void getRulesAuthTable(String cardId, ResultCallback<EuiccRulesAuthTable> callback) {
+ public void requestRulesAuthTable(String cardId, Executor executor,
+ ResultCallback<EuiccRulesAuthTable> callback) {
try {
getIEuiccCardController().getRulesAuthTable(mContext.getOpPackageName(), cardId,
new IGetRulesAuthTableCallback.Stub() {
@Override
public void onComplete(int resultCode, EuiccRulesAuthTable rat) {
- callback.onComplete(resultCode, rat);
+ executor.execute(() -> callback.onComplete(resultCode, rat));
}
});
} catch (RemoteException e) {
@@ -390,18 +411,20 @@
}
/**
- * Gets the eUICC challenge for new profile downloading.
+ * Requests the eUICC challenge for new profile downloading.
*
* @param cardId The Id of the eUICC.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and the challenge.
*/
- public void getEuiccChallenge(String cardId, ResultCallback<byte[]> callback) {
+ public void requestEuiccChallenge(String cardId, Executor executor,
+ ResultCallback<byte[]> callback) {
try {
getIEuiccCardController().getEuiccChallenge(mContext.getOpPackageName(), cardId,
new IGetEuiccChallengeCallback.Stub() {
@Override
public void onComplete(int resultCode, byte[] challenge) {
- callback.onComplete(resultCode, challenge);
+ executor.execute(() -> callback.onComplete(resultCode, challenge));
}
});
} catch (RemoteException e) {
@@ -411,18 +434,20 @@
}
/**
- * Gets the eUICC info1 defined in GSMA RSP v2.0+ for new profile downloading.
+ * Requests the eUICC info1 defined in GSMA RSP v2.0+ for new profile downloading.
*
* @param cardId The Id of the eUICC.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and the info1.
*/
- public void getEuiccInfo1(String cardId, ResultCallback<byte[]> callback) {
+ public void requestEuiccInfo1(String cardId, Executor executor,
+ ResultCallback<byte[]> callback) {
try {
getIEuiccCardController().getEuiccInfo1(mContext.getOpPackageName(), cardId,
new IGetEuiccInfo1Callback.Stub() {
@Override
public void onComplete(int resultCode, byte[] info) {
- callback.onComplete(resultCode, info);
+ executor.execute(() -> callback.onComplete(resultCode, info));
}
});
} catch (RemoteException e) {
@@ -435,15 +460,17 @@
* Gets the eUICC info2 defined in GSMA RSP v2.0+ for new profile downloading.
*
* @param cardId The Id of the eUICC.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and the info2.
*/
- public void getEuiccInfo2(String cardId, ResultCallback<byte[]> callback) {
+ public void requestEuiccInfo2(String cardId, Executor executor,
+ ResultCallback<byte[]> callback) {
try {
getIEuiccCardController().getEuiccInfo2(mContext.getOpPackageName(), cardId,
new IGetEuiccInfo2Callback.Stub() {
@Override
public void onComplete(int resultCode, byte[] info) {
- callback.onComplete(resultCode, info);
+ executor.execute(() -> callback.onComplete(resultCode, info));
}
});
} catch (RemoteException e) {
@@ -466,12 +493,13 @@
* GSMA RSP v2.0+.
* @param serverCertificate ASN.1 data in byte array indicating SM-DP+ Certificate returned by
* SM-DP+ server.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and a byte array which represents a
* {@code AuthenticateServerResponse} defined in GSMA RSP v2.0+.
*/
public void authenticateServer(String cardId, String matchingId, byte[] serverSigned1,
byte[] serverSignature1, byte[] euiccCiPkIdToBeUsed, byte[] serverCertificate,
- ResultCallback<byte[]> callback) {
+ Executor executor, ResultCallback<byte[]> callback) {
try {
getIEuiccCardController().authenticateServer(
mContext.getOpPackageName(),
@@ -484,7 +512,7 @@
new IAuthenticateServerCallback.Stub() {
@Override
public void onComplete(int resultCode, byte[] response) {
- callback.onComplete(resultCode, response);
+ executor.execute(() -> callback.onComplete(resultCode, response));
}
});
} catch (RemoteException e) {
@@ -505,11 +533,13 @@
* SM-DP+ server.
* @param smdpCertificate ASN.1 data in byte array indicating the SM-DP+ Certificate returned
* by SM-DP+ server.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and a byte array which represents a
* {@code PrepareDownloadResponse} defined in GSMA RSP v2.0+
*/
public void prepareDownload(String cardId, @Nullable byte[] hashCc, byte[] smdpSigned2,
- byte[] smdpSignature2, byte[] smdpCertificate, ResultCallback<byte[]> callback) {
+ byte[] smdpSignature2, byte[] smdpCertificate, Executor executor,
+ ResultCallback<byte[]> callback) {
try {
getIEuiccCardController().prepareDownload(
mContext.getOpPackageName(),
@@ -521,7 +551,7 @@
new IPrepareDownloadCallback.Stub() {
@Override
public void onComplete(int resultCode, byte[] response) {
- callback.onComplete(resultCode, response);
+ executor.execute(() -> callback.onComplete(resultCode, response));
}
});
} catch (RemoteException e) {
@@ -535,11 +565,12 @@
*
* @param cardId The Id of the eUICC.
* @param boundProfilePackage the Bound Profile Package data returned by SM-DP+ server.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and a byte array which represents a
* {@code LoadBoundProfilePackageResponse} defined in GSMA RSP v2.0+.
*/
public void loadBoundProfilePackage(String cardId, byte[] boundProfilePackage,
- ResultCallback<byte[]> callback) {
+ Executor executor, ResultCallback<byte[]> callback) {
try {
getIEuiccCardController().loadBoundProfilePackage(
mContext.getOpPackageName(),
@@ -548,7 +579,7 @@
new ILoadBoundProfilePackageCallback.Stub() {
@Override
public void onComplete(int resultCode, byte[] response) {
- callback.onComplete(resultCode, response);
+ executor.execute(() -> callback.onComplete(resultCode, response));
}
});
} catch (RemoteException e) {
@@ -563,11 +594,12 @@
* @param cardId The Id of the eUICC.
* @param transactionId the transaction ID returned by SM-DP+ server.
* @param reason the cancel reason.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and an byte[] which represents a
* {@code CancelSessionResponse} defined in GSMA RSP v2.0+.
*/
public void cancelSession(String cardId, byte[] transactionId, @CancelReason int reason,
- ResultCallback<byte[]> callback) {
+ Executor executor, ResultCallback<byte[]> callback) {
try {
getIEuiccCardController().cancelSession(
mContext.getOpPackageName(),
@@ -577,7 +609,7 @@
new ICancelSessionCallback.Stub() {
@Override
public void onComplete(int resultCode, byte[] response) {
- callback.onComplete(resultCode, response);
+ executor.execute(() -> callback.onComplete(resultCode, response));
}
});
} catch (RemoteException e) {
@@ -591,16 +623,17 @@
*
* @param cardId The Id of the eUICC.
* @param events bits of the event types ({@link EuiccNotification.Event}) to list.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and the list of notifications.
*/
public void listNotifications(String cardId, @EuiccNotification.Event int events,
- ResultCallback<EuiccNotification[]> callback) {
+ Executor executor, ResultCallback<EuiccNotification[]> callback) {
try {
getIEuiccCardController().listNotifications(mContext.getOpPackageName(), cardId, events,
new IListNotificationsCallback.Stub() {
@Override
public void onComplete(int resultCode, EuiccNotification[] notifications) {
- callback.onComplete(resultCode, notifications);
+ executor.execute(() -> callback.onComplete(resultCode, notifications));
}
});
} catch (RemoteException e) {
@@ -614,16 +647,17 @@
*
* @param cardId The Id of the eUICC.
* @param events bits of the event types ({@link EuiccNotification.Event}) to list.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and the list of notifications.
*/
public void retrieveNotificationList(String cardId, @EuiccNotification.Event int events,
- ResultCallback<EuiccNotification[]> callback) {
+ Executor executor, ResultCallback<EuiccNotification[]> callback) {
try {
getIEuiccCardController().retrieveNotificationList(mContext.getOpPackageName(), cardId,
events, new IRetrieveNotificationListCallback.Stub() {
@Override
public void onComplete(int resultCode, EuiccNotification[] notifications) {
- callback.onComplete(resultCode, notifications);
+ executor.execute(() -> callback.onComplete(resultCode, notifications));
}
});
} catch (RemoteException e) {
@@ -637,16 +671,17 @@
*
* @param cardId The Id of the eUICC.
* @param seqNumber the sequence number of the notification.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code and the notification.
*/
- public void retrieveNotification(String cardId, int seqNumber,
+ public void retrieveNotification(String cardId, int seqNumber, Executor executor,
ResultCallback<EuiccNotification> callback) {
try {
getIEuiccCardController().retrieveNotification(mContext.getOpPackageName(), cardId,
seqNumber, new IRetrieveNotificationCallback.Stub() {
@Override
public void onComplete(int resultCode, EuiccNotification notification) {
- callback.onComplete(resultCode, notification);
+ executor.execute(() -> callback.onComplete(resultCode, notification));
}
});
} catch (RemoteException e) {
@@ -660,9 +695,10 @@
*
* @param cardId The Id of the eUICC.
* @param seqNumber the sequence number of the notification.
+ * @param executor The executor through which the callback should be invode.
* @param callback the callback to get the result code.
*/
- public void removeNotificationFromList(String cardId, int seqNumber,
+ public void removeNotificationFromList(String cardId, int seqNumber, Executor executor,
ResultCallback<Void> callback) {
try {
getIEuiccCardController().removeNotificationFromList(
@@ -672,7 +708,7 @@
new IRemoveNotificationFromListCallback.Stub() {
@Override
public void onComplete(int resultCode) {
- callback.onComplete(resultCode, null);
+ executor.execute(() -> callback.onComplete(resultCode, null));
}
});
} catch (RemoteException e) {
diff --git a/telephony/java/android/telephony/euicc/EuiccInfo.java b/telephony/java/android/telephony/euicc/EuiccInfo.java
index 5bfff08..a4adf05 100644
--- a/telephony/java/android/telephony/euicc/EuiccInfo.java
+++ b/telephony/java/android/telephony/euicc/EuiccInfo.java
@@ -23,9 +23,6 @@
* Information about an eUICC chip/device.
*
* @see EuiccManager#getEuiccInfo
- * @hide
- *
- * TODO(b/35851809): Make this public.
*/
// WARNING: Do not add any privacy-sensitive fields to this class (such as an eUICC identifier)!
// This API is accessible to all applications. Privacy-sensitive fields should be returned in their
@@ -45,12 +42,17 @@
}
};
+ @Nullable
+ private final String osVersion;
+
/**
- * Version of the operating system running on the eUICC. This field is hardware-specific and is
- * not guaranteed to match any particular format.
+ * Gets the version of the operating system running on the eUICC. This field is
+ * hardware-specific and is not guaranteed to match any particular format.
*/
@Nullable
- public final String osVersion;
+ public String getOsVersion() {
+ return osVersion;
+ }
public EuiccInfo(@Nullable String osVersion) {
this.osVersion = osVersion;
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index 662056e..71ef5de 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -42,9 +42,6 @@
* {@link Context#getSystemService(String)} and {@link Context#EUICC_SERVICE}.
*
* <p>See {@link #isEnabled} before attempting to use these APIs.
- *
- * TODO(b/35851809): Make this public.
- * @hide
*/
public class EuiccManager {
@@ -56,6 +53,8 @@
*
* <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
* {@link #isEnabled} is false.
+ *
+ * This is ued by non-LPA app to bring up LUI.
*/
@SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS =
@@ -69,8 +68,10 @@
*
* <p class="note">This is a protected intent that can only be sent
* by the system.
- * TODO(b/35851809): Make this a SystemApi.
+ *
+ * @hide
*/
+ @SystemApi
@SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_OTA_STATUS_CHANGED =
"android.telephony.euicc.action.OTA_STATUS_CHANGED";
@@ -78,12 +79,10 @@
/**
* Broadcast Action: The action sent to carrier app so it knows the carrier setup is not
* completed.
- *
- * TODO(b/35851809): Make this a public API.
*/
@SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_NOTIFY_CARRIER_SETUP =
- "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP";
+ public static final String ACTION_NOTIFY_CARRIER_SETUP_INCOMPLETE =
+ "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE";
/**
* Intent action to provision an embedded subscription.
@@ -95,8 +94,9 @@
* <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
* {@link #isEnabled} is false or if the device is already provisioned.
*
- * TODO(b/35851809): Make this a SystemApi.
+ * @hide
*/
+ @SystemApi
@SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION =
"android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
@@ -143,9 +143,8 @@
* Key for an extra set on {@link #getDownloadableSubscriptionMetadata} PendingIntent result
* callbacks providing the downloadable subscription metadata.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION =
"android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
@@ -153,9 +152,8 @@
* Key for an extra set on {@link #getDefaultDownloadableSubscriptionList} PendingIntent result
* callbacks providing the list of available downloadable subscriptions.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS =
"android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS";
@@ -201,6 +199,7 @@
* Euicc OTA update status which can be got by {@link #getOtaStatus}
* @hide
*/
+ @SystemApi
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"EUICC_OTA_"}, value = {
EUICC_OTA_IN_PROGRESS,
@@ -215,15 +214,37 @@
/**
* An OTA is in progress. During this time, the eUICC is not available and the user may lose
* network access.
+ * @hide
*/
+ @SystemApi
public static final int EUICC_OTA_IN_PROGRESS = 1;
- /** The OTA update failed. */
+
+ /**
+ * The OTA update failed.
+ * @hide
+ */
+ @SystemApi
public static final int EUICC_OTA_FAILED = 2;
- /** The OTA update finished successfully. */
+
+ /**
+ * The OTA update finished successfully.
+ * @hide
+ */
+ @SystemApi
public static final int EUICC_OTA_SUCCEEDED = 3;
- /** The OTA update not needed since current eUICC OS is latest. */
+
+ /**
+ * The OTA update not needed since current eUICC OS is latest.
+ * @hide
+ */
+ @SystemApi
public static final int EUICC_OTA_NOT_NEEDED = 4;
- /** The OTA status is unavailable since eUICC service is unavailable. */
+
+ /**
+ * The OTA status is unavailable since eUICC service is unavailable.
+ * @hide
+ */
+ @SystemApi
public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5;
private final Context mContext;
@@ -276,8 +297,10 @@
*
* @return the status of eUICC OTA. If {@link #isEnabled()} is false or the eUICC is not ready,
* {@link OtaStatus#EUICC_OTA_STATUS_UNAVAILABLE} will be returned.
- * TODO(b/35851809): Make this a SystemApi.
+ *
+ * @hide
*/
+ @SystemApi
public int getOtaStatus() {
if (!isEnabled()) {
return EUICC_OTA_STATUS_UNAVAILABLE;
@@ -292,7 +315,7 @@
/**
* Attempt to download the given {@link DownloadableSubscription}.
*
- * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
+ * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
* or the calling app must be authorized to manage both the currently-active subscription and
* the subscription to be downloaded according to the subscription metadata. Without the former,
* an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
@@ -354,14 +377,16 @@
*
* <p>To be called by the LUI upon completion of a resolvable error flow.
*
+ * <p>Requires that the calling app has the
+ * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
+ *
* @param resolutionIntent The original intent used to start the LUI.
* @param resolutionExtras Resolution-specific extras depending on the result of the resolution.
* For example, this may indicate whether the user has consented or may include the input
* they provided.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
public void continueOperation(Intent resolutionIntent, Bundle resolutionExtras) {
if (!isEnabled()) {
PendingIntent callbackIntent =
@@ -395,9 +420,8 @@
* @param subscription the subscription which needs metadata filled in
* @param callbackIntent a PendingIntent to launch when the operation completes.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
public void getDownloadableSubscriptionMetadata(
DownloadableSubscription subscription, PendingIntent callbackIntent) {
if (!isEnabled()) {
@@ -426,9 +450,8 @@
*
* @param callbackIntent a PendingIntent to launch when the operation completes.
* @hide
- *
- * TODO(b/35851809): Make this a SystemApi.
*/
+ @SystemApi
public void getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent) {
if (!isEnabled()) {
sendUnavailableError(callbackIntent);
@@ -468,7 +491,7 @@
*
* <p>Requires that the calling app has carrier privileges according to the metadata of the
* profile to be deleted, or the
- * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
+ * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
*
* @param subscriptionId the ID of the subscription to delete.
* @param callbackIntent a PendingIntent to launch when the operation completes.
@@ -489,7 +512,7 @@
/**
* Switch to (enable) the given subscription.
*
- * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
+ * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
* or the calling app must be authorized to manage both the currently-active subscription and
* the subscription to be enabled according to the subscription metadata. Without the former,
* an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
@@ -599,11 +622,7 @@
}
}
- /**
- * @hide
- */
- @TestApi
- protected IEuiccController getIEuiccController() {
+ private static IEuiccController getIEuiccController() {
return IEuiccController.Stub.asInterface(ServiceManager.getService("econtroller"));
}
}
diff --git a/telephony/java/android/telephony/euicc/EuiccNotification.java b/telephony/java/android/telephony/euicc/EuiccNotification.java
index ef3c1ce..43a7707 100644
--- a/telephony/java/android/telephony/euicc/EuiccNotification.java
+++ b/telephony/java/android/telephony/euicc/EuiccNotification.java
@@ -17,6 +17,7 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -31,10 +32,9 @@
* disabling, or deleting).
*
* @hide
- *
- * TODO(b/35851809): Make this a @SystemApi.
*/
-public class EuiccNotification implements Parcelable {
+@SystemApi
+public final class EuiccNotification implements Parcelable {
/** Event */
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, prefix = { "EVENT_" }, value = {
@@ -43,6 +43,7 @@
EVENT_DISABLE,
EVENT_DELETE
})
+ /** @hide */
public @interface Event {}
/** A profile is downloaded and installed. */
@@ -57,7 +58,7 @@
/** A profile is deleted. */
public static final int EVENT_DELETE = 1 << 3;
- /** Value of the bits of all above events */
+ /** Value of the bits of all the events including install, enable, disable and delete. */
@Event
public static final int ALL_EVENTS =
EVENT_INSTALL | EVENT_ENABLE | EVENT_DISABLE | EVENT_DELETE;
diff --git a/telephony/java/android/telephony/euicc/EuiccRulesAuthTable.java b/telephony/java/android/telephony/euicc/EuiccRulesAuthTable.java
index 7efe043..67ae983 100644
--- a/telephony/java/android/telephony/euicc/EuiccRulesAuthTable.java
+++ b/telephony/java/android/telephony/euicc/EuiccRulesAuthTable.java
@@ -16,6 +16,7 @@
package android.telephony.euicc;
import android.annotation.IntDef;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.carrier.CarrierIdentifier;
@@ -27,20 +28,21 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
/**
* This represents the RAT (Rules Authorisation Table) stored on eUICC.
- *
* @hide
- *
- * TODO(b/35851809): Make this a @SystemApi.
*/
+@SystemApi
public final class EuiccRulesAuthTable implements Parcelable {
/** Profile policy rule flags */
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, prefix = { "POLICY_RULE_FLAG_" }, value = {
POLICY_RULE_FLAG_CONSENT_REQUIRED
})
+ /** @hide */
public @interface PolicyRuleFlag {}
/** User consent is required to install the profile. */
@@ -89,12 +91,14 @@
* @throws ArrayIndexOutOfBoundsException If the {@code mPosition} is larger than the size
* this table.
*/
- public Builder add(int policyRules, CarrierIdentifier[] carrierId, int policyRuleFlags) {
+ public Builder add(int policyRules, List<CarrierIdentifier> carrierId, int policyRuleFlags) {
if (mPosition >= mPolicyRules.length) {
throw new ArrayIndexOutOfBoundsException(mPosition);
}
mPolicyRules[mPosition] = policyRules;
- mCarrierIds[mPosition] = carrierId;
+ if (carrierId != null && carrierId.size() > 0) {
+ mCarrierIds[mPosition] = carrierId.toArray(new CarrierIdentifier[carrierId.size()]);
+ }
mPolicyRuleFlags[mPosition] = policyRuleFlags;
mPosition++;
return this;
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index cc792cc..03a617c 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -38,6 +38,7 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.timeout;
@@ -217,7 +218,8 @@
// callback triggers
captor.getValue().send(makeMessage(request, ConnectivityManager.CALLBACK_AVAILABLE));
- verify(callback, timeout(500).times(1)).onAvailable(any());
+ verify(callback, timeout(500).times(1)).onAvailable(any(Network.class),
+ any(NetworkCapabilities.class), any(LinkProperties.class));
// unregister callback
manager.unregisterNetworkCallback(callback);
@@ -244,7 +246,8 @@
// callback triggers
captor.getValue().send(makeMessage(req1, ConnectivityManager.CALLBACK_AVAILABLE));
- verify(callback, timeout(100).times(1)).onAvailable(any());
+ verify(callback, timeout(100).times(1)).onAvailable(any(Network.class),
+ any(NetworkCapabilities.class), any(LinkProperties.class));
// unregister callback
manager.unregisterNetworkCallback(callback);
@@ -335,6 +338,10 @@
static Message makeMessage(NetworkRequest req, int messageType) {
Bundle bundle = new Bundle();
bundle.putParcelable(NetworkRequest.class.getSimpleName(), req);
+ // Pass default objects as we don't care which get passed here
+ bundle.putParcelable(Network.class.getSimpleName(), new Network(1));
+ bundle.putParcelable(NetworkCapabilities.class.getSimpleName(), new NetworkCapabilities());
+ bundle.putParcelable(LinkProperties.class.getSimpleName(), new LinkProperties());
Message msg = Message.obtain();
msg.what = messageType;
msg.setData(bundle);
diff --git a/tests/net/java/android/net/IpSecConfigTest.java b/tests/net/java/android/net/IpSecConfigTest.java
index f6c5532..f186ee5 100644
--- a/tests/net/java/android/net/IpSecConfigTest.java
+++ b/tests/net/java/android/net/IpSecConfigTest.java
@@ -17,6 +17,7 @@
package android.net;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -48,18 +49,12 @@
assertEquals(IpSecManager.INVALID_RESOURCE_ID, c.getSpiResourceId());
}
- @Test
- public void testParcelUnparcel() throws Exception {
- assertParcelingIsLossless(new IpSecConfig());
-
+ private IpSecConfig getSampleConfig() {
IpSecConfig c = new IpSecConfig();
c.setMode(IpSecTransform.MODE_TUNNEL);
c.setSourceAddress("0.0.0.0");
c.setDestinationAddress("1.2.3.4");
- c.setEncapType(android.system.OsConstants.UDP_ENCAP_ESPINUDP);
- c.setEncapSocketResourceId(7);
- c.setEncapRemotePort(22);
- c.setNattKeepaliveInterval(42);
+ c.setSpiResourceId(1984);
c.setEncryption(
new IpSecAlgorithm(
IpSecAlgorithm.CRYPT_AES_CBC,
@@ -68,7 +63,37 @@
new IpSecAlgorithm(
IpSecAlgorithm.AUTH_HMAC_MD5,
new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0}));
- c.setSpiResourceId(1984);
+ c.setAuthenticatedEncryption(
+ new IpSecAlgorithm(
+ IpSecAlgorithm.AUTH_CRYPT_AES_GCM,
+ new byte[] {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0, 1, 2, 3, 4
+ },
+ 128));
+ c.setEncapType(android.system.OsConstants.UDP_ENCAP_ESPINUDP);
+ c.setEncapSocketResourceId(7);
+ c.setEncapRemotePort(22);
+ c.setNattKeepaliveInterval(42);
+ c.setMarkValue(12);
+ c.setMarkMask(23);
+
+ return c;
+ }
+
+ @Test
+ public void testCopyConstructor() {
+ IpSecConfig original = getSampleConfig();
+ IpSecConfig copy = new IpSecConfig(original);
+
+ assertTrue(IpSecConfig.equals(original, copy));
+ assertFalse(original == copy);
+ }
+
+ @Test
+ public void testParcelUnparcel() throws Exception {
+ assertParcelingIsLossless(new IpSecConfig());
+
+ IpSecConfig c = getSampleConfig();
assertParcelingIsLossless(c);
}
diff --git a/tests/net/java/android/net/IpSecTransformTest.java b/tests/net/java/android/net/IpSecTransformTest.java
new file mode 100644
index 0000000..b4342df
--- /dev/null
+++ b/tests/net/java/android/net/IpSecTransformTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 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.net;
+
+import static org.junit.Assert.assertFalse;
+
+import android.support.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Unit tests for {@link IpSecTransform}. */
+@SmallTest
+@RunWith(JUnit4.class)
+public class IpSecTransformTest {
+
+ @Test
+ public void testCreateTransformCopiesConfig() {
+ // Create a config with a few parameters to make sure it's not empty
+ IpSecConfig config = new IpSecConfig();
+ config.setSourceAddress("0.0.0.0");
+ config.setDestinationAddress("1.2.3.4");
+ config.setSpiResourceId(1984);
+
+ IpSecTransform preModification = new IpSecTransform(null, config);
+
+ config.setSpiResourceId(1985);
+ IpSecTransform postModification = new IpSecTransform(null, config);
+
+ assertFalse(IpSecTransform.equals(preModification, postModification));
+ }
+
+ @Test
+ public void testCreateTransformsWithSameConfigEqual() {
+ // Create a config with a few parameters to make sure it's not empty
+ IpSecConfig config = new IpSecConfig();
+ config.setSourceAddress("0.0.0.0");
+ config.setDestinationAddress("1.2.3.4");
+ config.setSpiResourceId(1984);
+
+ IpSecTransform config1 = new IpSecTransform(null, config);
+ IpSecTransform config2 = new IpSecTransform(null, config);
+
+ assertFalse(IpSecTransform.equals(config1, config2));
+ }
+}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index e7abede..24639e9 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -35,6 +35,7 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_RCS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
@@ -528,6 +529,11 @@
mNetworkAgent.sendNetworkInfo(mNetworkInfo);
}
+ public void resume() {
+ mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
+ mNetworkAgent.sendNetworkInfo(mNetworkInfo);
+ }
+
public void disconnect() {
mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
mNetworkAgent.sendNetworkInfo(mNetworkInfo);
@@ -569,6 +575,10 @@
assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS));
return mRedirectUrl;
}
+
+ public NetworkCapabilities getNetworkCapabilities() {
+ return mNetworkCapabilities;
+ }
}
/**
@@ -1273,6 +1283,7 @@
NETWORK_CAPABILITIES,
LINK_PROPERTIES,
SUSPENDED,
+ RESUMED,
LOSING,
LOST,
UNAVAILABLE
@@ -1344,6 +1355,11 @@
}
@Override
+ public void onNetworkResumed(Network network) {
+ setLastCallback(CallbackState.RESUMED, network, null);
+ }
+
+ @Override
public void onLosing(Network network, int maxMsToLive) {
setLastCallback(CallbackState.LOSING, network, maxMsToLive /* autoboxed int */);
}
@@ -2459,16 +2475,31 @@
// Suspend the network.
mCellNetworkAgent.suspend();
+ cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_SUSPENDED,
+ mCellNetworkAgent);
cellNetworkCallback.expectCallback(CallbackState.SUSPENDED, mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
// Register a garden variety default network request.
- final TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback();
+ TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback();
mCm.registerDefaultNetworkCallback(dfltNetworkCallback);
// We should get onAvailable(), onCapabilitiesChanged(), onLinkPropertiesChanged(),
// as well as onNetworkSuspended() in rapid succession.
dfltNetworkCallback.expectAvailableAndSuspendedCallbacks(mCellNetworkAgent, true);
dfltNetworkCallback.assertNoCallback();
+ mCm.unregisterNetworkCallback(dfltNetworkCallback);
+
+ mCellNetworkAgent.resume();
+ cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_SUSPENDED,
+ mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackState.RESUMED, mCellNetworkAgent);
+ cellNetworkCallback.assertNoCallback();
+
+ dfltNetworkCallback = new TestNetworkCallback();
+ mCm.registerDefaultNetworkCallback(dfltNetworkCallback);
+ // This time onNetworkSuspended should not be called.
+ dfltNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
+ dfltNetworkCallback.assertNoCallback();
mCm.unregisterNetworkCallback(dfltNetworkCallback);
mCm.unregisterNetworkCallback(cellNetworkCallback);
@@ -3682,8 +3713,7 @@
vpnNetworkCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent);
genericNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, vpnNetworkAgent);
- vpnNetworkCallback.expectCapabilitiesLike(
- nc -> nc.appliesToUid(uid) && !nc.appliesToUid(uid + 1), vpnNetworkAgent);
+ vpnNetworkCallback.expectCapabilitiesLike(nc -> null == nc.getUids(), vpnNetworkAgent);
ranges.clear();
vpnNetworkAgent.setUids(ranges);