Merge "Remove libpac as a JNI library in Android.mk"
diff --git a/Android.bp b/Android.bp
index 04f2040..ab2bd9d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1006,6 +1006,7 @@
"core/java/android/annotation/IntDef.java",
"core/java/android/annotation/NonNull.java",
"core/java/android/annotation/SystemApi.java",
+ "core/java/android/annotation/TestApi.java",
"core/java/android/os/HwBinder.java",
"core/java/android/os/HwBlob.java",
"core/java/android/os/HwParcel.java",
diff --git a/api/current.txt b/api/current.txt
index a3b3722..7c7429f 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -35184,6 +35184,12 @@
field public static final java.lang.String CACHED_NUMBER_TYPE = "numbertype";
field public static final java.lang.String CACHED_PHOTO_ID = "photo_id";
field public static final java.lang.String CACHED_PHOTO_URI = "photo_uri";
+ field public static final java.lang.String CALL_ID_APP_NAME = "call_id_app_name";
+ field public static final java.lang.String CALL_ID_DESCRIPTION = "call_id_description";
+ field public static final java.lang.String CALL_ID_DETAILS = "call_id_details";
+ field public static final java.lang.String CALL_ID_NAME = "call_id_name";
+ field public static final java.lang.String CALL_ID_NUISANCE_CONFIDENCE = "call_id_nuisance_confidence";
+ field public static final java.lang.String CALL_ID_PACKAGE_NAME = "call_id_package_name";
field public static final java.lang.String CALL_SCREENING_APP_NAME = "call_screening_app_name";
field public static final java.lang.String CALL_SCREENING_COMPONENT_NAME = "call_screening_component_name";
field public static final android.net.Uri CONTENT_FILTER_URI;
@@ -41185,6 +41191,7 @@
method public static java.lang.String capabilitiesToString(int);
method public android.telecom.PhoneAccountHandle getAccountHandle();
method public int getCallCapabilities();
+ method public android.telecom.CallIdentification getCallIdentification();
method public int getCallProperties();
method public java.lang.String getCallerDisplayName();
method public int getCallerDisplayNamePresentation();
@@ -41263,6 +41270,34 @@
field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5
}
+ public final class CallIdentification implements android.os.Parcelable {
+ method public int describeContents();
+ method public java.lang.String getCallScreeningAppName();
+ method public java.lang.String getCallScreeningPackageName();
+ method public java.lang.String getDescription();
+ method public java.lang.String getDetails();
+ method public java.lang.String getName();
+ method public int getNuisanceConfidence();
+ method public android.graphics.drawable.Icon getPhoto();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CONFIDENCE_LIKELY_NOT_NUISANCE = -1; // 0xffffffff
+ field public static final int CONFIDENCE_LIKELY_NUISANCE = 1; // 0x1
+ field public static final int CONFIDENCE_NOT_NUISANCE = -2; // 0xfffffffe
+ field public static final int CONFIDENCE_NUISANCE = 2; // 0x2
+ field public static final int CONFIDENCE_UNKNOWN = 0; // 0x0
+ field public static final android.os.Parcelable.Creator<android.telecom.CallIdentification> CREATOR;
+ }
+
+ public static class CallIdentification.Builder {
+ ctor public CallIdentification.Builder();
+ method public android.telecom.CallIdentification build();
+ method public android.telecom.CallIdentification.Builder setDescription(java.lang.String);
+ method public android.telecom.CallIdentification.Builder setDetails(java.lang.String);
+ method public android.telecom.CallIdentification.Builder setName(java.lang.String);
+ method public android.telecom.CallIdentification.Builder setNuisanceConfidence(int);
+ method public android.telecom.CallIdentification.Builder setPhoto(android.graphics.drawable.Icon);
+ }
+
public abstract class CallRedirectionService extends android.app.Service {
ctor public CallRedirectionService();
method public final void cancelCall();
@@ -41278,6 +41313,7 @@
ctor public CallScreeningService();
method public android.os.IBinder onBind(android.content.Intent);
method public abstract void onScreenCall(android.telecom.Call.Details);
+ method public final void provideCallIdentification(android.telecom.Call.Details, android.telecom.CallIdentification);
method public final void respondToCall(android.telecom.Call.Details, android.telecom.CallScreeningService.CallResponse);
field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.CallScreeningService";
}
@@ -41453,10 +41489,12 @@
field public static final int CAPABILITY_SWAP_CONFERENCE = 8; // 0x8
field public static final java.lang.String EVENT_CALL_MERGE_FAILED = "android.telecom.event.CALL_MERGE_FAILED";
field public static final java.lang.String EVENT_CALL_PULL_FAILED = "android.telecom.event.CALL_PULL_FAILED";
+ field public static final java.lang.String EVENT_RTT_AUDIO_INDICATION_CHANGED = "android.telecom.event.RTT_AUDIO_INDICATION_CHANGED";
field public static final java.lang.String EXTRA_ANSWERING_DROPS_FG_CALL = "android.telecom.extra.ANSWERING_DROPS_FG_CALL";
field public static final java.lang.String EXTRA_ANSWERING_DROPS_FG_CALL_APP_NAME = "android.telecom.extra.ANSWERING_DROPS_FG_CALL_APP_NAME";
field public static final java.lang.String EXTRA_CALL_SUBJECT = "android.telecom.extra.CALL_SUBJECT";
field public static final java.lang.String EXTRA_CHILD_ADDRESS = "android.telecom.extra.CHILD_ADDRESS";
+ field public static final java.lang.String EXTRA_IS_RTT_AUDIO_PRESENT = "android.telecom.extra.IS_RTT_AUDIO_PRESENT";
field public static final java.lang.String EXTRA_LAST_FORWARDED_NUMBER = "android.telecom.extra.LAST_FORWARDED_NUMBER";
field public static final java.lang.String EXTRA_SIP_INVITE = "android.telecom.extra.SIP_INVITE";
field public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 32; // 0x20
@@ -41873,7 +41911,6 @@
method public java.lang.String getVoiceMailNumber(android.telecom.PhoneAccountHandle);
method public boolean handleMmi(java.lang.String);
method public boolean handleMmi(java.lang.String, android.telecom.PhoneAccountHandle);
- method public boolean isDefaultCallScreeningApp(android.content.ComponentName);
method public boolean isInCall();
method public boolean isInManagedCall();
method public boolean isIncomingCallPermitted(android.telecom.PhoneAccountHandle);
@@ -41882,7 +41919,6 @@
method public boolean isVoiceMailNumber(android.telecom.PhoneAccountHandle, java.lang.String);
method public void placeCall(android.net.Uri, android.os.Bundle);
method public void registerPhoneAccount(android.telecom.PhoneAccount);
- method public void requestChangeDefaultCallScreeningApp(android.content.ComponentName);
method public void showInCallScreen(boolean);
method public void silenceRinger();
method public void unregisterPhoneAccount(android.telecom.PhoneAccountHandle);
@@ -42732,6 +42768,7 @@
method public int describeContents();
method public int getCdmaDbm();
method public int getCdmaEcio();
+ method public java.util.List<android.telephony.CellSignalStrength> getCellSignalStrengths();
method public int getEvdoDbm();
method public int getEvdoEcio();
method public int getEvdoSnr();
@@ -42925,6 +42962,8 @@
method public void removeOnOpportunisticSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
method public boolean removeSubscriptionsFromGroup(int[]);
+ method public boolean setMetered(boolean, int);
+ method public boolean setOpportunistic(boolean, int);
method public java.lang.String setSubscriptionGroup(int[]);
method public void setSubscriptionOverrideCongested(int, boolean, long);
method public void setSubscriptionOverrideUnmetered(int, boolean, long);
@@ -43171,6 +43210,9 @@
public static abstract class TelephonyManager.CellInfoCallback {
ctor public TelephonyManager.CellInfoCallback();
method public abstract void onCellInfo(java.util.List<android.telephony.CellInfo>);
+ method public void onError(int, java.lang.Throwable);
+ field public static final int ERROR_MODEM_ERROR = 2; // 0x2
+ field public static final int ERROR_TIMEOUT = 1; // 0x1
}
public static abstract class TelephonyManager.UssdResponseCallback {
@@ -43392,6 +43434,7 @@
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);
+ method public void updateSubscriptionNickname(int, java.lang.String, 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
diff --git a/api/system-current.txt b/api/system-current.txt
index 25f35bb..7daab86 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4435,6 +4435,16 @@
package android.service.euicc {
+ public final class DownloadSubscriptionResult implements android.os.Parcelable {
+ ctor public DownloadSubscriptionResult(int, int, int);
+ method public int describeContents();
+ method public int getCardId();
+ method public int getResolvableErrors();
+ method public int getResult();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.euicc.DownloadSubscriptionResult> CREATOR;
+ }
+
public final class EuiccProfileInfo implements android.os.Parcelable {
method public int describeContents();
method public android.service.carrier.CarrierIdentifier getCarrierIdentifier();
@@ -4488,7 +4498,8 @@
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 android.service.euicc.DownloadSubscriptionResult onDownloadSubscription(int, android.telephony.euicc.DownloadableSubscription, boolean, boolean, android.os.Bundle);
+ method public deprecated 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);
@@ -4502,19 +4513,25 @@
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 deprecated 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 ACTION_RESOLVE_RESOLVABLE_ERRORS = "android.service.euicc.action.RESOLVE_RESOLVABLE_ERRORS";
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_ALLOW_POLICY_RULES = "android.service.euicc.extra.RESOLUTION_ALLOW_POLICY_RULES";
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 java.lang.String EXTRA_RESOLVABLE_ERRORS = "android.service.euicc.extra.RESOLVABLE_ERRORS";
+ field public static final int RESOLVABLE_ERROR_CONFIRMATION_CODE = 1; // 0x1
+ field public static final int RESOLVABLE_ERROR_POLICY_RULES = 2; // 0x2
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 deprecated int RESULT_NEED_CONFIRMATION_CODE = -2; // 0xfffffffe
field public static final int RESULT_OK = 0; // 0x0
+ field public static final int RESULT_RESOLVABLE_ERRORS = -2; // 0xfffffffe
}
public static abstract class EuiccService.OtaStatusChangedCallback {
@@ -5035,7 +5052,7 @@
method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsSupportingScheme(java.lang.String);
method public boolean isInEmergencyCall();
method public boolean isRinging();
- method public boolean setDefaultDialer(java.lang.String);
+ method public deprecated boolean setDefaultDialer(java.lang.String);
field public static final java.lang.String EXTRA_CALL_BACK_INTENT = "android.telecom.extra.CALL_BACK_INTENT";
field public static final java.lang.String EXTRA_CLEAR_MISSED_CALLS_INTENT = "android.telecom.extra.CLEAR_MISSED_CALLS_INTENT";
field public static final java.lang.String EXTRA_CONNECTION_SERVICE = "android.telecom.extra.CONNECTION_SERVICE";
@@ -5054,6 +5071,40 @@
field public static final int WWAN = 1; // 0x1
}
+ public class CallAttributes implements android.os.Parcelable {
+ ctor public CallAttributes(android.telephony.PreciseCallState, int, android.telephony.CallQuality);
+ method public int describeContents();
+ method public android.telephony.CallQuality getCallQuality();
+ method public int getNetworkType();
+ method public android.telephony.PreciseCallState getPreciseCallState();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
+ }
+
+ public final class CallQuality implements android.os.Parcelable {
+ ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int);
+ method public int describeContents();
+ method public int getAverageRelativeJitter();
+ method public int getAverageRoundTripTime();
+ method public int getCallDuration();
+ method public int getCodecType();
+ method public int getDownlinkCallQualityLevel();
+ method public int getMaxRelativeJitter();
+ method public int getNumRtpPacketsNotReceived();
+ method public int getNumRtpPacketsReceived();
+ method public int getNumRtpPacketsTransmitted();
+ method public int getNumRtpPacketsTransmittedLost();
+ method public int getUplinkCallQualityLevel();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CALL_QUALITY_BAD = 4; // 0x4
+ field public static final int CALL_QUALITY_EXCELLENT = 0; // 0x0
+ field public static final int CALL_QUALITY_FAIR = 2; // 0x2
+ field public static final int CALL_QUALITY_GOOD = 1; // 0x1
+ field public static final int CALL_QUALITY_NOT_AVAILABLE = 5; // 0x5
+ field public static final int CALL_QUALITY_POOR = 3; // 0x3
+ field public static final android.os.Parcelable.Creator<android.telephony.CallQuality> CREATOR;
+ }
+
public class CarrierConfigManager {
method public static android.os.PersistableBundle getDefaultConfig();
method public void overrideConfig(int, android.os.PersistableBundle);
@@ -5319,12 +5370,14 @@
}
public class PhoneStateListener {
+ method public void onCallAttributesChanged(android.telephony.CallAttributes);
method public void onCallDisconnectCauseChanged(int, int);
method public void onPreciseCallStateChanged(android.telephony.PreciseCallState);
method public void onPreciseDataConnectionStateChanged(android.telephony.PreciseDataConnectionState);
method public void onRadioPowerStateChanged(int);
method public void onSrvccStateChanged(int);
method public void onVoiceActivationStateChanged(int);
+ field public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000
field public static final int LISTEN_CALL_DISCONNECT_CAUSES = 33554432; // 0x2000000
field public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800
field public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000
@@ -5505,6 +5558,7 @@
method public void requestEmbeddedSubscriptionInfoListRefresh();
method public void setDefaultDataSubId(int);
method public void setDefaultSmsSubId(int);
+ method public void requestEmbeddedSubscriptionInfoListRefresh(int);
field public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI;
field public static final int PROFILE_CLASS_DEFAULT = -1; // 0xffffffff
field public static final int PROFILE_CLASS_OPERATIONAL = 2; // 0x2
@@ -5569,6 +5623,7 @@
method public deprecated boolean getDataEnabled(int);
method public boolean getEmergencyCallbackMode();
method public java.lang.String getIsimDomain();
+ method public java.lang.String getIsimIst();
method public int getPreferredNetworkType(int);
method public int getRadioPowerState();
method public int getSimApplicationState();
@@ -6061,6 +6116,7 @@
method public void callSessionInviteParticipantsRequestDelivered();
method public void callSessionInviteParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo);
method public void callSessionMayHandover(int, int);
+ method public void callSessionRttAudioIndicatorChanged(android.telephony.ims.ImsStreamMediaProfile);
method public void callSessionMergeComplete(android.telephony.ims.stub.ImsCallSessionImplBase);
method public void callSessionMergeFailed(android.telephony.ims.ImsReasonInfo);
method public void callSessionMergeStarted(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile);
@@ -6127,6 +6183,7 @@
public class ImsMmTelManager {
method public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(android.content.Context, int);
method public int getVoWiFiModeSetting();
+ method public int getVoWiFiRoamingModeSetting();
method public boolean isAdvancedCallingSettingEnabled();
method public boolean isAvailable(int, int);
method public boolean isCapable(int, int);
@@ -6477,10 +6534,12 @@
method public int describeContents();
method public int getAudioDirection();
method public int getAudioQuality();
+ method public boolean getRttAudioSpeech();
method public int getRttMode();
method public int getVideoDirection();
method public int getVideoQuality();
method public boolean isRttCall();
+ method public void setRttAudioSpeech(boolean);
method public void setRttMode(int);
method public void writeToParcel(android.os.Parcel, int);
field public static final int AUDIO_QUALITY_AMR = 1; // 0x1
diff --git a/api/test-current.txt b/api/test-current.txt
index dfa1c16..f4c2eff 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -631,6 +631,134 @@
method public static java.io.File buildPath(java.io.File, java.lang.String...);
}
+ public abstract class HwBinder implements android.os.IHwBinder {
+ ctor public HwBinder();
+ method public static final void configureRpcThreadpool(long, boolean);
+ method public static void enableInstrumentation();
+ method public static final android.os.IHwBinder getService(java.lang.String, java.lang.String) throws java.util.NoSuchElementException, android.os.RemoteException;
+ method public static final android.os.IHwBinder getService(java.lang.String, java.lang.String, boolean) throws java.util.NoSuchElementException, android.os.RemoteException;
+ method public static final void joinRpcThreadpool();
+ method public abstract void onTransact(int, android.os.HwParcel, android.os.HwParcel, int) throws android.os.RemoteException;
+ method public final void registerService(java.lang.String) throws android.os.RemoteException;
+ method public final void transact(int, android.os.HwParcel, android.os.HwParcel, int) throws android.os.RemoteException;
+ }
+
+ public class HwBlob {
+ ctor public HwBlob(int);
+ method public final void copyToBoolArray(long, boolean[], int);
+ method public final void copyToDoubleArray(long, double[], int);
+ method public final void copyToFloatArray(long, float[], int);
+ method public final void copyToInt16Array(long, short[], int);
+ method public final void copyToInt32Array(long, int[], int);
+ method public final void copyToInt64Array(long, long[], int);
+ method public final void copyToInt8Array(long, byte[], int);
+ method public final boolean getBool(long);
+ method public final double getDouble(long);
+ method public final float getFloat(long);
+ method public final short getInt16(long);
+ method public final int getInt32(long);
+ method public final long getInt64(long);
+ method public final byte getInt8(long);
+ method public final java.lang.String getString(long);
+ method public final long handle();
+ method public final void putBlob(long, android.os.HwBlob);
+ method public final void putBool(long, boolean);
+ method public final void putBoolArray(long, boolean[]);
+ method public final void putDouble(long, double);
+ method public final void putDoubleArray(long, double[]);
+ method public final void putFloat(long, float);
+ method public final void putFloatArray(long, float[]);
+ method public final void putInt16(long, short);
+ method public final void putInt16Array(long, short[]);
+ method public final void putInt32(long, int);
+ method public final void putInt32Array(long, int[]);
+ method public final void putInt64(long, long);
+ method public final void putInt64Array(long, long[]);
+ method public final void putInt8(long, byte);
+ method public final void putInt8Array(long, byte[]);
+ method public final void putNativeHandle(long, android.os.NativeHandle);
+ method public final void putString(long, java.lang.String);
+ method public static java.lang.Boolean[] wrapArray(boolean[]);
+ method public static java.lang.Long[] wrapArray(long[]);
+ method public static java.lang.Byte[] wrapArray(byte[]);
+ method public static java.lang.Short[] wrapArray(short[]);
+ method public static java.lang.Integer[] wrapArray(int[]);
+ method public static java.lang.Float[] wrapArray(float[]);
+ method public static java.lang.Double[] wrapArray(double[]);
+ }
+
+ public class HwParcel {
+ ctor public HwParcel();
+ method public final void enforceInterface(java.lang.String);
+ method public final boolean readBool();
+ method public final java.util.ArrayList<java.lang.Boolean> readBoolVector();
+ method public final android.os.HwBlob readBuffer(long);
+ method public final double readDouble();
+ method public final java.util.ArrayList<java.lang.Double> readDoubleVector();
+ method public final android.os.HwBlob readEmbeddedBuffer(long, long, long, boolean);
+ method public final android.os.NativeHandle readEmbeddedNativeHandle(long, long);
+ method public final float readFloat();
+ method public final java.util.ArrayList<java.lang.Float> readFloatVector();
+ method public final short readInt16();
+ method public final java.util.ArrayList<java.lang.Short> readInt16Vector();
+ method public final int readInt32();
+ method public final java.util.ArrayList<java.lang.Integer> readInt32Vector();
+ method public final long readInt64();
+ method public final java.util.ArrayList<java.lang.Long> readInt64Vector();
+ method public final byte readInt8();
+ method public final java.util.ArrayList<java.lang.Byte> readInt8Vector();
+ method public final android.os.NativeHandle readNativeHandle();
+ method public final java.util.ArrayList<android.os.NativeHandle> readNativeHandleVector();
+ method public final java.lang.String readString();
+ method public final java.util.ArrayList<java.lang.String> readStringVector();
+ method public final android.os.IHwBinder readStrongBinder();
+ method public final void release();
+ method public final void releaseTemporaryStorage();
+ method public final void send();
+ method public final void verifySuccess();
+ method public final void writeBool(boolean);
+ method public final void writeBoolVector(java.util.ArrayList<java.lang.Boolean>);
+ method public final void writeBuffer(android.os.HwBlob);
+ method public final void writeDouble(double);
+ method public final void writeDoubleVector(java.util.ArrayList<java.lang.Double>);
+ method public final void writeFloat(float);
+ method public final void writeFloatVector(java.util.ArrayList<java.lang.Float>);
+ method public final void writeInt16(short);
+ method public final void writeInt16Vector(java.util.ArrayList<java.lang.Short>);
+ method public final void writeInt32(int);
+ method public final void writeInt32Vector(java.util.ArrayList<java.lang.Integer>);
+ method public final void writeInt64(long);
+ method public final void writeInt64Vector(java.util.ArrayList<java.lang.Long>);
+ method public final void writeInt8(byte);
+ method public final void writeInt8Vector(java.util.ArrayList<java.lang.Byte>);
+ method public final void writeInterfaceToken(java.lang.String);
+ method public final void writeNativeHandle(android.os.NativeHandle);
+ method public final void writeNativeHandleVector(java.util.ArrayList<android.os.NativeHandle>);
+ method public final void writeStatus(int);
+ method public final void writeString(java.lang.String);
+ method public final void writeStringVector(java.util.ArrayList<java.lang.String>);
+ method public final void writeStrongBinder(android.os.IHwBinder);
+ field public static final int STATUS_SUCCESS = 0; // 0x0
+ }
+
+ public static abstract class HwParcel.Status implements java.lang.annotation.Annotation {
+ }
+
+ public abstract interface IHwBinder {
+ method public abstract boolean linkToDeath(android.os.IHwBinder.DeathRecipient, long);
+ method public abstract android.os.IHwInterface queryLocalInterface(java.lang.String);
+ method public abstract void transact(int, android.os.HwParcel, android.os.HwParcel, int) throws android.os.RemoteException;
+ method public abstract boolean unlinkToDeath(android.os.IHwBinder.DeathRecipient);
+ }
+
+ public static abstract interface IHwBinder.DeathRecipient {
+ method public abstract void serviceDied(long);
+ }
+
+ public abstract interface IHwInterface {
+ method public abstract android.os.IHwBinder asBinder();
+ }
+
public class IncidentManager {
method public void reportIncident(android.os.IncidentReportArgs);
}
@@ -650,6 +778,18 @@
field public static final android.os.Parcelable.Creator<android.os.IncidentReportArgs> CREATOR;
}
+ public final class NativeHandle implements java.io.Closeable {
+ ctor public NativeHandle();
+ ctor public NativeHandle(java.io.FileDescriptor, boolean);
+ ctor public NativeHandle(java.io.FileDescriptor[], int[], boolean);
+ method public void close() throws java.io.IOException;
+ method public android.os.NativeHandle dup() throws java.io.IOException;
+ method public java.io.FileDescriptor getFileDescriptor();
+ method public java.io.FileDescriptor[] getFileDescriptors();
+ method public int[] getInts();
+ method public boolean hasSingleFileDescriptor();
+ }
+
public final class PowerManager {
method public void nap(long);
}
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 68b6522..7cfa58f 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -24,7 +24,9 @@
import "frameworks/base/core/proto/android/app/enums.proto";
import "frameworks/base/core/proto/android/app/job/enums.proto";
import "frameworks/base/core/proto/android/bluetooth/enums.proto";
+import "frameworks/base/core/proto/android/net/networkcapabilities.proto";
import "frameworks/base/core/proto/android/os/enums.proto";
+import "frameworks/base/core/proto/android/server/connectivity/data_stall_event.proto";
import "frameworks/base/core/proto/android/server/enums.proto";
import "frameworks/base/core/proto/android/stats/launcher/launcher.proto";
import "frameworks/base/core/proto/android/telecomm/enums.proto";
@@ -125,8 +127,8 @@
PhoneServiceStateChanged phone_service_state_changed = 94;
PhoneStateChanged phone_state_changed = 95;
LowMemReported low_mem_reported = 81;
-
-
+ NetworkDnsEventReported network_dns_event_reported = 116;
+ DataStallEvent data_stall_event = 121;
}
// Pulled events will start at field 10000.
@@ -2017,3 +2019,74 @@
// Temperature in tenths of a degree C.
optional int32 temperature_dC = 3;
}
+
+/**
+ * Logs the latency period(in microseconds) and the return code of
+ * the DNS(Domain Name System) lookups.
+ * These 4 methods(GETADDRINFO,GETHOSTBYNAME,GETHOSTBYADDR,RES_NSEND)
+ * to get info(address or hostname) from DNS server(or DNS cache).
+ * Logged from:
+ * /system/netd/server/DnsProxyListener.cpp
+ */
+message NetworkDnsEventReported {
+ // The types of the DNS lookups, as defined in
+ //system/netd/server/binder/android/net/metrics/INetdEventListener.aidl
+ enum EventType {
+ EVENT_UNKNOWN = 0;
+ EVENT_GETADDRINFO = 1;
+ EVENT_GETHOSTBYNAME = 2;
+ EVENT_GETHOSTBYADDR = 3;
+ EVENT_RES_NSEND = 4;
+ }
+ optional EventType event_type = 1;
+
+ // The return value of the DNS resolver for each DNS lookups.
+ //bionic/libc/include/netdb.h
+ //system/netd/resolv/include/netd_resolv/resolv.h
+ enum ReturnCode {
+ EAI_NO_ERROR = 0;
+ EAI_ADDRFAMILY = 1;
+ EAI_AGAIN = 2;
+ EAI_BADFLAGS = 3;
+ EAI_FAIL = 4;
+ EAI_FAMILY = 5;
+ EAI_MEMORY = 6;
+ EAI_NODATA = 7;
+ EAI_NONAME = 8;
+ EAI_SERVICE = 9;
+ EAI_SOCKTYPE = 10;
+ EAI_SYSTEM = 11;
+ EAI_BADHINTS = 12;
+ EAI_PROTOCOL = 13;
+ EAI_OVERFLOW = 14;
+ RESOLV_TIMEOUT = 255;
+ EAI_MAX = 256;
+ }
+ optional ReturnCode return_code = 2;
+
+ // The latency period(in microseconds) it took for this DNS lookup to complete.
+ optional int32 latency_micros = 3;
+}
+
+/**
+ * Logs when a data stall event occurs.
+ *
+ * Log from:
+ * frameworks/base/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+ */
+message DataStallEvent {
+ // Data stall evaluation type.
+ // See frameworks/base/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+ // Refer to the definition of DATA_STALL_EVALUATION_TYPE_*.
+ optional int32 evaluation_type = 1;
+ // See definition in data_stall_event.proto.
+ optional com.android.server.connectivity.ProbeResult validation_result = 2;
+ // See definition in data_stall_event.proto.
+ optional android.net.NetworkCapabilitiesProto.Transport network_type = 3;
+ // See definition in data_stall_event.proto.
+ optional com.android.server.connectivity.WifiData wifi_info = 4 [(log_mode) = MODE_BYTES];
+ // See definition in data_stall_event.proto.
+ optional com.android.server.connectivity.CellularData cell_info = 5 [(log_mode) = MODE_BYTES];
+ // See definition in data_stall_event.proto.
+ optional com.android.server.connectivity.DnsEvent dns_event = 6 [(log_mode) = MODE_BYTES];
+}
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 6025766..7b1c26a 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -1499,7 +1499,6 @@
Landroid/service/dreams/IDreamManager;->isDreaming()Z
Landroid/service/dreams/IDreamManager;->setDreamComponents([Landroid/content/ComponentName;)V
Landroid/service/euicc/IDeleteSubscriptionCallback;->onComplete(I)V
-Landroid/service/euicc/IDownloadSubscriptionCallback;->onComplete(I)V
Landroid/service/euicc/IEraseSubscriptionsCallback;->onComplete(I)V
Landroid/service/euicc/IEuiccService$Stub;-><init>()V
Landroid/service/euicc/IGetDefaultDownloadableSubscriptionListCallback;->onComplete(Landroid/service/euicc/GetDefaultDownloadableSubscriptionListResult;)V
@@ -1569,7 +1568,6 @@
Landroid/test/AndroidTestCase;->getTestContext()Landroid/content/Context;
Landroid/test/AndroidTestCase;->setTestContext(Landroid/content/Context;)V
Landroid/test/InstrumentationTestCase;->runMethod(Ljava/lang/reflect/Method;I)V
-Landroid/test/RepetitiveTest;->numIterations()I
Landroid/util/Singleton;-><init>()V
Landroid/util/XmlPullAttributes;-><init>(Lorg/xmlpull/v1/XmlPullParser;)V
Landroid/util/XmlPullAttributes;->mParser:Lorg/xmlpull/v1/XmlPullParser;
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 4a466f3..c2963fd 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -66,6 +66,7 @@
private int mMtu;
// in the format "rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max"
private String mTcpBufferSizes;
+ private IpPrefix mNat64Prefix;
private static final int MIN_MTU = 68;
private static final int MIN_MTU_V6 = 1280;
@@ -190,6 +191,7 @@
}
setMtu(source.mMtu);
mTcpBufferSizes = source.mTcpBufferSizes;
+ mNat64Prefix = source.mNat64Prefix;
}
}
@@ -760,6 +762,32 @@
}
/**
+ * Returns the NAT64 prefix in use on this link, if any.
+ *
+ * @return the NAT64 prefix.
+ * @hide
+ */
+ public @Nullable IpPrefix getNat64Prefix() {
+ return mNat64Prefix;
+ }
+
+ /**
+ * Sets the NAT64 prefix in use on this link.
+ *
+ * Currently, only 96-bit prefixes (i.e., where the 32-bit IPv4 address is at the end of the
+ * 128-bit IPv6 address) are supported.
+ *
+ * @param prefix the NAT64 prefix.
+ * @hide
+ */
+ public void setNat64Prefix(IpPrefix prefix) {
+ if (prefix != null && prefix.getPrefixLength() != 96) {
+ throw new IllegalArgumentException("Only 96-bit prefixes are supported: " + prefix);
+ }
+ mNat64Prefix = prefix; // IpPrefix objects are immutable.
+ }
+
+ /**
* Adds a stacked link.
*
* If there is already a stacked link with the same interface name as link,
@@ -831,6 +859,7 @@
mStackedLinks.clear();
mMtu = 0;
mTcpBufferSizes = null;
+ mNat64Prefix = null;
}
/**
@@ -908,6 +937,11 @@
resultJoiner.add(mHttpProxy.toString());
}
+ if (mNat64Prefix != null) {
+ resultJoiner.add("Nat64Prefix:");
+ resultJoiner.add(mNat64Prefix.toString());
+ }
+
final Collection<LinkProperties> stackedLinksValues = mStackedLinks.values();
if (!stackedLinksValues.isEmpty()) {
final StringJoiner stackedLinksJoiner = new StringJoiner(",", "Stacked: [", "]");
@@ -1295,6 +1329,17 @@
}
/**
+ * Compares this {@code LinkProperties} NAT64 prefix against the target.
+ *
+ * @param target LinkProperties to compare.
+ * @return {@code true} if both are identical, {@code false} otherwise.
+ * @hide
+ */
+ public boolean isIdenticalNat64Prefix(LinkProperties target) {
+ return Objects.equals(mNat64Prefix, target.mNat64Prefix);
+ }
+
+ /**
* Compares this {@code LinkProperties} instance against the target
* LinkProperties in {@code obj}. Two LinkPropertieses are equal if
* all their fields are equal in values.
@@ -1330,7 +1375,8 @@
&& isIdenticalHttpProxy(target)
&& isIdenticalStackedLinks(target)
&& isIdenticalMtu(target)
- && isIdenticalTcpBufferSizes(target);
+ && isIdenticalTcpBufferSizes(target)
+ && isIdenticalNat64Prefix(target);
}
/**
@@ -1443,7 +1489,8 @@
+ ((null == mTcpBufferSizes) ? 0 : mTcpBufferSizes.hashCode())
+ (mUsePrivateDns ? 57 : 0)
+ mPcscfs.size() * 67
- + ((null == mPrivateDnsServerName) ? 0 : mPrivateDnsServerName.hashCode());
+ + ((null == mPrivateDnsServerName) ? 0 : mPrivateDnsServerName.hashCode())
+ + Objects.hash(mNat64Prefix);
}
/**
@@ -1484,6 +1531,8 @@
} else {
dest.writeByte((byte)0);
}
+ dest.writeParcelable(mNat64Prefix, 0);
+
ArrayList<LinkProperties> stackedLinks = new ArrayList<>(mStackedLinks.values());
dest.writeList(stackedLinks);
}
@@ -1535,6 +1584,7 @@
if (in.readByte() == 1) {
netProp.setHttpProxy(in.readParcelable(null));
}
+ netProp.setNat64Prefix(in.readParcelable(null));
ArrayList<LinkProperties> stackedLinks = new ArrayList<LinkProperties>();
in.readList(stackedLinks, LinkProperties.class.getClassLoader());
for (LinkProperties stackedLink: stackedLinks) {
diff --git a/core/java/android/net/ipmemorystore/NetworkAttributes.java b/core/java/android/net/ipmemorystore/NetworkAttributes.java
index d7e5b27..b932d21 100644
--- a/core/java/android/net/ipmemorystore/NetworkAttributes.java
+++ b/core/java/android/net/ipmemorystore/NetworkAttributes.java
@@ -28,6 +28,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.StringJoiner;
/**
* A POD object to represent attributes of a single L2 network entry.
@@ -207,4 +208,52 @@
public int hashCode() {
return Objects.hash(assignedV4Address, groupHint, dnsAddresses, mtu);
}
+
+ /** Pretty print */
+ @Override
+ public String toString() {
+ final StringJoiner resultJoiner = new StringJoiner(" ", "{", "}");
+ final ArrayList<String> nullFields = new ArrayList<>();
+
+ if (null != assignedV4Address) {
+ resultJoiner.add("assignedV4Addr :");
+ resultJoiner.add(assignedV4Address.toString());
+ } else {
+ nullFields.add("assignedV4Addr");
+ }
+
+ if (null != groupHint) {
+ resultJoiner.add("groupHint :");
+ resultJoiner.add(groupHint);
+ } else {
+ nullFields.add("groupHint");
+ }
+
+ if (null != dnsAddresses) {
+ resultJoiner.add("dnsAddr : [");
+ for (final InetAddress addr : dnsAddresses) {
+ resultJoiner.add(addr.getHostAddress());
+ }
+ resultJoiner.add("]");
+ } else {
+ nullFields.add("dnsAddr");
+ }
+
+ if (null != mtu) {
+ resultJoiner.add("mtu :");
+ resultJoiner.add(mtu.toString());
+ } else {
+ nullFields.add("mtu");
+ }
+
+ if (!nullFields.isEmpty()) {
+ resultJoiner.add("; Null fields : [");
+ for (final String field : nullFields) {
+ resultJoiner.add(field);
+ }
+ resultJoiner.add("]");
+ }
+
+ return resultJoiner.toString();
+ }
}
diff --git a/core/java/android/net/ipmemorystore/SameL3NetworkResponse.java b/core/java/android/net/ipmemorystore/SameL3NetworkResponse.java
index 0cb37e9..d040dcc 100644
--- a/core/java/android/net/ipmemorystore/SameL3NetworkResponse.java
+++ b/core/java/android/net/ipmemorystore/SameL3NetworkResponse.java
@@ -128,4 +128,19 @@
public int hashCode() {
return Objects.hash(l2Key1, l2Key2, confidence);
}
+
+ @Override
+ /** Pretty print */
+ public String toString() {
+ switch (getNetworkSameness()) {
+ case NETWORK_SAME:
+ return "\"" + l2Key1 + "\" same L3 network as \"" + l2Key2 + "\"";
+ case NETWORK_DIFFERENT:
+ return "\"" + l2Key1 + "\" different L3 network from \"" + l2Key2 + "\"";
+ case NETWORK_NEVER_CONNECTED:
+ return "\"" + l2Key1 + "\" can't be tested against \"" + l2Key2 + "\"";
+ default:
+ return "Buggy sameness value ? \"" + l2Key1 + "\", \"" + l2Key2 + "\"";
+ }
+ }
}
diff --git a/core/java/android/net/ipmemorystore/Status.java b/core/java/android/net/ipmemorystore/Status.java
index 5b016ec..95e5042 100644
--- a/core/java/android/net/ipmemorystore/Status.java
+++ b/core/java/android/net/ipmemorystore/Status.java
@@ -26,6 +26,8 @@
public class Status {
public static final int SUCCESS = 0;
+ public static final int ERROR_DATABASE_CANNOT_BE_OPENED = -1;
+
public final int resultCode;
public Status(final int resultCode) {
@@ -47,4 +49,14 @@
public boolean isSuccess() {
return SUCCESS == resultCode;
}
+
+ /** Pretty print */
+ @Override
+ public String toString() {
+ switch (resultCode) {
+ case SUCCESS: return "SUCCESS";
+ case ERROR_DATABASE_CANNOT_BE_OPENED: return "DATABASE CANNOT BE OPENED";
+ default: return "Unknown value ?!";
+ }
+ }
}
diff --git a/core/java/android/net/ipmemorystore/Utils.java b/core/java/android/net/ipmemorystore/Utils.java
new file mode 100644
index 0000000..73d8c83
--- /dev/null
+++ b/core/java/android/net/ipmemorystore/Utils.java
@@ -0,0 +1,44 @@
+/*
+ * 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 android.net.ipmemorystore;
+
+import android.annotation.NonNull;
+
+/** {@hide} */
+public class Utils {
+ /** Pretty print */
+ public static String blobToString(final Blob blob) {
+ final StringBuilder sb = new StringBuilder("Blob : [");
+ if (blob.data.length <= 24) {
+ appendByteArray(sb, blob.data, 0, blob.data.length);
+ } else {
+ appendByteArray(sb, blob.data, 0, 16);
+ sb.append("...");
+ appendByteArray(sb, blob.data, blob.data.length - 8, blob.data.length);
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
+ // Adds the hex representation of the array between the specified indices (inclusive, exclusive)
+ private static void appendByteArray(@NonNull final StringBuilder sb, @NonNull final byte[] ar,
+ final int from, final int to) {
+ for (int i = from; i < to; ++i) {
+ sb.append(String.format("%02X", ar[i]));
+ }
+ }
+}
diff --git a/core/java/android/os/BugreportManager.java b/core/java/android/os/BugreportManager.java
index 1343d24..cbb3909 100644
--- a/core/java/android/os/BugreportManager.java
+++ b/core/java/android/os/BugreportManager.java
@@ -114,8 +114,6 @@
}
}
-
- // TODO(b/111441001) Connect up with BugreportListener methods.
private final class DumpstateListener extends IDumpstateListener.Stub
implements DeathRecipient {
private final BugreportListener mListener;
@@ -130,19 +128,36 @@
}
@Override
+ public void onProgress(int progress) throws RemoteException {
+ mListener.onProgress(progress);
+ }
+
+ @Override
+ public void onError(int errorCode) throws RemoteException {
+ mListener.onError(errorCode);
+ }
+
+ @Override
+ public void onFinished(long durationMs, String title, String description)
+ throws RemoteException {
+ mListener.onFinished(durationMs, title, description);
+ }
+
+ // Old methods; should go away
+ @Override
public void onProgressUpdated(int progress) throws RemoteException {
- // TODO(b/111441001): implement
+ // TODO(b/111441001): remove from interface
}
@Override
public void onMaxProgressUpdated(int maxProgress) throws RemoteException {
- // TODO(b/111441001): implement
+ // TODO(b/111441001): remove from interface
}
@Override
public void onSectionComplete(String title, int status, int size, int durationMs)
throws RemoteException {
- // TODO(b/111441001): implement
+ // TODO(b/111441001): remove from interface
}
}
}
diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java
index 3de3494..9e3e83e 100644
--- a/core/java/android/os/HwBinder.java
+++ b/core/java/android/os/HwBinder.java
@@ -17,6 +17,7 @@
package android.os;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import libcore.util.NativeAllocationRegistry;
@@ -24,6 +25,7 @@
/** @hide */
@SystemApi
+@TestApi
public abstract class HwBinder implements IHwBinder {
private static final String TAG = "HwBinder";
diff --git a/core/java/android/os/HwBlob.java b/core/java/android/os/HwBlob.java
index 6a5bb1c..0ec63b5 100644
--- a/core/java/android/os/HwBlob.java
+++ b/core/java/android/os/HwBlob.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import libcore.util.NativeAllocationRegistry;
@@ -28,6 +29,7 @@
* @hide
*/
@SystemApi
+@TestApi
public class HwBlob {
private static final String TAG = "HwBlob";
diff --git a/core/java/android/os/HwParcel.java b/core/java/android/os/HwParcel.java
index 7a51db2..7919a00 100644
--- a/core/java/android/os/HwParcel.java
+++ b/core/java/android/os/HwParcel.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import libcore.util.NativeAllocationRegistry;
@@ -28,6 +29,7 @@
/** @hide */
@SystemApi
+@TestApi
public class HwParcel {
private static final String TAG = "HwParcel";
diff --git a/core/java/android/os/IHwBinder.java b/core/java/android/os/IHwBinder.java
index 249eb3a..46fa6ef 100644
--- a/core/java/android/os/IHwBinder.java
+++ b/core/java/android/os/IHwBinder.java
@@ -17,9 +17,11 @@
package android.os;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
/** @hide */
@SystemApi
+@TestApi
public interface IHwBinder {
/**
* Process a hwbinder transaction.
diff --git a/core/java/android/os/IHwInterface.java b/core/java/android/os/IHwInterface.java
index f9edd5b..0a5a715 100644
--- a/core/java/android/os/IHwInterface.java
+++ b/core/java/android/os/IHwInterface.java
@@ -17,8 +17,11 @@
package android.os;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
+
/** @hide */
@SystemApi
+@TestApi
public interface IHwInterface {
/**
* @return the binder object that corresponds to this interface.
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index fdd7488..8ced722 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -356,16 +356,6 @@
void removeVpnUidRanges(int netId, in UidRange[] ranges);
/**
- * Start the clatd (464xlat) service on the given interface.
- */
- void startClatd(String interfaceName);
-
- /**
- * Stop the clatd (464xlat) service on the given interface.
- */
- void stopClatd(String interfaceName);
-
- /**
* Start listening for mobile activity state changes.
*/
void registerNetworkActivityListener(INetworkActivityListener listener);
diff --git a/core/java/android/os/NativeHandle.java b/core/java/android/os/NativeHandle.java
index f7ffc37..f13bf5f 100644
--- a/core/java/android/os/NativeHandle.java
+++ b/core/java/android/os/NativeHandle.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.system.ErrnoException;
import android.system.Os;
@@ -32,6 +33,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class NativeHandle implements Closeable {
// whether this object owns mFds
private boolean mOwn = false;
diff --git a/core/java/android/os/ParcelableException.aidl b/core/java/android/os/ParcelableException.aidl
new file mode 100644
index 0000000..d214922
--- /dev/null
+++ b/core/java/android/os/ParcelableException.aidl
@@ -0,0 +1,18 @@
+/* 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.os;
+
+parcelable ParcelableException;
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 3d93afd..de54a8aa 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -28,12 +28,14 @@
import android.location.Country;
import android.location.CountryDetector;
import android.net.Uri;
+import android.os.Build;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.ContactsContract.CommonDataKinds.Callable;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.DataUsageFeedback;
+import android.telecom.CallIdentification;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
@@ -603,6 +605,69 @@
public static final String BLOCK_REASON = "block_reason";
/**
+ * The package name of the {@link android.telecom.CallScreeningService} which provided
+ * {@link android.telecom.CallIdentification} for this call.
+ * <P>Type: TEXT</P>
+ */
+ public static final String CALL_ID_PACKAGE_NAME = "call_id_package_name";
+
+ /**
+ * The app name of the {@link android.telecom.CallScreeningService} which provided
+ * {@link android.telecom.CallIdentification} for this call.
+ * <P>Type: TEXT</P>
+ */
+ public static final String CALL_ID_APP_NAME = "call_id_app_name";
+
+ /**
+ * The {@link CallIdentification#getName() name} of a call, as provided by the
+ * {@link android.telecom.CallScreeningService}.
+ * <p>
+ * The name is provided by the app identified by {@link #CALL_ID_PACKAGE_NAME} and
+ * {@link #CALL_ID_APP_NAME}.
+ * <P>Type: TEXT</P>
+ */
+ public static final String CALL_ID_NAME = "call_id_name";
+
+ /**
+ * The {@link CallIdentification#getDescription() description} of a call, as provided by the
+ * {@link android.telecom.CallScreeningService}.
+ * <p>
+ * The description is provided by the app identified by {@link #CALL_ID_PACKAGE_NAME} and
+ * {@link #CALL_ID_APP_NAME}.
+ * <P>Type: TEXT</P>
+ */
+ public static final String CALL_ID_DESCRIPTION = "call_id_description";
+
+ /**
+ * The {@link CallIdentification#getDetails() details} of a call, as provided by the
+ * {@link android.telecom.CallScreeningService}.
+ * <p>
+ * The details field is provided by the app identified by {@link #CALL_ID_PACKAGE_NAME} and
+ * {@link #CALL_ID_APP_NAME}.
+ * <P>Type: TEXT</P>
+ */
+ public static final String CALL_ID_DETAILS = "call_id_details";
+
+ /**
+ * The {@link CallIdentification#getNuisanceConfidence() nuisance confidence} of a call, as
+ * provided by the {@link android.telecom.CallScreeningService}.
+ * <p>
+ * Valid values are defined in {@link CallIdentification}, and include:
+ * <ul>
+ * <li>{@link CallIdentification#CONFIDENCE_NOT_NUISANCE}</li>
+ * <li>{@link CallIdentification#CONFIDENCE_LIKELY_NOT_NUISANCE}</li>
+ * <li>{@link CallIdentification#CONFIDENCE_UNKNOWN}</li>
+ * <li>{@link CallIdentification#CONFIDENCE_LIKELY_NUISANCE}</li>
+ * <li>{@link CallIdentification#CONFIDENCE_NUISANCE}</li>
+ * </ul>
+ * <p>
+ * The nuisance confidence is provided by the app identified by
+ * {@link #CALL_ID_PACKAGE_NAME} and {@link #CALL_ID_APP_NAME}.
+ * <P>Type: INTEGER</P>
+ */
+ public static final String CALL_ID_NUISANCE_CONFIDENCE = "call_id_nuisance_confidence";
+
+ /**
* Adds a call to the call log.
*
* @param ci the CallerInfo object to get the target contact from. Can be null
@@ -631,7 +696,8 @@
presentation, callType, features, accountHandle, start, duration,
dataUsage, false /* addForAllUsers */, null /* userToBeInsertedTo */,
false /* isRead */, Calls.BLOCK_REASON_NOT_BLOCKED /* callBlockReason */,
- null /* callScreeningAppName */, null /* callScreeningComponentName */);
+ null /* callScreeningAppName */, null /* callScreeningComponentName */,
+ null /* callIdentification */);
}
@@ -671,7 +737,8 @@
features, accountHandle, start, duration, dataUsage, addForAllUsers,
userToBeInsertedTo, false /* isRead */ , Calls.BLOCK_REASON_NOT_BLOCKED
/* callBlockReason */, null /* callScreeningAppName */,
- null /* callScreeningComponentName */);
+ null /* callScreeningComponentName */,
+ null /* callIdentification */);
}
/**
@@ -705,19 +772,32 @@
* @param callBlockReason The reason why the call is blocked.
* @param callScreeningAppName The call screening application name which block the call.
* @param callScreeningComponentName The call screening component name which block the call.
+ * @param callIdPackageName The package name of the
+ * {@link android.telecom.CallScreeningService} which provided
+ * {@link CallIdentification}.
+ * @param callIdAppName The app name of the {@link android.telecom.CallScreeningService}
+ * which provided {@link CallIdentification}.
+ * @param callIdName The caller name provided by the
+ * {@link android.telecom.CallScreeningService}.
+ * @param callIdDescription The caller description provided by the
+ * {@link android.telecom.CallScreeningService}.
+ * @param callIdDetails The caller details provided by the
+ * {@link android.telecom.CallScreeningService}.
+ * @param callIdCallType The caller type provided by the
+ * {@link android.telecom.CallScreeningService}.
*
* @result The URI of the call log entry belonging to the user that made or received this
* call. This could be of the shadow provider. Do not return it to non-system apps,
* as they don't have permissions.
* {@hide}
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public static Uri addCall(CallerInfo ci, Context context, String number,
String postDialDigits, String viaNumber, int presentation, int callType,
int features, PhoneAccountHandle accountHandle, long start, int duration,
Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo,
boolean isRead, int callBlockReason, String callScreeningAppName,
- String callScreeningComponentName) {
+ String callScreeningComponentName, CallIdentification callIdentification) {
if (VERBOSE_LOG) {
Log.v(LOG_TAG, String.format("Add call: number=%s, user=%s, for all=%s",
number, userToBeInsertedTo, addForAllUsers));
@@ -799,6 +879,22 @@
values.put(CALL_SCREENING_APP_NAME, callScreeningAppName);
values.put(CALL_SCREENING_COMPONENT_NAME, callScreeningComponentName);
+ if (callIdentification != null) {
+ values.put(CALL_ID_PACKAGE_NAME, callIdentification.getCallScreeningPackageName());
+ values.put(CALL_ID_APP_NAME, callIdentification.getCallScreeningAppName());
+ values.put(CALL_ID_NAME, callIdentification.getName());
+ values.put(CALL_ID_DESCRIPTION, callIdentification.getDescription());
+ values.put(CALL_ID_DETAILS, callIdentification.getDetails());
+ values.put(CALL_ID_NUISANCE_CONFIDENCE, callIdentification.getNuisanceConfidence());
+ } else {
+ values.putNull(CALL_ID_PACKAGE_NAME);
+ values.putNull(CALL_ID_APP_NAME);
+ values.putNull(CALL_ID_NAME);
+ values.putNull(CALL_ID_DESCRIPTION);
+ values.putNull(CALL_ID_DETAILS);
+ values.putNull(CALL_ID_NUISANCE_CONFIDENCE);
+ }
+
if ((ci != null) && (ci.contactIdOrZero > 0)) {
// Update usage information for the number associated with the contact ID.
// We need to use both the number and the ID for obtaining a data ID since other
diff --git a/core/java/android/service/euicc/DownloadSubscriptionResult.aidl b/core/java/android/service/euicc/DownloadSubscriptionResult.aidl
new file mode 100644
index 0000000..b625fd6
--- /dev/null
+++ b/core/java/android/service/euicc/DownloadSubscriptionResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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 android.service.euicc;
+
+parcelable DownloadSubscriptionResult;
diff --git a/core/java/android/service/euicc/DownloadSubscriptionResult.java b/core/java/android/service/euicc/DownloadSubscriptionResult.java
new file mode 100644
index 0000000..b410e35
--- /dev/null
+++ b/core/java/android/service/euicc/DownloadSubscriptionResult.java
@@ -0,0 +1,99 @@
+/*
+ * 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 android.service.euicc;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.service.euicc.EuiccService.ResolvableError;
+import android.service.euicc.EuiccService.Result;
+
+/**
+ * Result of a {@link EuiccService#onDownloadSubscription} operation.
+ * @hide
+ */
+@SystemApi
+public final class DownloadSubscriptionResult implements Parcelable {
+
+ public static final Creator<DownloadSubscriptionResult> CREATOR =
+ new Creator<DownloadSubscriptionResult>() {
+ @Override
+ public DownloadSubscriptionResult createFromParcel(Parcel in) {
+ return new DownloadSubscriptionResult(in);
+ }
+
+ @Override
+ public DownloadSubscriptionResult[] newArray(int size) {
+ return new DownloadSubscriptionResult[size];
+ }
+ };
+
+ private final @Result int mResult;
+ private final @ResolvableError int mResolvableErrors;
+ private final int mCardId;
+
+ public DownloadSubscriptionResult(@Result int result, @ResolvableError int resolvableErrors,
+ int cardId) {
+ this.mResult = result;
+ this.mResolvableErrors = resolvableErrors;
+ this.mCardId = cardId;
+ }
+
+ /** Gets the result of the operation. */
+ public @Result int getResult() {
+ return mResult;
+ }
+
+ /**
+ * Gets the bit map of resolvable errors.
+ *
+ * <p>The value is passed from EuiccService. The values can be
+ *
+ * <ul>
+ * <li>{@link EuiccService#RESOLVABLE_ERROR_CONFIRMATION_CODE}
+ * <li>{@link EuiccService#RESOLVABLE_ERROR_POLICY_RULES}
+ * </ul>
+ */
+ public @ResolvableError int getResolvableErrors() {
+ return mResolvableErrors;
+ }
+
+ /**
+ * Gets the card Id. This is used when resolving resolvable errors. The value is passed from
+ * EuiccService.
+ */
+ public int getCardId() {
+ return mCardId;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mResult);
+ dest.writeInt(mResolvableErrors);
+ dest.writeInt(mCardId);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ private DownloadSubscriptionResult(Parcel in) {
+ this.mResult = in.readInt();
+ this.mResolvableErrors = in.readInt();
+ this.mCardId = in.readInt();
+ }
+}
diff --git a/core/java/android/service/euicc/EuiccService.java b/core/java/android/service/euicc/EuiccService.java
index b87faef..b84e556 100644
--- a/core/java/android/service/euicc/EuiccService.java
+++ b/core/java/android/service/euicc/EuiccService.java
@@ -16,17 +16,24 @@
package android.service.euicc;
import android.annotation.CallSuper;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
+import android.telephony.TelephonyManager;
import android.telephony.euicc.DownloadableSubscription;
import android.telephony.euicc.EuiccInfo;
import android.telephony.euicc.EuiccManager.OtaStatus;
import android.util.ArraySet;
+import android.util.Log;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
@@ -73,6 +80,8 @@
*/
@SystemApi
public abstract class EuiccService extends Service {
+ private static final String TAG = "EuiccService";
+
/** Action which must be included in this service's intent filter. */
public static final String EUICC_SERVICE_INTERFACE = "android.service.euicc.EuiccService";
@@ -108,30 +117,91 @@
public static final String ACTION_RESOLVE_NO_PRIVILEGES =
"android.service.euicc.action.RESOLVE_NO_PRIVILEGES";
- /** Ask the user to input carrier confirmation code. */
+ /**
+ * Ask the user to input carrier confirmation code.
+ *
+ * @deprecated From Q, the resolvable errors happened in the download step are presented as
+ * bit map in {@link #EXTRA_RESOLVABLE_ERRORS}. The corresponding action would be
+ * {@link #ACTION_RESOLVE_RESOLVABLE_ERRORS}.
+ */
+ @Deprecated
public static final String ACTION_RESOLVE_CONFIRMATION_CODE =
"android.service.euicc.action.RESOLVE_CONFIRMATION_CODE";
+ /** Ask the user to resolve all the resolvable errors. */
+ public static final String ACTION_RESOLVE_RESOLVABLE_ERRORS =
+ "android.service.euicc.action.RESOLVE_RESOLVABLE_ERRORS";
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, prefix = { "RESOLVABLE_ERROR_" }, value = {
+ RESOLVABLE_ERROR_CONFIRMATION_CODE,
+ RESOLVABLE_ERROR_POLICY_RULES,
+ })
+ public @interface ResolvableError {}
+
+ /**
+ * Possible value for the bit map of resolvable errors indicating the download process needs
+ * the user to input confirmation code.
+ */
+ public static final int RESOLVABLE_ERROR_CONFIRMATION_CODE = 1 << 0;
+ /**
+ * Possible value for the bit map of resolvable errors indicating the download process needs
+ * the user's consent to allow profile policy rules.
+ */
+ public static final int RESOLVABLE_ERROR_POLICY_RULES = 1 << 1;
+
/**
* 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.
+ * ACTION_RESOLVE_NO_PRIVILEGES and ACTION_RESOLVE_RESOLVABLE_ERRORS.
*/
public static final String EXTRA_RESOLUTION_CALLING_PACKAGE =
"android.service.euicc.extra.RESOLUTION_CALLING_PACKAGE";
/**
+ * Intent extra set for resolution requests containing the list of resolvable errors to be
+ * resolved. Each resolvable error is an integer. Its possible values include:
+ * <UL>
+ * <LI>{@link #RESOLVABLE_ERROR_CONFIRMATION_CODE}
+ * <LI>{@link #RESOLVABLE_ERROR_POLICY_RULES}
+ * </UL>
+ */
+ public static final String EXTRA_RESOLVABLE_ERRORS =
+ "android.service.euicc.extra.RESOLVABLE_ERRORS";
+
+ /**
* Intent extra set for resolution requests containing a boolean indicating whether to ask the
* user to retry another confirmation code.
*/
public static final String EXTRA_RESOLUTION_CONFIRMATION_CODE_RETRIED =
"android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE_RETRIED";
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "RESULT_" }, value = {
+ RESULT_OK,
+ RESULT_MUST_DEACTIVATE_SIM,
+ RESULT_RESOLVABLE_ERRORS,
+ RESULT_NEED_CONFIRMATION_CODE,
+ RESULT_FIRST_USER,
+ })
+ public @interface Result {}
+
/** Result code for a successful operation. */
public static final int RESULT_OK = 0;
/** Result code indicating that an active SIM must be deactivated to perform the operation. */
public static final int RESULT_MUST_DEACTIVATE_SIM = -1;
- /** Result code indicating that the user must input a carrier confirmation code. */
+ /** Result code indicating that the user must resolve resolvable errors. */
+ public static final int RESULT_RESOLVABLE_ERRORS = -2;
+ /**
+ * Result code indicating that the user must input a carrier confirmation code.
+ *
+ * @deprecated From Q, the resolvable errors happened in the download step are presented as
+ * bit map in {@link #EXTRA_RESOLVABLE_ERRORS}. The corresponding result would be
+ * {@link #RESULT_RESOLVABLE_ERRORS}.
+ */
+ @Deprecated
public static final int RESULT_NEED_CONFIRMATION_CODE = -2;
// New predefined codes should have negative values.
@@ -147,7 +217,7 @@
RESOLUTION_ACTIONS = new ArraySet<>();
RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM);
RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES);
- RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_CONFIRMATION_CODE);
+ RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_RESOLVABLE_ERRORS);
}
/**
@@ -162,6 +232,12 @@
*/
public static final String EXTRA_RESOLUTION_CONFIRMATION_CODE =
"android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE";
+ /**
+ * String extra for resolution actions indicating whether the user allows policy rules.
+ * This is used and set by the implementation and used in {@code EuiccOperation}.
+ */
+ public static final String EXTRA_RESOLUTION_ALLOW_POLICY_RULES =
+ "android.service.euicc.extra.RESOLUTION_ALLOW_POLICY_RULES";
private final IEuiccService.Stub mStubWrapper;
@@ -229,8 +305,7 @@
/**
* Return the EID of the eUICC.
*
- * @param slotId ID of the SIM slot being queried. This is currently not populated but is here
- * to future-proof the APIs.
+ * @param slotId ID of the SIM slot being queried.
* @return the EID.
* @see android.telephony.euicc.EuiccManager#getEid
*/
@@ -240,8 +315,7 @@
/**
* Return the status of OTA update.
*
- * @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 status of Euicc OTA update.
* @see android.telephony.euicc.EuiccManager#getOtaStatus
*/
@@ -250,8 +324,7 @@
/**
* Perform OTA if current OS is not the latest one.
*
- * @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 statusChangedCallback Function called when OTA status changed.
*/
public abstract void onStartOtaIfNecessary(
@@ -274,8 +347,7 @@
/**
* Return metadata for subscriptions which are available for download for this 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.
* @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)}
* should be returned to allow the user to consent to this operation first.
@@ -295,13 +367,44 @@
* @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}
* should be returned to allow the user to consent to this operation first.
+ * @param resolvedBundle The bundle containing information on resolved errors. It can contain
+ * a string of confirmation code for the key {@link #EXTRA_RESOLUTION_CONFIRMATION_CODE},
+ * and a boolean for key {@link #EXTRA_RESOLUTION_ALLOW_POLICY_RULES} indicating whether
+ * the user allows profile policy rules or not.
+ * @return a DownloadSubscriptionResult instance including a result code, a resolvable errors
+ * bit map, and original the card Id. The result code may be one of the predefined
+ * {@code RESULT_} constants or any implementation-specific code starting with
+ * {@link #RESULT_FIRST_USER}. The resolvable error bit map can be either 0 or values
+ * defined in {@code RESOLVABLE_ERROR_}.
+ * @see android.telephony.euicc.EuiccManager#downloadSubscription
+ */
+ public abstract DownloadSubscriptionResult onDownloadSubscription(int slotId,
+ @NonNull DownloadableSubscription subscription, boolean switchAfterDownload,
+ boolean forceDeactivateSim, @Nullable Bundle resolvedBundle);
+
+ /**
+ * Download the given subscription.
+ *
+ * @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.
+ * @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}
+ * should be returned to allow the user to consent to this operation first.
* @return the result of the download operation. May be one of the predefined {@code RESULT_}
* constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
* @see android.telephony.euicc.EuiccManager#downloadSubscription
+ *
+ * @deprecated From Q, please use the above
+ * {@link #onDownloadSubscription(int, DownloadableSubscription, boolean, boolean, Bundle)}.
*/
- public abstract int onDownloadSubscription(int slotId,
- DownloadableSubscription subscription, boolean switchAfterDownload,
- boolean forceDeactivateSim);
+ @Deprecated public @Result int onDownloadSubscription(int slotId,
+ @NonNull DownloadableSubscription subscription, boolean switchAfterDownload,
+ boolean forceDeactivateSim) {
+ throw new UnsupportedOperationException("onDownloadSubscription(int, "
+ + "DownloadableSubscription, boolean, boolean) is deprecated.");
+ }
/**
* Return a list of all @link EuiccProfileInfo}s.
@@ -311,7 +414,7 @@
* @see android.telephony.SubscriptionManager#getAvailableSubscriptionInfoList
* @see android.telephony.SubscriptionManager#getAccessibleSubscriptionInfoList
*/
- public abstract GetEuiccProfileInfoListResult onGetEuiccProfileInfoList(int slotId);
+ public abstract @NonNull GetEuiccProfileInfoListResult onGetEuiccProfileInfoList(int slotId);
/**
* Return info about the eUICC chip/device.
@@ -320,7 +423,7 @@
* @return the {@link EuiccInfo} for the eUICC chip/device.
* @see android.telephony.euicc.EuiccManager#getEuiccInfo
*/
- public abstract EuiccInfo onGetEuiccInfo(int slotId);
+ public abstract @NonNull EuiccInfo onGetEuiccInfo(int slotId);
/**
* Delete the given subscription.
@@ -334,7 +437,7 @@
* constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
* @see android.telephony.euicc.EuiccManager#deleteSubscription
*/
- public abstract int onDeleteSubscription(int slotId, String iccid);
+ public abstract @Result int onDeleteSubscription(int slotId, String iccid);
/**
* Switch to the given subscription.
@@ -350,7 +453,7 @@
* constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
* @see android.telephony.euicc.EuiccManager#switchToSubscription
*/
- public abstract int onSwitchToSubscription(int slotId, @Nullable String iccid,
+ public abstract @Result int onSwitchToSubscription(int slotId, @Nullable String iccid,
boolean forceDeactivateSim);
/**
@@ -372,8 +475,7 @@
* <p>This is intended to be used for device resets. As such, the reset should be performed even
* if an active SIM must be deactivated in order to access the eUICC.
*
- * @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 erase operation. May be one of the predefined {@code RESULT_}
* constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
* @see android.telephony.euicc.EuiccManager#eraseSubscriptions
@@ -388,8 +490,7 @@
* should persist some bit that will remain accessible after the factory reset to bypass this
* flow when this method is called.
*
- * @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. May be one of the predefined {@code RESULT_} constants
* or any implementation-specific code starting with {@link #RESULT_FIRST_USER}.
*/
@@ -401,13 +502,26 @@
private class IEuiccServiceWrapper extends IEuiccService.Stub {
@Override
public void downloadSubscription(int slotId, DownloadableSubscription subscription,
- boolean switchAfterDownload, boolean forceDeactivateSim,
+ boolean switchAfterDownload, boolean forceDeactivateSim, Bundle resolvedBundle,
IDownloadSubscriptionCallback callback) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
- int result = EuiccService.this.onDownloadSubscription(
- slotId, subscription, switchAfterDownload, forceDeactivateSim);
+ DownloadSubscriptionResult result;
+ try {
+ result =
+ EuiccService.this.onDownloadSubscription(
+ slotId, subscription, switchAfterDownload, forceDeactivateSim,
+ resolvedBundle);
+ } catch (AbstractMethodError e) {
+ Log.w(TAG, "The new onDownloadSubscription(int, "
+ + "DownloadableSubscription, boolean, boolean, Bundle) is not "
+ + "implemented. Fall back to the old one.", e);
+ int resultCode = EuiccService.this.onDownloadSubscription(
+ slotId, subscription, switchAfterDownload, forceDeactivateSim);
+ result = new DownloadSubscriptionResult(resultCode,
+ 0 /* resolvableErrors */, TelephonyManager.INVALID_CARD_ID);
+ }
try {
callback.onComplete(result);
} catch (RemoteException e) {
diff --git a/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl b/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl
index 6893c85..50ecbeb 100644
--- a/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl
+++ b/core/java/android/service/euicc/IDownloadSubscriptionCallback.aidl
@@ -16,7 +16,9 @@
package android.service.euicc;
+import android.service.euicc.DownloadSubscriptionResult;
+
/** @hide */
oneway interface IDownloadSubscriptionCallback {
- void onComplete(int result);
+ void onComplete(in DownloadSubscriptionResult result);
}
\ No newline at end of file
diff --git a/core/java/android/service/euicc/IEuiccService.aidl b/core/java/android/service/euicc/IEuiccService.aidl
index 45be527..c2cdf09 100644
--- a/core/java/android/service/euicc/IEuiccService.aidl
+++ b/core/java/android/service/euicc/IEuiccService.aidl
@@ -30,11 +30,12 @@
import android.service.euicc.ISwitchToSubscriptionCallback;
import android.service.euicc.IUpdateSubscriptionNicknameCallback;
import android.telephony.euicc.DownloadableSubscription;
+import android.os.Bundle;
/** @hide */
oneway interface IEuiccService {
void downloadSubscription(int slotId, in DownloadableSubscription subscription,
- boolean switchAfterDownload, boolean forceDeactivateSim,
+ boolean switchAfterDownload, boolean forceDeactivateSim, in Bundle resolvedBundle,
in IDownloadSubscriptionCallback callback);
void getDownloadableSubscriptionMetadata(int slotId, in DownloadableSubscription subscription,
boolean forceDeactivateSim, in IGetDownloadableSubscriptionMetadataCallback callback);
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index b085bc9..b6fbb0a 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -1095,7 +1095,7 @@
#endif
// Dup the file descriptor so we can keep a reference to it after the Parcel
// is disposed.
- int dupFd = dup(blob.fd());
+ int dupFd = fcntl(blob.fd(), F_DUPFD_CLOEXEC, 0);
if (dupFd < 0) {
ALOGE("Error allocating dup fd. Error:%d", errno);
blob.release();
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 49a24a3..b2d3651 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -281,15 +281,18 @@
std::unique_ptr<NativeCode> code;
bool needs_native_bridge = false;
+ char* nativeloader_error_msg = nullptr;
void* handle = OpenNativeLibrary(env,
sdkVersion,
pathStr.c_str(),
classLoader,
libraryPath,
&needs_native_bridge,
- &g_error_msg);
+ &nativeloader_error_msg);
if (handle == nullptr) {
+ g_error_msg = nativeloader_error_msg;
+ NativeLoaderFreeErrorMessage(nativeloader_error_msg);
ALOGW("NativeActivity LoadNativeLibrary(\"%s\") failed: %s",
pathStr.c_str(),
g_error_msg.c_str());
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 7ef06dc..3b59321 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -473,7 +473,7 @@
if (parcel != NULL) {
int fd = parcel->readFileDescriptor();
if (fd < 0) return NULL;
- fd = dup(fd);
+ fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
if (fd < 0) return NULL;
return jniCreateFileDescriptor(env, fd);
}
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index d8d919d..c8e4125 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -33,6 +33,7 @@
// Static whitelist of open paths that the zygote is allowed to keep open.
static const char* kPathWhitelist[] = {
+ "/apex/com.android.conscrypt/javalib/conscrypt.jar",
"/dev/null",
"/dev/socket/zygote",
"/dev/socket/zygote_secondary",
diff --git a/core/proto/android/server/connectivity/data_stall_event.proto b/core/proto/android/server/connectivity/data_stall_event.proto
new file mode 100644
index 0000000..b70bb67
--- /dev/null
+++ b/core/proto/android/server/connectivity/data_stall_event.proto
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package com.android.server.connectivity;
+option java_multiple_files = true;
+option java_outer_classname = "DataStallEventProto";
+
+enum ProbeResult {
+ UNKNOWN = 0;
+ VALID = 1;
+ INVALID = 2;
+ PORTAL = 3;
+}
+
+enum ApBand {
+ AP_BAND_UNKNOWN = 0;
+ AP_BAND_2GHZ = 1;
+ AP_BAND_5GHZ = 2;
+}
+
+// Refer to definition in ServiceState.java.
+enum RadioTech {
+ RADIO_TECHNOLOGY_UNKNOWN = 0;
+ RADIO_TECHNOLOGY_GPRS = 1;
+ RADIO_TECHNOLOGY_EDGE = 2;
+ RADIO_TECHNOLOGY_UMTS = 3;
+ RADIO_TECHNOLOGY_IS95A = 4;
+ RADIO_TECHNOLOGY_IS95B = 5;
+ RADIO_TECHNOLOGY_1xRTT = 6;
+ RADIO_TECHNOLOGY_EVDO_0 = 7;
+ RADIO_TECHNOLOGY_EVDO_A = 8;
+ RADIO_TECHNOLOGY_HSDPA = 9;
+ RADIO_TECHNOLOGY_HSUPA = 10;
+ RADIO_TECHNOLOGY_HSPA = 11;
+ RADIO_TECHNOLOGY_EVDO_B = 12;
+ RADIO_TECHNOLOGY_EHRPD = 13;
+ RADIO_TECHNOLOGY_LTE = 14;
+ RADIO_TECHNOLOGY_HSPAP = 15;
+ RADIO_TECHNOLOGY_GSM = 16;
+ RADIO_TECHNOLOGY_TD_SCDMA = 17;
+ RADIO_TECHNOLOGY_IWLAN = 18;
+ RADIO_TECHNOLOGY_LTE_CA = 19;
+ RADIO_TECHNOLOGY_NR = 20;
+}
+
+// Cellular specific information.
+message CellularData {
+ // Indicate the radio technology at the time of data stall suspected.
+ optional RadioTech rat_type = 1;
+ // True if device is in roaming network at the time of data stall suspected.
+ optional bool is_roaming = 2;
+ // Registered network MccMnc when data stall happen
+ optional string network_mccmnc = 3;
+ // Indicate the SIM card carrier.
+ optional string sim_mccmnc = 4;
+ // Signal strength level at the time of data stall suspected.
+ optional int32 signal_strength = 5;
+}
+
+// Wifi specific information.
+message WifiData {
+ // Signal strength at the time of data stall suspected.
+ // RSSI range is between -55 to -110.
+ optional int32 signal_strength = 1;
+ // AP band.
+ optional ApBand wifi_band = 2;
+}
+
+message DnsEvent {
+ // The dns return code.
+ repeated int32 dns_return_code = 1;
+ // Indicate the timestamp of the dns event.
+ repeated int64 dns_time = 2;
+}
\ No newline at end of file
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index 25dabad..035ee10 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -42,6 +42,38 @@
}
prebuilt_etc {
+ name: "privapp_whitelist_com.android.carrierconfig",
+ product_specific: true,
+ sub_dir: "permissions",
+ src: "com.android.carrierconfig.xml",
+ filename_from_src: true,
+}
+
+prebuilt_etc {
+ name: "privapp_whitelist_com.android.contacts",
+ product_specific: true,
+ sub_dir: "permissions",
+ src: "com.android.contacts.xml",
+ filename_from_src: true,
+}
+
+prebuilt_etc {
+ name: "privapp_whitelist_com.android.launcher3",
+ product_specific: true,
+ sub_dir: "permissions",
+ src: "com.android.launcher3.xml",
+ filename_from_src: true,
+}
+
+prebuilt_etc {
+ name: "privapp_whitelist_com.android.provision",
+ product_specific: true,
+ sub_dir: "permissions",
+ src: "com.android.provision.xml",
+ filename_from_src: true,
+}
+
+prebuilt_etc {
name: "privapp_whitelist_com.android.settings",
product_specific: true,
sub_dir: "permissions",
@@ -50,6 +82,22 @@
}
prebuilt_etc {
+ name: "privapp_whitelist_com.android.settings.intelligence",
+ product_specific: true,
+ sub_dir: "permissions",
+ src: "com.android.settings.intelligence.xml",
+ filename_from_src: true,
+}
+
+prebuilt_etc {
+ name: "privapp_whitelist_com.android.storagemanager",
+ product_specific: true,
+ sub_dir: "permissions",
+ src: "com.android.storagemanager.xml",
+ filename_from_src: true,
+}
+
+prebuilt_etc {
name: "privapp_whitelist_com.android.systemui",
product_specific: true,
sub_dir: "permissions",
diff --git a/data/etc/com.android.carrierconfig.xml b/data/etc/com.android.carrierconfig.xml
new file mode 100644
index 0000000..17efb03
--- /dev/null
+++ b/data/etc/com.android.carrierconfig.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<permissions>
+ <privapp-permissions package="com.android.carrierconfig">
+ <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+ </privapp-permissions>
+</permissions>
diff --git a/data/etc/com.android.contacts.xml b/data/etc/com.android.contacts.xml
new file mode 100644
index 0000000..78eae40
--- /dev/null
+++ b/data/etc/com.android.contacts.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<permissions>
+ <privapp-permissions package="com.android.contacts">
+ <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+ <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
+ </privapp-permissions>
+</permissions>
diff --git a/data/etc/com.android.launcher3.xml b/data/etc/com.android.launcher3.xml
new file mode 100644
index 0000000..337e153
--- /dev/null
+++ b/data/etc/com.android.launcher3.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<permissions>
+ <privapp-permissions package="com.android.launcher3">
+ <permission name="android.permission.BIND_APPWIDGET"/>
+ <permission name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS"/>
+ <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+ </privapp-permissions>
+</permissions>
diff --git a/data/etc/com.android.provision.xml b/data/etc/com.android.provision.xml
new file mode 100644
index 0000000..05404ef
--- /dev/null
+++ b/data/etc/com.android.provision.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<permissions>
+ <privapp-permissions package="com.android.provision">
+ <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+ </privapp-permissions>
+</permissions>
diff --git a/data/etc/com.android.settings.intelligence.xml b/data/etc/com.android.settings.intelligence.xml
new file mode 100644
index 0000000..f06ae86
--- /dev/null
+++ b/data/etc/com.android.settings.intelligence.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<permissions>
+ <privapp-permissions package="com.android.settings.intelligence">
+ <permission name="android.permission.MANAGE_FINGERPRINT"/>
+ <permission name="android.permission.MODIFY_PHONE_STATE"/>
+ <permission name="android.permission.READ_SEARCH_INDEXABLES"/>
+ </privapp-permissions>
+</permissions>
diff --git a/data/etc/com.android.storagemanager.xml b/data/etc/com.android.storagemanager.xml
new file mode 100644
index 0000000..e85a82c
--- /dev/null
+++ b/data/etc/com.android.storagemanager.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<permissions>
+ <privapp-permissions package="com.android.storagemanager">
+ <permission name="android.permission.DELETE_PACKAGES"/>
+ <permission name="android.permission.INTERACT_ACROSS_USERS"/>
+ <permission name="android.permission.MANAGE_USERS"/>
+ <permission name="android.permission.PACKAGE_USAGE_STATS"/>
+ <permission name="android.permission.USE_RESERVED_DISK"/>
+ <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+ </privapp-permissions>
+</permissions>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 07287b1..c9f0f10 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -33,10 +33,6 @@
<permission name="android.permission.CRYPT_KEEPER"/>
</privapp-permissions>
- <privapp-permissions package="com.android.carrierconfig">
- <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
- </privapp-permissions>
-
<privapp-permissions package="com.android.cellbroadcastreceiver">
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
<permission name="android.permission.MANAGE_USERS"/>
@@ -45,11 +41,6 @@
<permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/>
</privapp-permissions>
- <privapp-permissions package="com.android.contacts">
- <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
- <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
- </privapp-permissions>
-
<privapp-permissions package="com.android.defcontainer">
<permission name="android.permission.ACCESS_CACHE_FILESYSTEM"/>
<permission name="android.permission.ALLOCATE_AGGRESSIVE"/>
@@ -79,12 +70,6 @@
<permission name="android.permission.WRITE_MEDIA_STORAGE"/>
</privapp-permissions>
- <privapp-permissions package="com.android.launcher3">
- <permission name="android.permission.BIND_APPWIDGET"/>
- <permission name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS"/>
- <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
- </privapp-permissions>
-
<privapp-permissions package="com.android.location.fused">
<permission name="android.permission.INSTALL_LOCATION_PROVIDER"/>
</privapp-permissions>
@@ -225,10 +210,6 @@
<permission name="android.permission.USE_RESERVED_DISK"/>
</privapp-permissions>
- <privapp-permissions package="com.android.provision">
- <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
- </privapp-permissions>
-
<privapp-permissions package="com.android.mainline.networkstack">
<permission name="android.permission.ACCESS_NETWORK_CONDITIONS"/>
<permission name="android.permission.CHANGE_BACKGROUND_DATA_SETTING"/>
@@ -267,12 +248,6 @@
<permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
</privapp-permissions>
- <privapp-permissions package="com.android.settings.intelligence">
- <permission name="android.permission.MANAGE_FINGERPRINT"/>
- <permission name="android.permission.MODIFY_PHONE_STATE"/>
- <permission name="android.permission.READ_SEARCH_INDEXABLES"/>
- </privapp-permissions>
-
<privapp-permissions package="com.android.sharedstoragebackup">
<permission name="android.permission.WRITE_MEDIA_STORAGE"/>
</privapp-permissions>
@@ -339,15 +314,6 @@
<permission name="android.permission.INTENT_FILTER_VERIFICATION_AGENT"/>
</privapp-permissions>
- <privapp-permissions package="com.android.storagemanager">
- <permission name="android.permission.DELETE_PACKAGES"/>
- <permission name="android.permission.INTERACT_ACROSS_USERS"/>
- <permission name="android.permission.MANAGE_USERS"/>
- <permission name="android.permission.PACKAGE_USAGE_STATS"/>
- <permission name="android.permission.USE_RESERVED_DISK"/>
- <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
- </privapp-permissions>
-
<privapp-permissions package="com.android.tv">
<permission name="android.permission.CHANGE_HDMI_CEC_ACTIVE_SOURCE"/>
<permission name="android.permission.DVB_DEVICE"/>
diff --git a/libs/androidfw/AttributeResolution.cpp b/libs/androidfw/AttributeResolution.cpp
index f912af4..2fcecf2 100644
--- a/libs/androidfw/AttributeResolution.cpp
+++ b/libs/androidfw/AttributeResolution.cpp
@@ -51,7 +51,7 @@
class BagAttributeFinder
: public BackTrackingAttributeFinder<BagAttributeFinder, const ResolvedBag::Entry*> {
public:
- BagAttributeFinder(const ResolvedBag* bag)
+ explicit BagAttributeFinder(const ResolvedBag* bag)
: BackTrackingAttributeFinder(bag != nullptr ? bag->entries : nullptr,
bag != nullptr ? bag->entries + bag->entry_count : nullptr) {
}
diff --git a/libs/androidfw/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp
index 5694115..a99e77f 100644
--- a/libs/androidfw/CursorWindow.cpp
+++ b/libs/androidfw/CursorWindow.cpp
@@ -94,7 +94,7 @@
if (size < 0) {
result = UNKNOWN_ERROR;
} else {
- int dupAshmemFd = ::dup(ashmemFd);
+ int dupAshmemFd = ::fcntl(ashmemFd, F_DUPFD_CLOEXEC, 0);
if (dupAshmemFd < 0) {
result = -errno;
} else {
diff --git a/libs/androidfw/ZipUtils.cpp b/libs/androidfw/ZipUtils.cpp
index 5d243da..5be2105 100644
--- a/libs/androidfw/ZipUtils.cpp
+++ b/libs/androidfw/ZipUtils.cpp
@@ -37,7 +37,7 @@
// TODO: This can go away once the only remaining usage in aapt goes away.
class FileReader : public zip_archive::Reader {
public:
- FileReader(FILE* fp) : Reader(), mFp(fp), mCurrentOffset(0) {
+ explicit FileReader(FILE* fp) : Reader(), mFp(fp), mCurrentOffset(0) {
}
bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const {
diff --git a/libs/androidfw/include/androidfw/AssetDir.h b/libs/androidfw/include/androidfw/AssetDir.h
index 7aef02d..ce6e066 100644
--- a/libs/androidfw/include/androidfw/AssetDir.h
+++ b/libs/androidfw/include/androidfw/AssetDir.h
@@ -78,7 +78,7 @@
class FileInfo {
public:
FileInfo(void) {}
- FileInfo(const String8& path) // useful for e.g. svect.indexOf
+ explicit FileInfo(const String8& path) // useful for e.g. svect.indexOf
: mFileName(path), mFileType(kFileTypeUnknown)
{}
~FileInfo(void) {}
diff --git a/libs/androidfw/include/androidfw/BackupHelpers.h b/libs/androidfw/include/androidfw/BackupHelpers.h
index fc1ad47..2da247b 100644
--- a/libs/androidfw/include/androidfw/BackupHelpers.h
+++ b/libs/androidfw/include/androidfw/BackupHelpers.h
@@ -67,7 +67,7 @@
class BackupDataWriter
{
public:
- BackupDataWriter(int fd);
+ explicit BackupDataWriter(int fd);
// does not close fd
~BackupDataWriter();
@@ -104,7 +104,7 @@
class BackupDataReader
{
public:
- BackupDataReader(int fd);
+ explicit BackupDataReader(int fd);
// does not close fd
~BackupDataReader();
diff --git a/libs/androidfw/include/androidfw/ConfigDescription.h b/libs/androidfw/include/androidfw/ConfigDescription.h
index 29424c4..6fa089a 100644
--- a/libs/androidfw/include/androidfw/ConfigDescription.h
+++ b/libs/androidfw/include/androidfw/ConfigDescription.h
@@ -82,7 +82,7 @@
static void ApplyVersionForCompatibility(ConfigDescription* config);
ConfigDescription();
- ConfigDescription(const android::ResTable_config& o); // NOLINT(implicit)
+ ConfigDescription(const android::ResTable_config& o); // NOLINT(google-explicit-constructor)
ConfigDescription(const ConfigDescription& o);
ConfigDescription(ConfigDescription&& o) noexcept;
diff --git a/libs/androidfw/include/androidfw/DisplayEventDispatcher.h b/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
index e1dfb94..bf35aa3 100644
--- a/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
+++ b/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
@@ -22,7 +22,7 @@
class DisplayEventDispatcher : public LooperCallback {
public:
- DisplayEventDispatcher(const sp<Looper>& looper,
+ explicit DisplayEventDispatcher(const sp<Looper>& looper,
ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp);
status_t initialize();
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index a028515..be536bf 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -691,7 +691,7 @@
class ResXMLParser
{
public:
- ResXMLParser(const ResXMLTree& tree);
+ explicit ResXMLParser(const ResXMLTree& tree);
enum event_code_t {
BAD_DOCUMENT = -1,
@@ -804,7 +804,7 @@
* The tree stores a clone of the specified DynamicRefTable, so any changes to the original
* DynamicRefTable will not affect this tree after instantiation.
**/
- ResXMLTree(const DynamicRefTable* dynamicRefTable);
+ explicit ResXMLTree(const DynamicRefTable* dynamicRefTable);
ResXMLTree();
~ResXMLTree();
@@ -1803,7 +1803,7 @@
class Theme {
public:
- Theme(const ResTable& table);
+ explicit Theme(const ResTable& table);
~Theme();
inline const ResTable& getResTable() const { return mTable; }
diff --git a/libs/androidfw/include/androidfw/StringPiece.h b/libs/androidfw/include/androidfw/StringPiece.h
index 99b4245..c65c86b 100644
--- a/libs/androidfw/include/androidfw/StringPiece.h
+++ b/libs/androidfw/include/androidfw/StringPiece.h
@@ -44,8 +44,8 @@
BasicStringPiece();
BasicStringPiece(const BasicStringPiece<TChar>& str);
- BasicStringPiece(const std::basic_string<TChar>& str); // NOLINT(implicit)
- BasicStringPiece(const TChar* str); // NOLINT(implicit)
+ BasicStringPiece(const std::basic_string<TChar>& str); // NOLINT(google-explicit-constructor)
+ BasicStringPiece(const TChar* str); // NOLINT(google-explicit-constructor)
BasicStringPiece(const TChar* str, size_t len);
BasicStringPiece<TChar>& operator=(const BasicStringPiece<TChar>& rhs);
diff --git a/libs/androidfw/include/androidfw/TypeWrappers.h b/libs/androidfw/include/androidfw/TypeWrappers.h
index 5cfe54e5..fb2fad6 100644
--- a/libs/androidfw/include/androidfw/TypeWrappers.h
+++ b/libs/androidfw/include/androidfw/TypeWrappers.h
@@ -23,7 +23,7 @@
namespace android {
struct TypeVariant {
- TypeVariant(const ResTable_type* data);
+ explicit TypeVariant(const ResTable_type* data);
class iterator {
public:
diff --git a/libs/androidfw/include/androidfw/Util.h b/libs/androidfw/include/androidfw/Util.h
index 10d088e..aa1466f 100644
--- a/libs/androidfw/include/androidfw/Util.h
+++ b/libs/androidfw/include/androidfw/Util.h
@@ -46,7 +46,7 @@
using pointer = typename std::add_pointer<T>::type;
constexpr unique_cptr() : ptr_(nullptr) {}
- constexpr unique_cptr(std::nullptr_t) : ptr_(nullptr) {}
+ constexpr explicit unique_cptr(std::nullptr_t) : ptr_(nullptr) {}
explicit unique_cptr(pointer ptr) : ptr_(ptr) {}
unique_cptr(unique_cptr&& o) noexcept : ptr_(o.ptr_) { o.ptr_ = nullptr; }
diff --git a/native/android/sharedmem.cpp b/native/android/sharedmem.cpp
index 757aaec..4410bd6 100644
--- a/native/android/sharedmem.cpp
+++ b/native/android/sharedmem.cpp
@@ -71,7 +71,7 @@
}
int fd = env->CallIntMethod(javaSharedMemory, sSharedMemory.getFd);
if (fd != -1) {
- fd = dup(fd);
+ fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
}
return fd;
}
diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml
index 0b0f1ec..7f8bb93 100644
--- a/packages/NetworkStack/AndroidManifest.xml
+++ b/packages/NetworkStack/AndroidManifest.xml
@@ -20,6 +20,7 @@
package="com.android.mainline.networkstack"
android:sharedUserId="android.uid.networkstack">
<uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
index 94ea1b9..4077d93 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
@@ -545,7 +545,9 @@
return HANDLED;
case CMD_FORCE_REEVALUATION:
case CMD_CAPTIVE_PORTAL_RECHECK:
- log("Forcing reevaluation for UID " + message.arg1);
+ final int dnsCount = mDnsStallDetector.getConsecutiveTimeoutCount();
+ validationLog("Forcing reevaluation for UID " + message.arg1
+ + ". Dns signal count: " + dnsCount);
mUidResponsibleForReeval = message.arg1;
transitionTo(mEvaluatingState);
return HANDLED;
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 2530abc..2d7471d 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -56,6 +56,7 @@
import android.accounts.Account;
import android.accounts.AccountManager;
import android.annotation.MainThread;
+import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Notification;
@@ -799,6 +800,18 @@
Log.wtf(TAG, "Missing " + EXTRA_BUGREPORT + " on intent " + intent);
return;
}
+ final int max = intent.getIntExtra(EXTRA_MAX, -1);
+ final File screenshotFile = getFileExtra(intent, EXTRA_SCREENSHOT);
+ final String shareTitle = intent.getStringExtra(EXTRA_TITLE);
+ final String shareDescription = intent.getStringExtra(EXTRA_DESCRIPTION);
+ onBugreportFinished(id, bugreportFile, screenshotFile, shareTitle, shareDescription, max);
+ }
+
+ /**
+ * Wraps up bugreport generation and triggers a notification to share the bugreport.
+ */
+ private void onBugreportFinished(int id, File bugreportFile, @Nullable File screenshotFile,
+ String shareTitle, String shareDescription, int max) {
mInfoDialog.onBugreportFinished();
BugreportInfo info = getInfo(id);
if (info == null) {
@@ -809,22 +822,17 @@
}
info.renameScreenshots(mScreenshotsDir);
info.bugreportFile = bugreportFile;
+ if (screenshotFile != null) {
+ info.addScreenshot(screenshotFile);
+ }
- final int max = intent.getIntExtra(EXTRA_MAX, -1);
if (max != -1) {
MetricsLogger.histogram(this, "dumpstate_duration", max);
info.max = max;
}
- final File screenshot = getFileExtra(intent, EXTRA_SCREENSHOT);
- if (screenshot != null) {
- info.addScreenshot(screenshot);
- }
-
- final String shareTitle = intent.getStringExtra(EXTRA_TITLE);
if (!TextUtils.isEmpty(shareTitle)) {
info.title = shareTitle;
- final String shareDescription = intent.getStringExtra(EXTRA_DESCRIPTION);
if (!TextUtils.isEmpty(shareDescription)) {
info.shareDescription= shareDescription;
}
@@ -1944,6 +1952,22 @@
}
@Override
+ public void onProgress(int progress) throws RemoteException {
+ updateProgressInfo(progress, 100 /* progress is already a percentage; so max = 100 */);
+ }
+
+ @Override
+ public void onError(int errorCode) throws RemoteException {
+ // TODO(b/111441001): implement
+ }
+
+ @Override
+ public void onFinished(long durationMs, String title, String description)
+ throws RemoteException {
+ // TODO(b/111441001): implement
+ }
+
+ @Override
public void onProgressUpdated(int progress) throws RemoteException {
/*
* Checks whether the progress changed in a way that should be displayed to the user:
@@ -1964,21 +1988,7 @@
}
if (newPercentage > oldPercentage) {
- if (DEBUG) {
- if (progress != info.progress) {
- Log.v(TAG, "Updating progress for PID " + info.pid + "(id: " + info.id
- + ") from " + info.progress + " to " + progress);
- }
- if (max != info.max) {
- Log.v(TAG, "Updating max progress for PID " + info.pid + "(id: " + info.id
- + ") from " + info.max + " to " + max);
- }
- }
- info.progress = progress;
- info.max = max;
- info.lastUpdate = System.currentTimeMillis();
-
- updateProgress(info);
+ updateProgressInfo(progress, max);
}
}
@@ -2000,5 +2010,23 @@
public void dump(String prefix, PrintWriter pw) {
pw.print(prefix); pw.print("token: "); pw.println(token);
}
+
+ private void updateProgressInfo(int progress, int max) {
+ if (DEBUG) {
+ if (progress != info.progress) {
+ Log.v(TAG, "Updating progress for PID " + info.pid + "(id: " + info.id
+ + ") from " + info.progress + " to " + progress);
+ }
+ if (max != info.max) {
+ Log.v(TAG, "Updating max progress for PID " + info.pid + "(id: " + info.id
+ + ") from " + info.max + " to " + max);
+ }
+ }
+ info.progress = progress;
+ info.max = max;
+ info.lastUpdate = System.currentTimeMillis();
+
+ updateProgress(info);
+ }
}
}
diff --git a/packages/WallpaperCropper/Android.mk b/packages/WallpaperCropper/Android.mk
index 848f2bd..2fa1dde 100644
--- a/packages/WallpaperCropper/Android.mk
+++ b/packages/WallpaperCropper/Android.mk
@@ -8,6 +8,7 @@
LOCAL_PACKAGE_NAME := WallpaperCropper
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_CERTIFICATE := platform
+LOCAL_PRODUCT_MODULE := true
LOCAL_PRIVILEGED_MODULE := true
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
diff --git a/packages/WallpaperCropper/CleanSpec.mk b/packages/WallpaperCropper/CleanSpec.mk
new file mode 100644
index 0000000..e6d8d5a
--- /dev/null
+++ b/packages/WallpaperCropper/CleanSpec.mk
@@ -0,0 +1,50 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list. These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list. E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/WallpaperCropper)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index d0666b9..d6f3e2b 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -4879,7 +4879,7 @@
final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore,
- mContext, mTrackerHandler, new NetworkMisc(networkMisc), this);
+ mContext, mTrackerHandler, new NetworkMisc(networkMisc), this, mNetd, mNMS);
// Make sure the network capabilities reflect what the agent info says.
nai.networkCapabilities = mixInCapabilities(nai, nc);
final String extraInfo = networkInfo.getExtraInfo();
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 00b1320..600a6ae 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -17,13 +17,11 @@
package com.android.server;
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
-import static android.Manifest.permission.DUMP;
import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.Manifest.permission.NETWORK_STACK;
import static android.Manifest.permission.SHUTDOWN;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
-import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_NONE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NONE;
@@ -40,6 +38,7 @@
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.net.TrafficStats.UID_TETHERING;
+
import static com.android.server.NetworkManagementService.NetdResponseCode.ClatdStatusResult;
import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceGetCfgResult;
import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceListResult;
@@ -53,11 +52,9 @@
import android.annotation.NonNull;
import android.app.ActivityManager;
-import android.content.ContentResolver;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.INetd;
-import android.net.TetherStatsParcel;
import android.net.INetworkManagementEventObserver;
import android.net.ITetheringStatsProvider;
import android.net.InterfaceConfiguration;
@@ -69,18 +66,15 @@
import android.net.NetworkStats;
import android.net.NetworkUtils;
import android.net.RouteInfo;
+import android.net.TetherStatsParcel;
import android.net.UidRange;
-import android.net.UidRangeParcel;
import android.net.util.NetdService;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.INetworkActivityListener;
import android.os.INetworkManagementService;
-import android.os.PersistableBundle;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteCallbackList;
@@ -91,12 +85,7 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
-import android.provider.Settings;
import android.telephony.DataConnectionRealTimeInfo;
-import android.telephony.PhoneStateListener;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
@@ -109,13 +98,11 @@
import com.android.internal.util.DumpUtils;
import com.android.internal.util.HexDump;
import com.android.internal.util.Preconditions;
-import com.android.server.NativeDaemonConnector.Command;
-import com.android.server.NativeDaemonConnector.SensitiveArg;
+
import com.google.android.collect.Maps;
import java.io.BufferedReader;
import java.io.DataInputStream;
-import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
@@ -123,15 +110,11 @@
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InterfaceAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.StringTokenizer;
import java.util.concurrent.CountDownLatch;
/**
@@ -2147,28 +2130,6 @@
}
@Override
- public void startClatd(String interfaceName) throws IllegalStateException {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
- try {
- mNetdService.clatdStart(interfaceName);
- } catch (RemoteException | ServiceSpecificException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
- public void stopClatd(String interfaceName) throws IllegalStateException {
- mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
- try {
- mNetdService.clatdStop(interfaceName);
- } catch (RemoteException | ServiceSpecificException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
public void registerNetworkActivityListener(INetworkActivityListener listener) {
mNetworkActivityListeners.register(listener);
}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 566d837..ead9cab 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -2008,6 +2008,13 @@
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
}
+ if ((events & PhoneStateListener.LISTEN_PREFERRED_DATA_SUBID_CHANGE) != 0) {
+ // It can have either READ_PHONE_STATE or READ_PRIVILEGED_PHONE_STATE.
+ TelephonyPermissions.checkReadPhoneState(mContext,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID, Binder.getCallingPid(),
+ Binder.getCallingUid(), callingPackage, "listen to "
+ + "LISTEN_PREFERRED_DATA_SUBID_CHANGE");
+ }
if ((events & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) {
mContext.enforceCallingOrSelfPermission(
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index 6596d27..9d9b1cf 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -16,8 +16,9 @@
package com.android.server.connectivity;
-import android.net.InterfaceConfiguration;
import android.net.ConnectivityManager;
+import android.net.INetd;
+import android.net.InterfaceConfiguration;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.NetworkInfo;
@@ -59,6 +60,7 @@
NetworkInfo.State.SUSPENDED,
};
+ private final INetd mNetd;
private final INetworkManagementService mNMService;
// The network we're running on, and its type.
@@ -76,7 +78,8 @@
private String mIface;
private State mState = State.IDLE;
- public Nat464Xlat(INetworkManagementService nmService, NetworkAgentInfo nai) {
+ public Nat464Xlat(NetworkAgentInfo nai, INetd netd, INetworkManagementService nmService) {
+ mNetd = netd;
mNMService = nmService;
mNetwork = nai;
}
@@ -140,7 +143,7 @@
return;
}
try {
- mNMService.startClatd(baseIface);
+ mNetd.clatdStart(baseIface);
} catch(RemoteException|IllegalStateException e) {
Slog.e(TAG, "Error starting clatd on " + baseIface, e);
}
@@ -162,7 +165,7 @@
*/
private void enterStoppingState() {
try {
- mNMService.stopClatd(mBaseIface);
+ mNetd.clatdStop(mBaseIface);
} catch(RemoteException|IllegalStateException e) {
Slog.e(TAG, "Error stopping clatd on " + mBaseIface, e);
}
@@ -204,7 +207,7 @@
Slog.e(TAG, "startClat: Can't start clat on null interface");
return;
}
- // TODO: should we only do this if mNMService.startClatd() succeeds?
+ // TODO: should we only do this if mNetd.clatdStart() succeeds?
Slog.i(TAG, "Starting clatd on " + baseIface);
enterStartingState(baseIface);
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 54c89aa..9ea73fb 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -17,6 +17,7 @@
package com.android.server.connectivity;
import android.content.Context;
+import android.net.INetd;
import android.net.INetworkMonitor;
import android.net.LinkProperties;
import android.net.Network;
@@ -239,12 +240,15 @@
private static final String TAG = ConnectivityService.class.getSimpleName();
private static final boolean VDBG = false;
private final ConnectivityService mConnService;
+ private final INetd mNetd;
+ private final INetworkManagementService mNMS;
private final Context mContext;
private final Handler mHandler;
public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info,
LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler,
- NetworkMisc misc, ConnectivityService connService) {
+ NetworkMisc misc, ConnectivityService connService, INetd netd,
+ INetworkManagementService nms) {
this.messenger = messenger;
asyncChannel = ac;
network = net;
@@ -253,6 +257,8 @@
networkCapabilities = nc;
currentScore = score;
mConnService = connService;
+ mNetd = netd;
+ mNMS = nms;
mContext = context;
mHandler = handler;
networkMisc = misc;
@@ -587,18 +593,18 @@
public void updateClat(INetworkManagementService netd) {
if (Nat464Xlat.requiresClat(this)) {
- maybeStartClat(netd);
+ maybeStartClat();
} else {
maybeStopClat();
}
}
/** Ensure clat has started for this network. */
- public void maybeStartClat(INetworkManagementService netd) {
+ public void maybeStartClat() {
if (clatd != null && clatd.isStarted()) {
return;
}
- clatd = new Nat464Xlat(netd, this);
+ clatd = new Nat464Xlat(this, mNetd, mNMS);
clatd.start();
}
diff --git a/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreDatabase.java b/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreDatabase.java
new file mode 100644
index 0000000..eaab650
--- /dev/null
+++ b/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreDatabase.java
@@ -0,0 +1,143 @@
+/*
+ * 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.server.net.ipmemorystore;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+/**
+ * Encapsulating class for using the SQLite database backing the memory store.
+ *
+ * This class groups together the contracts and the SQLite helper used to
+ * use the database.
+ *
+ * @hide
+ */
+public class IpMemoryStoreDatabase {
+ /**
+ * Contract class for the Network Attributes table.
+ */
+ public static class NetworkAttributesContract {
+ public static final String TABLENAME = "NetworkAttributes";
+
+ public static final String COLNAME_L2KEY = "l2Key";
+ public static final String COLTYPE_L2KEY = "TEXT NOT NULL";
+
+ public static final String COLNAME_EXPIRYDATE = "expiryDate";
+ // Milliseconds since the Epoch, in true Java style
+ public static final String COLTYPE_EXPIRYDATE = "BIGINT";
+
+ public static final String COLNAME_ASSIGNEDV4ADDRESS = "assignedV4Address";
+ public static final String COLTYPE_ASSIGNEDV4ADDRESS = "INTEGER";
+
+ // Please note that the group hint is only a *hint*, hence its name. The client can offer
+ // this information to nudge the grouping in the decision it thinks is right, but it can't
+ // decide for the memory store what is the same L3 network.
+ public static final String COLNAME_GROUPHINT = "groupHint";
+ public static final String COLTYPE_GROUPHINT = "TEXT";
+
+ public static final String COLNAME_DNSADDRESSES = "dnsAddresses";
+ // Stored in marshalled form as is
+ public static final String COLTYPE_DNSADDRESSES = "BLOB";
+
+ public static final String COLNAME_MTU = "mtu";
+ public static final String COLTYPE_MTU = "INTEGER";
+
+ public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS "
+ + TABLENAME + " ("
+ + COLNAME_L2KEY + " " + COLTYPE_L2KEY + " PRIMARY KEY NOT NULL, "
+ + COLNAME_EXPIRYDATE + " " + COLTYPE_EXPIRYDATE + ", "
+ + COLNAME_ASSIGNEDV4ADDRESS + " " + COLTYPE_ASSIGNEDV4ADDRESS + ", "
+ + COLNAME_GROUPHINT + " " + COLTYPE_GROUPHINT + ", "
+ + COLNAME_DNSADDRESSES + " " + COLTYPE_DNSADDRESSES + ", "
+ + COLNAME_MTU + " " + COLTYPE_MTU + ")";
+ public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLENAME;
+ }
+
+ /**
+ * Contract class for the Private Data table.
+ */
+ public static class PrivateDataContract {
+ public static final String TABLENAME = "PrivateData";
+
+ public static final String COLNAME_L2KEY = "l2Key";
+ public static final String COLTYPE_L2KEY = "TEXT NOT NULL";
+
+ public static final String COLNAME_CLIENT = "client";
+ public static final String COLTYPE_CLIENT = "TEXT NOT NULL";
+
+ public static final String COLNAME_DATANAME = "dataName";
+ public static final String COLTYPE_DATANAME = "TEXT NOT NULL";
+
+ public static final String COLNAME_DATA = "data";
+ public static final String COLTYPE_DATA = "BLOB NOT NULL";
+
+ public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS "
+ + TABLENAME + " ("
+ + COLNAME_L2KEY + " " + COLTYPE_L2KEY + ", "
+ + COLNAME_CLIENT + " " + COLTYPE_CLIENT + ", "
+ + COLNAME_DATANAME + " " + COLTYPE_DATANAME + ", "
+ + COLNAME_DATA + " " + COLTYPE_DATA + ", "
+ + "PRIMARY KEY ("
+ + COLNAME_L2KEY + ", "
+ + COLNAME_CLIENT + ", "
+ + COLNAME_DATANAME + "))";
+ public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLENAME;
+ }
+
+ // To save memory when the DB is not used, close it after 30s of inactivity. This is
+ // determined manually based on what feels right.
+ private static final long IDLE_CONNECTION_TIMEOUT_MS = 30_000;
+
+ /** The SQLite DB helper */
+ public static class DbHelper extends SQLiteOpenHelper {
+ // Update this whenever changing the schema.
+ private static final int SCHEMA_VERSION = 1;
+ private static final String DATABASE_FILENAME = "IpMemoryStore.db";
+
+ public DbHelper(@NonNull final Context context) {
+ super(context, DATABASE_FILENAME, null, SCHEMA_VERSION);
+ setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
+ }
+
+ /** Called when the database is created */
+ public void onCreate(@NonNull final SQLiteDatabase db) {
+ db.execSQL(NetworkAttributesContract.CREATE_TABLE);
+ db.execSQL(PrivateDataContract.CREATE_TABLE);
+ }
+
+ /** Called when the database is upgraded */
+ public void onUpgrade(@NonNull final SQLiteDatabase db, final int oldVersion,
+ final int newVersion) {
+ // No upgrade supported yet.
+ db.execSQL(NetworkAttributesContract.DROP_TABLE);
+ db.execSQL(PrivateDataContract.DROP_TABLE);
+ onCreate(db);
+ }
+
+ /** Called when the database is downgraded */
+ public void onDowngrade(@NonNull final SQLiteDatabase db, final int oldVersion,
+ final int newVersion) {
+ // Downgrades always nuke all data and recreate an empty table.
+ db.execSQL(NetworkAttributesContract.DROP_TABLE);
+ db.execSQL(PrivateDataContract.DROP_TABLE);
+ onCreate(db);
+ }
+ }
+}
diff --git a/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreService.java b/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreService.java
index c9759bf..55a72190 100644
--- a/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreService.java
+++ b/services/ipmemorystore/java/com/android/server/net/ipmemorystore/IpMemoryStoreService.java
@@ -19,6 +19,8 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
import android.net.IIpMemoryStore;
import android.net.ipmemorystore.Blob;
import android.net.ipmemorystore.IOnBlobRetrievedListener;
@@ -27,6 +29,10 @@
import android.net.ipmemorystore.IOnSameNetworkResponseListener;
import android.net.ipmemorystore.IOnStatusListener;
import android.net.ipmemorystore.NetworkAttributesParcelable;
+import android.util.Log;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
/**
* Implementation for the IP memory store.
@@ -37,10 +43,75 @@
* @hide
*/
public class IpMemoryStoreService extends IIpMemoryStore.Stub {
- final Context mContext;
+ private static final String TAG = IpMemoryStoreService.class.getSimpleName();
+ private static final int MAX_CONCURRENT_THREADS = 4;
+ @NonNull
+ final Context mContext;
+ @Nullable
+ final SQLiteDatabase mDb;
+ @NonNull
+ final ExecutorService mExecutor;
+
+ /**
+ * Construct an IpMemoryStoreService object.
+ * This constructor will block on disk access to open the database.
+ * @param context the context to access storage with.
+ */
public IpMemoryStoreService(@NonNull final Context context) {
+ // Note that constructing the service will access the disk and block
+ // for some time, but it should make no difference to the clients. Because
+ // the interface is one-way, clients fire and forget requests, and the callback
+ // will get called eventually in any case, and the framework will wait for the
+ // service to be created to deliver subsequent requests.
+ // Avoiding this would mean the mDb member can't be final, which means the service would
+ // have to test for nullity, care for failure, and allow for a wait at every single access,
+ // which would make the code a lot more complex and require all methods to possibly block.
mContext = context;
+ SQLiteDatabase db;
+ final IpMemoryStoreDatabase.DbHelper helper = new IpMemoryStoreDatabase.DbHelper(context);
+ try {
+ db = helper.getWritableDatabase();
+ if (null == db) Log.e(TAG, "Unexpected null return of getWriteableDatabase");
+ } catch (final SQLException e) {
+ Log.e(TAG, "Can't open the Ip Memory Store database", e);
+ db = null;
+ } catch (final Exception e) {
+ Log.wtf(TAG, "Impossible exception Ip Memory Store database", e);
+ db = null;
+ }
+ mDb = db;
+ // The work-stealing thread pool executor will spawn threads as needed up to
+ // the max only when there is no free thread available. This generally behaves
+ // exactly like one would expect it intuitively :
+ // - When work arrives, it will spawn a new thread iff there are no available threads
+ // - When there is no work to do it will shutdown threads after a while (the while
+ // being equal to 2 seconds (not configurable) when max threads are spun up and
+ // twice as much for every one less thread)
+ // - When all threads are busy the work is enqueued and waits for any worker
+ // to become available.
+ // Because the stealing pool is made for very heavily parallel execution of
+ // small tasks that spawn others, it creates a queue per thread that in this
+ // case is overhead. However, the three behaviors above make it a superior
+ // choice to cached or fixedThreadPoolExecutor, neither of which can actually
+ // enqueue a task waiting for a thread to be free. This can probably be solved
+ // with judicious subclassing of ThreadPoolExecutor, but that's a lot of dangerous
+ // complexity for little benefit in this case.
+ mExecutor = Executors.newWorkStealingPool(MAX_CONCURRENT_THREADS);
+ }
+
+ /**
+ * Shutdown the memory store service, cancelling running tasks and dropping queued tasks.
+ *
+ * This is provided to give a way to clean up, and is meant to be available in case of an
+ * emergency shutdown.
+ */
+ public void shutdown() {
+ // By contrast with ExecutorService#shutdown, ExecutorService#shutdownNow tries
+ // to cancel the existing tasks, and does not wait for completion. It does not
+ // guarantee the threads can be terminated in any given amount of time.
+ mExecutor.shutdownNow();
+ if (mDb != null) mDb.close();
}
/**
@@ -61,7 +132,7 @@
public void storeNetworkAttributes(@NonNull final String l2Key,
@NonNull final NetworkAttributesParcelable attributes,
@Nullable final IOnStatusListener listener) {
- // TODO : implement this
+ // TODO : implement this.
}
/**
@@ -79,7 +150,7 @@
public void storeBlob(@NonNull final String l2Key, @NonNull final String clientId,
@NonNull final String name, @NonNull final Blob data,
@Nullable final IOnStatusListener listener) {
- // TODO : implement this
+ // TODO : implement this.
}
/**
@@ -99,7 +170,7 @@
@Override
public void findL2Key(@NonNull final NetworkAttributesParcelable attributes,
@NonNull final IOnL2KeyResponseListener listener) {
- // TODO : implement this
+ // TODO : implement this.
}
/**
@@ -114,7 +185,7 @@
@Override
public void isSameNetwork(@NonNull final String l2Key1, @NonNull final String l2Key2,
@NonNull final IOnSameNetworkResponseListener listener) {
- // TODO : implement this
+ // TODO : implement this.
}
/**
diff --git a/services/ipmemorystore/java/com/android/server/net/ipmemorystore/RelevanceUtils.java b/services/ipmemorystore/java/com/android/server/net/ipmemorystore/RelevanceUtils.java
new file mode 100644
index 0000000..aa45400
--- /dev/null
+++ b/services/ipmemorystore/java/com/android/server/net/ipmemorystore/RelevanceUtils.java
@@ -0,0 +1,307 @@
+/*
+ * 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.server.net.ipmemorystore;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * A class containing the logic around the relevance value for
+ * IP Memory Store.
+ *
+ * @hide
+ */
+public class RelevanceUtils {
+ /**
+ * The relevance is a decaying value that gets lower and lower until it
+ * reaches 0 after some time passes. It follows an exponential decay law,
+ * dropping slowly at first then faster and faster, because a network is
+ * likely to be visited again if it was visited not long ago, and the longer
+ * it hasn't been visited the more likely it is that it won't be visited
+ * again. For example, a network visited on holiday should stay fresh for
+ * the duration of the holiday and persist for a while, but after the venue
+ * hasn't been visited for a while it should quickly be discarded. What
+ * should accelerate forgetting the network is extended periods without
+ * visits, so that occasional venues get discarded but regular visits keep
+ * the network relevant, even if the visits are infrequent.
+ *
+ * This function must be stable by iteration, meaning that adjusting the same value
+ * for different dates iteratively multiple times should give the same result.
+ * Formally, if f is the decay function that associates a relevance x at a date d1
+ * to the value at ulterior date d3, then for any date d2 between d1 and d3 :
+ * f(x, d3 - d1) = f(f(x, d3 - d2), d2 - d1). Intuitively, this property simply
+ * means it should be the same to compute and store back the value after two months,
+ * or to do it once after one month, store it back, and do it again after another
+ * months has passed.
+ * The pair of the relevance and date define the entire curve, so any pair
+ * of values on the curve will define the same curve. Setting one of them to a
+ * constant, so as not to have to store it, means the other one will always suffice
+ * to describe the curve. For example, only storing the date for a known, constant
+ * value of the relevance is an efficient way of remembering this information (and
+ * to compare relevances together, as f is monotonically decreasing).
+ *
+ *** Choosing the function :
+ * Functions of the kind described above are standard exponential decay functions
+ * like the ones that govern atomic decay where the value at any given date can be
+ * computed uniformly from the value at a previous date and the time elapsed since
+ * that date. It is simple to picture this kind of function as one where after a
+ * given period of time called the half-life, the relevance value will have been
+ * halved. Decay of this kind is expressed in function of the previous value by
+ * functions like
+ * f(x, t) = x * F ^ (t / L)
+ * ...where x is the value, t is the elapsed time, L is the half-life (or more
+ * generally the F-th-life) and F the decay factor (typically 0.5, hence why L is
+ * usually called the half-life). The ^ symbol here is used for exponentiation.
+ * Or, starting at a given M for t = 0 :
+ * f(t) = M * F ^ (t / L)
+ *
+ * Because a line in the store needs to become irrelevant at some point but
+ * this class of functions never go to 0, a minimum cutoff has to be chosen to
+ * represent irrelevance. The simpler way of doing this is to simply add this
+ * minimum cutoff to the computation before and removing it after.
+ * Thus the function becomes :
+ * f(x, t) = ((x + K) * F ^ (t / L)) - K
+ * ...where K is the minimum cutoff, L the half-life, and F the factor between
+ * the original x and x after its half-life. Strictly speaking using the word
+ * "half-life" implies that F = 0.5, but the relation works for any value of F.
+ *
+ * It is easy enough to check that this function satisfies the stability
+ * relation that was given above for any value of F, L and K, which become
+ * parameters that can be defined at will.
+ *
+ * relevance
+ * 1.0 |
+ * |\
+ * | \
+ * | \ (this graph rendered with L = 75 days and K = 1/40)
+ * 0.75| ',
+ * | \
+ * | '.
+ * | \.
+ * | \
+ * 0.5 | '\
+ * | ''.
+ * | ''.
+ * | ''.
+ * 0.25| '''..
+ * | '''..
+ * | ''''....
+ * | '''''..........
+ * 0 +-------------------------------------------------------''''''''''----
+ * 0 50 100 150 200 250 300 350 400 days
+ *
+ *** Choosing the parameters
+ * The maximum M is an arbitrary parameter that simply scales the curve.
+ * The tradeoff for M is pretty simple : if the relevance is going to be an
+ * integer, the bigger M is the more precision there is in the relevance.
+ * However, values of M that are easy for humans to read are preferable to
+ * help debugging, and a suitably low value may be enough to ensure there
+ * won't be integer overflows in intermediate computations.
+ * A value of 1_000_000 probably is plenty for precision, while still in the
+ * low range of what ints can represent.
+ *
+ * F and L are parameters to be chosen arbitrarily and have an impact on how
+ * fast the relevance will be decaying at first, keeping in mind that
+ * the 400 days value and the cap stay the same. In simpler words, F and L
+ * define the steepness of the curve.
+ * To keep things simple (and familiar) F is arbitrarily chosen to be 0.5, and
+ * L is set to 200 days visually to achieve the desired effect. Refer to the
+ * illustration above to get a feel of how that feels.
+ *
+ * Moreover, the memory store works on an assumption that the relevance should
+ * be capped, and that an entry with capped relevance should decay in 400 days.
+ * This is on premises that the networks a device will need to remember the
+ * longest should be networks visited about once a year.
+ * For this reason, the relevance is at the maximum M 400 days before expiry :
+ * f(M, 400 days) = 0
+ * From replacing this with the value of the function, K can then be derived
+ * from the values of M, F and L :
+ * (M + K) * F ^ (t / L) - K = 0
+ * K = M * F ^ (400 days / L) / (1 - F ^ (400 days / L))
+ * Replacing with actual values this gives :
+ * K = 1_000_000 * 0.5 ^ (400 / 200) / (1 - 0.5 ^ (400 / 200))
+ * = 1_000_000 / 3 ≈ 333_333.3
+ * This ensures the function has the desired profile, the desired value at
+ * cap, and the desired value at expiry.
+ *
+ *** Useful relations
+ * Let's define the expiry time for any given relevance x as the interval of
+ * time such as :
+ * f(x, expiry) = 0
+ * which can be rewritten
+ * ((x + K) * F ^ (expiry / L)) = K
+ * ...giving an expression of the expiry in function of the relevance x as
+ * expiry = L * logF(K / (x + K))
+ * Conversely the relevance x can be expressed in function of the expiry as
+ * x = K / F ^ (expiry / L) - K
+ * These relations are useful in utility functions.
+ *
+ *** Bumping things up
+ * The last issue therefore is to decide how to bump up the relevance. The
+ * simple approach is to simply lift up the curve a little bit by a constant
+ * normalized amount, delaying the time of expiry. For example increasing
+ * the relevance by an amount I gives :
+ * x2 = x1 + I
+ * x2 and x1 correspond to two different expiry times expiry2 and expiry1,
+ * and replacing x1 and x2 in the relation above with their expression in
+ * function of the expiry comes :
+ * K / F ^ (expiry2 / L) - K = K / F ^ (expiry1 / L) - K + I
+ * which resolves to :
+ * expiry2 = L * logF(K / (I + K / F ^ (expiry1 / L)))
+ *
+ * In this implementation, the bump is defined as 1/25th of the cap for
+ * the relevance. This means a network will be remembered for the maximum
+ * period of 400 days if connected 25 times in succession not accounting
+ * for decay. Of course decay actually happens so it will take more than 25
+ * connections for any given network to actually reach the cap, but because
+ * decay is slow at first, it is a good estimate of how fast cap happens.
+ *
+ * Specifically, it gives the following four results :
+ * - A network that a device connects to once hits irrelevance about 32.7 days after
+ * it was first registered if never connected again.
+ * - A network that a device connects to once a day at a fixed hour will hit the cap
+ * on the 27th connection.
+ * - A network that a device connects to once a week at a fixed hour will hit the cap
+ * on the 57th connection.
+ * - A network that a device connects to every day for 7 straight days then never again
+ * expires 144 days after the last connection.
+ * These metrics tend to match pretty well the requirements.
+ */
+
+ // TODO : make these constants configurable at runtime. Don't forget to build it so that
+ // changes will wipe the database, migrate the values, or otherwise make sure the relevance
+ // values are still meaningful.
+
+ // How long, in milliseconds, is a capped relevance valid for, or in other
+ // words how many milliseconds after its relevance was set to RELEVANCE_CAP does
+ // any given line expire. 400 days.
+ @VisibleForTesting
+ public static final long CAPPED_RELEVANCE_LIFETIME_MS = 400L * 24 * 60 * 60 * 1000;
+
+ // The constant that represents a normalized 1.0 value for the relevance. In other words,
+ // the cap for the relevance. This is referred to as M in the explanation above.
+ @VisibleForTesting
+ public static final int CAPPED_RELEVANCE = 1_000_000;
+
+ // The decay factor. After a half-life, the relevance will have decayed by this value.
+ // This is referred to as F in the explanation above.
+ private static final double DECAY_FACTOR = 0.5;
+
+ // The half-life. After this time, the relevance will have decayed by a factor DECAY_FACTOR.
+ // This is referred to as L in the explanation above.
+ private static final long HALF_LIFE_MS = 200L * 24 * 60 * 60 * 1000;
+
+ // The value of the frame change. This is referred to as K in the explanation above.
+ private static final double IRRELEVANCE_FLOOR =
+ CAPPED_RELEVANCE * powF((double) CAPPED_RELEVANCE_LIFETIME_MS / HALF_LIFE_MS)
+ / (1 - powF((double) CAPPED_RELEVANCE_LIFETIME_MS / HALF_LIFE_MS));
+
+ // How much to bump the relevance by every time a line is written to.
+ @VisibleForTesting
+ public static final int RELEVANCE_BUMP = CAPPED_RELEVANCE / 25;
+
+ // Java doesn't include a function for the logarithm in an arbitrary base, so implement it
+ private static final double LOG_DECAY_FACTOR = Math.log(DECAY_FACTOR);
+ private static double logF(final double value) {
+ return Math.log(value) / LOG_DECAY_FACTOR;
+ }
+
+ // Utility function to get a power of the decay factor, to simplify the code.
+ private static double powF(final double value) {
+ return Math.pow(DECAY_FACTOR, value);
+ }
+
+ /**
+ * Compute the value of the relevance now given an expiry date.
+ *
+ * @param expiry the date at which the column in the database expires.
+ * @return the adjusted value of the relevance for this moment in time.
+ */
+ public static int computeRelevanceForNow(final long expiry) {
+ return computeRelevanceForTargetDate(expiry, System.currentTimeMillis());
+ }
+
+ /**
+ * Compute the value of the relevance at a given date from an expiry date.
+ *
+ * Because relevance decays with time, a relevance in the past corresponds to
+ * a different relevance later.
+ *
+ * Relevance is always a positive value. 0 means not relevant at all.
+ *
+ * See the explanation at the top of this file to get the justification for this
+ * computation.
+ *
+ * @param expiry the date at which the column in the database expires.
+ * @param target the target date to adjust the relevance to.
+ * @return the adjusted value of the relevance for the target moment.
+ */
+ public static int computeRelevanceForTargetDate(final long expiry, final long target) {
+ final long delay = expiry - target;
+ if (delay >= CAPPED_RELEVANCE_LIFETIME_MS) return CAPPED_RELEVANCE;
+ if (delay <= 0) return 0;
+ return (int) (IRRELEVANCE_FLOOR / powF((float) delay / HALF_LIFE_MS) - IRRELEVANCE_FLOOR);
+ }
+
+ /**
+ * Compute the expiry duration adjusted up for a new fresh write.
+ *
+ * Every time data is written to the memory store for a given line, the
+ * relevance is bumped up by a certain amount, which will boost the priority
+ * of this line for computation of group attributes, and delay (possibly
+ * indefinitely, if the line is accessed regularly) forgetting the data stored
+ * in that line.
+ * As opposed to bumpExpiryDate, this function uses a duration from now to expiry.
+ *
+ * See the explanation at the top of this file for a justification of this computation.
+ *
+ * @param oldExpiryDuration the old expiry duration in milliseconds from now.
+ * @return the expiry duration representing a bumped up relevance value.
+ */
+ public static long bumpExpiryDuration(final long oldExpiryDuration) {
+ // L * logF(K / (I + K / F ^ (expiry1 / L))), as documented above
+ final double divisionFactor = powF(((double) oldExpiryDuration) / HALF_LIFE_MS);
+ final double oldRelevance = IRRELEVANCE_FLOOR / divisionFactor;
+ final long newDuration =
+ (long) (HALF_LIFE_MS * logF(IRRELEVANCE_FLOOR / (RELEVANCE_BUMP + oldRelevance)));
+ return Math.min(newDuration, CAPPED_RELEVANCE_LIFETIME_MS);
+ }
+
+ /**
+ * Compute the new expiry date adjusted up for a new fresh write.
+ *
+ * Every time data is written to the memory store for a given line, the
+ * relevance is bumped up by a certain amount, which will boost the priority
+ * of this line for computation of group attributes, and delay (possibly
+ * indefinitely, if the line is accessed regularly) forgetting the data stored
+ * in that line.
+ * As opposed to bumpExpiryDuration, this function takes the old timestamp and returns the
+ * new timestamp.
+ *
+ * {@see bumpExpiryDuration}, and keep in mind that the bump depends on when this is called,
+ * because the relevance decays exponentially, therefore bumping up a high relevance (for a
+ * date far in the future) is less potent than bumping up a low relevance (for a date in
+ * a close future).
+ *
+ * @param oldExpiryDate the old date of expiration.
+ * @return the new expiration date after the relevance bump.
+ */
+ public static long bumpExpiryDate(final long oldExpiryDate) {
+ final long now = System.currentTimeMillis();
+ final long newDuration = bumpExpiryDuration(oldExpiryDate - now);
+ return now + newDuration;
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
index c8e6782..4a48468 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
@@ -85,6 +85,7 @@
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -793,6 +794,7 @@
}
@Test
+ @FlakyTest(bugId = 114098433)
public void testAllListeners() throws Exception {
final AppStateTrackerTestable instance = newInstance();
callStart(instance);
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index aa93c6b..7ea61e3 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -1760,8 +1760,8 @@
mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(),
USB_GADGET_HAL_DEATH_COOKIE);
mCurrentFunctions = UsbManager.FUNCTION_NONE;
- mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback());
mCurrentUsbFunctionsRequested = true;
+ mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback());
}
String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
updateState(state);
diff --git a/startop/view_compiler/Android.bp b/startop/view_compiler/Android.bp
index 2fc3a0d..7dc83c3 100644
--- a/startop/view_compiler/Android.bp
+++ b/startop/view_compiler/Android.bp
@@ -46,7 +46,7 @@
},
}
-cc_library_host_static {
+cc_library_static {
name: "libviewcompiler",
defaults: ["viewcompiler_defaults"],
srcs: [
@@ -58,9 +58,10 @@
"util.cc",
"layout_validation.cc",
],
+ host_supported: true,
}
-cc_binary_host {
+cc_binary {
name: "viewcompiler",
defaults: ["viewcompiler_defaults"],
srcs: [
@@ -70,6 +71,7 @@
"libgflags",
"libviewcompiler",
],
+ host_supported: true
}
cc_test_host {
diff --git a/startop/view_compiler/apk_layout_compiler.cc b/startop/view_compiler/apk_layout_compiler.cc
index e95041b..09cdbd5 100644
--- a/startop/view_compiler/apk_layout_compiler.cc
+++ b/startop/view_compiler/apk_layout_compiler.cc
@@ -79,9 +79,9 @@
return visitor.can_compile();
}
-void CompileApkLayouts(const std::string& filename, CompilationTarget target,
- std::ostream& target_out) {
- auto assets = android::ApkAssets::Load(filename);
+namespace {
+void CompileApkAssetsLayouts(const std::unique_ptr<const android::ApkAssets>& assets,
+ CompilationTarget target, std::ostream& target_out) {
android::AssetManager2 resources;
resources.SetApkAssets({assets.get()});
@@ -155,5 +155,20 @@
target_out.write(image.ptr<const char>(), image.size());
}
}
+} // namespace
+
+void CompileApkLayouts(const std::string& filename, CompilationTarget target,
+ std::ostream& target_out) {
+ auto assets = android::ApkAssets::Load(filename);
+ CompileApkAssetsLayouts(assets, target, target_out);
+}
+
+void CompileApkLayoutsFd(android::base::unique_fd fd, CompilationTarget target,
+ std::ostream& target_out) {
+ constexpr const char* friendly_name{"viewcompiler assets"};
+ auto assets = android::ApkAssets::LoadFromFd(
+ std::move(fd), friendly_name, /*system=*/false, /*force_shared_lib=*/false);
+ CompileApkAssetsLayouts(assets, target, target_out);
+}
} // namespace startop
diff --git a/startop/view_compiler/apk_layout_compiler.h b/startop/view_compiler/apk_layout_compiler.h
index c85ddd6..03bd545 100644
--- a/startop/view_compiler/apk_layout_compiler.h
+++ b/startop/view_compiler/apk_layout_compiler.h
@@ -19,12 +19,16 @@
#include <string>
+#include "android-base/unique_fd.h"
+
namespace startop {
enum class CompilationTarget { kJavaLanguage, kDex };
void CompileApkLayouts(const std::string& filename, CompilationTarget target,
std::ostream& target_out);
+void CompileApkLayoutsFd(android::base::unique_fd fd, CompilationTarget target,
+ std::ostream& target_out);
} // namespace startop
diff --git a/startop/view_compiler/main.cc b/startop/view_compiler/main.cc
index 871a421..11ecde2 100644
--- a/startop/view_compiler/main.cc
+++ b/startop/view_compiler/main.cc
@@ -49,6 +49,7 @@
DEFINE_bool(apk, false, "Compile layouts in an APK");
DEFINE_bool(dex, false, "Generate a DEX file instead of Java");
+DEFINE_int32(infd, -1, "Read input from the given file descriptor");
DEFINE_string(out, kStdoutFilename, "Where to write the generated class");
DEFINE_string(package, "", "The package name for the generated class (required)");
@@ -95,7 +96,7 @@
int main(int argc, char** argv) {
constexpr size_t kProgramName = 0;
constexpr size_t kFileNameParam = 1;
- constexpr size_t kNumRequiredArgs = 2;
+ constexpr size_t kNumRequiredArgs = 1;
gflags::SetUsageMessage(
"Compile XML layout files into equivalent Java language code\n"
@@ -104,12 +105,11 @@
gflags::ParseCommandLineFlags(&argc, &argv, /*remove_flags*/ true);
gflags::CommandLineFlagInfo cmd = gflags::GetCommandLineFlagInfoOrDie("package");
- if (argc != kNumRequiredArgs || cmd.is_default) {
+ if (argc < kNumRequiredArgs || cmd.is_default) {
gflags::ShowUsageWithFlags(argv[kProgramName]);
return 1;
}
- const char* const filename = argv[kFileNameParam];
const bool is_stdout = FLAGS_out == kStdoutFilename;
std::ofstream outfile;
@@ -118,13 +118,23 @@
}
if (FLAGS_apk) {
- startop::CompileApkLayouts(
- filename,
- FLAGS_dex ? startop::CompilationTarget::kDex : startop::CompilationTarget::kJavaLanguage,
- is_stdout ? std::cout : outfile);
+ const startop::CompilationTarget target =
+ FLAGS_dex ? startop::CompilationTarget::kDex : startop::CompilationTarget::kJavaLanguage;
+ if (FLAGS_infd >= 0) {
+ startop::CompileApkLayoutsFd(
+ android::base::unique_fd{FLAGS_infd}, target, is_stdout ? std::cout : outfile);
+ } else {
+ if (argc < 2) {
+ gflags::ShowUsageWithFlags(argv[kProgramName]);
+ return 1;
+ }
+ const char* const filename = argv[kFileNameParam];
+ startop::CompileApkLayouts(filename, target, is_stdout ? std::cout : outfile);
+ }
return 0;
}
+ const char* const filename = argv[kFileNameParam];
const string layout_name = startop::util::FindLayoutNameFromFilename(filename);
XMLDocument xml;
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 36d0188..2820836 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -518,6 +518,7 @@
private final Bundle mExtras;
private final Bundle mIntentExtras;
private final long mCreationTimeMillis;
+ private final CallIdentification mCallIdentification;
/**
* Whether the supplied capabilities supports the specified capability.
@@ -699,6 +700,12 @@
}
/**
+ * The display name for the caller.
+ * <p>
+ * This is the name as reported by the {@link ConnectionService} associated with this call.
+ * The name reported by a {@link CallScreeningService} can be retrieved using
+ * {@link CallIdentification#getName()}.
+ *
* @return The display name for the caller.
*/
public String getCallerDisplayName() {
@@ -814,6 +821,23 @@
return mCreationTimeMillis;
}
+ /**
+ * Returns {@link CallIdentification} information provided by a
+ * {@link CallScreeningService} for this call.
+ * <p>
+ * {@link InCallService} implementations should display the {@link CallIdentification} for
+ * calls. The name of the call screening service is provided in
+ * {@link CallIdentification#getCallScreeningAppName()} and should be used to attribute the
+ * call identification information.
+ *
+ * @return The {@link CallIdentification} if it was provided by a
+ * {@link CallScreeningService}, or {@code null} if no {@link CallScreeningService} has
+ * provided {@link CallIdentification} information for the call.
+ */
+ public @Nullable CallIdentification getCallIdentification() {
+ return mCallIdentification;
+ }
+
@Override
public boolean equals(Object o) {
if (o instanceof Details) {
@@ -834,7 +858,8 @@
Objects.equals(mStatusHints, d.mStatusHints) &&
areBundlesEqual(mExtras, d.mExtras) &&
areBundlesEqual(mIntentExtras, d.mIntentExtras) &&
- Objects.equals(mCreationTimeMillis, d.mCreationTimeMillis);
+ Objects.equals(mCreationTimeMillis, d.mCreationTimeMillis) &&
+ Objects.equals(mCallIdentification, d.mCallIdentification);
}
return false;
}
@@ -855,7 +880,8 @@
mStatusHints,
mExtras,
mIntentExtras,
- mCreationTimeMillis);
+ mCreationTimeMillis,
+ mCallIdentification);
}
/** {@hide} */
@@ -875,7 +901,8 @@
StatusHints statusHints,
Bundle extras,
Bundle intentExtras,
- long creationTimeMillis) {
+ long creationTimeMillis,
+ CallIdentification callIdentification) {
mTelecomCallId = telecomCallId;
mHandle = handle;
mHandlePresentation = handlePresentation;
@@ -892,6 +919,7 @@
mExtras = extras;
mIntentExtras = intentExtras;
mCreationTimeMillis = creationTimeMillis;
+ mCallIdentification = callIdentification;
}
/** {@hide} */
@@ -912,7 +940,8 @@
parcelableCall.getStatusHints(),
parcelableCall.getExtras(),
parcelableCall.getIntentExtras(),
- parcelableCall.getCreationTimeMillis());
+ parcelableCall.getCreationTimeMillis(),
+ parcelableCall.getCallIdentification());
}
@Override
diff --git a/telecomm/java/android/telecom/CallIdentification.aidl b/telecomm/java/android/telecom/CallIdentification.aidl
new file mode 100644
index 0000000..532535c
--- /dev/null
+++ b/telecomm/java/android/telecom/CallIdentification.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.telecom;
+
+/**
+ * {@hide}
+ */
+parcelable CallIdentification;
diff --git a/telecomm/java/android/telecom/CallIdentification.java b/telecomm/java/android/telecom/CallIdentification.java
new file mode 100644
index 0000000..97af06c
--- /dev/null
+++ b/telecomm/java/android/telecom/CallIdentification.java
@@ -0,0 +1,433 @@
+/*
+ * 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 android.telecom;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.pm.ApplicationInfo;
+import android.graphics.drawable.Icon;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Encapsulates information about an incoming or outgoing {@link Call} provided by a
+ * {@link CallScreeningService}.
+ * <p>
+ * Call identified information is consumed by the {@link InCallService dialer} app to provide the
+ * user with more information about a call. This can include information such as the name of the
+ * caller, address, etc. Call identification information is persisted to the
+ * {@link android.provider.CallLog}.
+ */
+public final class CallIdentification implements Parcelable {
+ /**
+ * Builder for {@link CallIdentification} instances.
+ * <p>
+ * A {@link CallScreeningService} uses this class to create new instances of
+ * {@link CallIdentification} for a screened call.
+ */
+ public static class Builder {
+ private String mName;
+ private String mDescription;
+ private String mDetails;
+ private Icon mPhoto;
+ private int mNuisanceConfidence = CallIdentification.CONFIDENCE_UNKNOWN;
+ private String mPackageName;
+ private String mAppName;
+
+ /**
+ * Default builder constructor.
+ */
+ public Builder() {
+ // Default constructor
+ }
+
+ /**
+ * Create instance of call identification with specified package/app name.
+ *
+ * @param callIdPackageName The package name.
+ * @param callIdAppName The app name.
+ * @hide
+ */
+ public Builder(String callIdPackageName, String callIdAppName) {
+ mPackageName = callIdPackageName;
+ mAppName = callIdAppName;
+ }
+
+ /**
+ * Sets the name associated with the {@link CallIdentification} being built.
+ * <p>
+ * Could be a business name, for example.
+ *
+ * @param name The name associated with the call, or {@code null} if none is provided.
+ * @return Builder instance.
+ */
+ public Builder setName(@Nullable String name) {
+ mName = name;
+ return this;
+ }
+
+ /**
+ * Sets the description associated with the {@link CallIdentification} being built.
+ * <p>
+ * A description of the call as identified by a {@link CallScreeningService}. The
+ * description is typically presented by Dialer apps after the
+ * {@link CallIdentification#getName() name} to provide a short piece of relevant
+ * information about the call. This could include a location, address, or a message
+ * regarding the potential nature of the call (e.g. potential telemarketer).
+ *
+ * @param description The call description, or {@code null} if none is provided.
+ * @return Builder instance.
+ */
+ public Builder setDescription(@Nullable String description) {
+ mDescription = description;
+ return this;
+ }
+
+ /**
+ * Sets the details associated with the {@link CallIdentification} being built.
+ * <p>
+ * The details is typically presented by Dialer apps after the
+ * {@link CallIdentification#getName() name} and
+ * {@link CallIdentification#getDescription() description} to provide further clarifying
+ * information about the call. This could include, for example, the opening hours of a
+ * business, or a stats about the number of times a call has been reported as spam.
+ *
+ * @param details The call details, or {@code null} if none is provided.
+ * @return Builder instance.
+ */
+ public Builder setDetails(@Nullable String details) {
+ mDetails = details;
+ return this;
+ }
+
+ /**
+ * Sets the photo associated with the {@link CallIdentification} being built.
+ * <p>
+ * This could be, for example, a business logo, or a photo of the caller.
+ *
+ * @param photo The photo associated with the call, or {@code null} if none was provided.
+ * @return Builder instance.
+ */
+ public Builder setPhoto(@Nullable Icon photo) {
+ mPhoto = photo;
+ return this;
+ }
+
+ /**
+ * Sets the nuisance confidence with the {@link CallIdentification} being built.
+ * <p>
+ * This can be used to specify how confident the {@link CallScreeningService} is that a call
+ * is or is not a nuisance call.
+ *
+ * @param nuisanceConfidence The nuisance confidence.
+ * @return The builder.
+ */
+ public Builder setNuisanceConfidence(@NuisanceConfidence int nuisanceConfidence) {
+ mNuisanceConfidence = nuisanceConfidence;
+ return this;
+ }
+
+ /**
+ * Creates a new instance of {@link CallIdentification} based on the parameters set in this
+ * builder.
+ *
+ * @return {@link CallIdentification} instance.
+ */
+ public CallIdentification build() {
+ return new CallIdentification(mName, mDescription, mDetails, mPhoto,
+ mNuisanceConfidence, mPackageName, mAppName);
+ }
+ }
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ prefix = { "CONFIDENCE_" },
+ value = {CONFIDENCE_NUISANCE, CONFIDENCE_LIKELY_NUISANCE, CONFIDENCE_UNKNOWN,
+ CONFIDENCE_LIKELY_NOT_NUISANCE, CONFIDENCE_NOT_NUISANCE})
+ public @interface NuisanceConfidence {}
+
+ /**
+ * Call has been identified as a nuisance call.
+ * <p>
+ * Returned from {@link #getNuisanceConfidence()} to indicate that a
+ * {@link CallScreeningService} to indicate how confident it is that a call is or is not a
+ * nuisance call.
+ */
+ public static final int CONFIDENCE_NUISANCE = 2;
+
+ /**
+ * Call has been identified as a likely nuisance call.
+ * <p>
+ * Returned from {@link #getNuisanceConfidence()} to indicate that a
+ * {@link CallScreeningService} to indicate how confident it is that a call is or is not a
+ * nuisance call.
+ */
+ public static final int CONFIDENCE_LIKELY_NUISANCE = 1;
+
+ /**
+ * Call could not be classified as nuisance or non-nuisance.
+ * <p>
+ * Returned from {@link #getNuisanceConfidence()} to indicate that a
+ * {@link CallScreeningService} to indicate how confident it is that a call is or is not a
+ * nuisance call.
+ */
+ public static final int CONFIDENCE_UNKNOWN = 0;
+
+ /**
+ * Call has been identified as not likely to be a nuisance call.
+ * <p>
+ * Returned from {@link #getNuisanceConfidence()} to indicate that a
+ * {@link CallScreeningService} to indicate how confident it is that a call is or is not a
+ * nuisance call.
+ */
+ public static final int CONFIDENCE_LIKELY_NOT_NUISANCE = -1;
+
+ /**
+ * Call has been identified as not a nuisance call.
+ * <p>
+ * Returned from {@link #getNuisanceConfidence()} to indicate that a
+ * {@link CallScreeningService} to indicate how confident it is that a call is or is not a
+ * nuisance call.
+ */
+ public static final int CONFIDENCE_NOT_NUISANCE = -2;
+
+ /**
+ * Default constructor for {@link CallIdentification}.
+ *
+ * @param name The name.
+ * @param description The description.
+ * @param details The details.
+ * @param photo The photo.
+ * @param nuisanceConfidence Confidence that this is a nuisance call.
+ * @hide
+ */
+ private CallIdentification(@Nullable String name, @Nullable String description,
+ @Nullable String details, @Nullable Icon photo,
+ @NuisanceConfidence int nuisanceConfidence) {
+ this(name, description, details, photo, nuisanceConfidence, null, null);
+ }
+
+ /**
+ * Default constructor for {@link CallIdentification}.
+ *
+ * @param name The name.
+ * @param description The description.
+ * @param details The details.
+ * @param photo The photo.
+ * @param nuisanceConfidence Confidence that this is a nuisance call.
+ * @param callScreeningPackageName Package name of the {@link CallScreeningService} which
+ * provided the call identification.
+ * @param callScreeningAppName App name of the {@link CallScreeningService} which provided the
+ * call identification.
+ * @hide
+ */
+ private CallIdentification(@Nullable String name, @Nullable String description,
+ @Nullable String details, @Nullable Icon photo,
+ @NuisanceConfidence int nuisanceConfidence, @NonNull String callScreeningPackageName,
+ @NonNull String callScreeningAppName) {
+ mName = name;
+ mDescription = description;
+ mDetails = details;
+ mPhoto = photo;
+ mNuisanceConfidence = nuisanceConfidence;
+ mCallScreeningAppName = callScreeningPackageName;
+ mCallScreeningPackageName = callScreeningAppName;
+ }
+
+ private String mName;
+ private String mDescription;
+ private String mDetails;
+ private Icon mPhoto;
+ private int mNuisanceConfidence;
+ private String mCallScreeningPackageName;
+ private String mCallScreeningAppName;
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int i) {
+ parcel.writeString(mName);
+ parcel.writeString(mDescription);
+ parcel.writeString(mDetails);
+ parcel.writeParcelable(mPhoto, 0);
+ parcel.writeInt(mNuisanceConfidence);
+ parcel.writeString(mCallScreeningPackageName);
+ parcel.writeString(mCallScreeningAppName);
+ }
+
+ /**
+ * Responsible for creating CallIdentification objects for deserialized Parcels.
+ */
+ public static final Parcelable.Creator<CallIdentification> CREATOR =
+ new Parcelable.Creator<CallIdentification> () {
+
+ @Override
+ public CallIdentification createFromParcel(Parcel source) {
+ String name = source.readString();
+ String description = source.readString();
+ String details = source.readString();
+ Icon photo = source.readParcelable(ClassLoader.getSystemClassLoader());
+ int nuisanceConfidence = source.readInt();
+ String callScreeningPackageName = source.readString();
+ String callScreeningAppName = source.readString();
+ return new CallIdentification(name, description, details, photo,
+ nuisanceConfidence, callScreeningPackageName, callScreeningAppName);
+ }
+
+ @Override
+ public CallIdentification[] newArray(int size) {
+ return new CallIdentification[size];
+ }
+ };
+
+ /**
+ * The name associated with the number.
+ * <p>
+ * The name of the call as identified by a {@link CallScreeningService}. Could be a business
+ * name, for example.
+ *
+ * @return The name associated with the number, or {@code null} if none was provided.
+ */
+ public final @Nullable String getName() {
+ return mName;
+ }
+
+ /**
+ * Description of the call.
+ * <p>
+ * A description of the call as identified by a {@link CallScreeningService}. The description
+ * is typically presented by Dialer apps after the {@link #getName() name} to provide a short
+ * piece of relevant information about the call. This could include a location, address, or a
+ * message regarding the potential nature of the call (e.g. potential telemarketer).
+ *
+ * @return The call description, or {@code null} if none was provided.
+ */
+ public final @Nullable String getDescription() {
+ return mDescription;
+ }
+
+ /**
+ * Details of the call.
+ * <p>
+ * Details of the call as identified by a {@link CallScreeningService}. The details
+ * are typically presented by Dialer apps after the {@link #getName() name} and
+ * {@link #getDescription() description} to provide further clarifying information about the
+ * call. This could include, for example, the opening hours of a business, or stats about
+ * the number of times a call has been reported as spam.
+ *
+ * @return The call details, or {@code null} if none was provided.
+ */
+ public final @Nullable String getDetails() {
+ return mDetails;
+ }
+
+ /**
+ * Photo associated with the call.
+ * <p>
+ * A photo associated with the call as identified by a {@link CallScreeningService}. This
+ * could be, for example, a business logo, or a photo of the caller.
+ *
+ * @return The photo associated with the call, or {@code null} if none was provided.
+ */
+ public final @Nullable Icon getPhoto() {
+ return mPhoto;
+ }
+
+ /**
+ * Indicates the likelihood that this call is a nuisance call.
+ * <p>
+ * How likely the call is a nuisance call, as identified by a {@link CallScreeningService}.
+ *
+ * @return The nuisance confidence.
+ */
+ public final @NuisanceConfidence
+ int getNuisanceConfidence() {
+ return mNuisanceConfidence;
+ }
+
+ /**
+ * The package name of the {@link CallScreeningService} which provided the
+ * {@link CallIdentification}.
+ * <p>
+ * A {@link CallScreeningService} may not set this property; it is set by the system.
+ * @return the package name
+ */
+ public final @NonNull String getCallScreeningPackageName() {
+ return mCallScreeningPackageName;
+ }
+
+ /**
+ * The {@link android.content.pm.PackageManager#getApplicationLabel(ApplicationInfo) name} of
+ * the {@link CallScreeningService} which provided the {@link CallIdentification}.
+ * <p>
+ * A {@link CallScreeningService} may not set this property; it is set by the system.
+ *
+ * @return The name of the app.
+ */
+ public final @NonNull String getCallScreeningAppName() {
+ return mCallScreeningAppName;
+ }
+
+ /**
+ * Set the package name of the {@link CallScreeningService} which provided this information.
+ *
+ * @param callScreeningPackageName The package name.
+ * @hide
+ */
+ public void setCallScreeningPackageName(@NonNull String callScreeningPackageName) {
+ mCallScreeningPackageName = callScreeningPackageName;
+ }
+
+ /**
+ * Set the app name of the {@link CallScreeningService} which provided this information.
+ *
+ * @param callScreeningAppName The app name.
+ * @hide
+ */
+ public void setCallScreeningAppName(@NonNull String callScreeningAppName) {
+ mCallScreeningAppName = callScreeningAppName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ CallIdentification that = (CallIdentification) o;
+ // Note: mPhoto purposely omit as no good comparison exists.
+ return mNuisanceConfidence == that.mNuisanceConfidence
+ && Objects.equals(mName, that.mName)
+ && Objects.equals(mDescription, that.mDescription)
+ && Objects.equals(mDetails, that.mDetails)
+ && Objects.equals(mCallScreeningAppName, that.mCallScreeningAppName)
+ && Objects.equals(mCallScreeningPackageName, that.mCallScreeningPackageName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mName, mDescription, mDetails, mPhoto, mNuisanceConfidence,
+ mCallScreeningAppName, mCallScreeningPackageName);
+ }
+}
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index 6628743..be96b3c 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -16,6 +16,7 @@
package android.telecom;
+import android.annotation.NonNull;
import android.annotation.SdkConstant;
import android.app.Service;
import android.content.ComponentName;
@@ -46,6 +47,15 @@
* </service>
* }
* </pre>
+ * <p>
+ * A CallScreeningService performs two functions:
+ * <ol>
+ * <li>Call blocking/screening - the service can choose which calls will ring on the user's
+ * device, and which will be silently sent to voicemail.</li>
+ * <li>Call identification - the service can optionally provide {@link CallIdentification}
+ * information about a {@link Call.Details call} which will be shown to the user in the
+ * Dialer app.</li>
+ * </ol>
*/
public abstract class CallScreeningService extends Service {
/**
@@ -229,16 +239,23 @@
*
* @param callDetails Information about a new incoming call, see {@link Call.Details}.
*/
- public abstract void onScreenCall(Call.Details callDetails);
+ public abstract void onScreenCall(@NonNull Call.Details callDetails);
/**
* Responds to the given call, either allowing it or disallowing it.
+ * <p>
+ * The {@link CallScreeningService} calls this method to inform the system whether the call
+ * should be silently blocked or not.
*
* @param callDetails The call to allow.
+ * <p>
+ * Must be the same {@link Call.Details call} which was provided to the
+ * {@link CallScreeningService} via {@link #onScreenCall(Call.Details)}.
* @param response The {@link CallScreeningService.CallResponse} which contains information
* about how to respond to a call.
*/
- public final void respondToCall(Call.Details callDetails, CallResponse response) {
+ public final void respondToCall(@NonNull Call.Details callDetails,
+ @NonNull CallResponse response) {
try {
if (response.getDisallowCall()) {
mCallScreeningAdapter.disallowCall(
@@ -253,4 +270,32 @@
} catch (RemoteException e) {
}
}
+
+ /**
+ * Provide {@link CallIdentification} information about a {@link Call.Details call}.
+ * <p>
+ * The {@link CallScreeningService} calls this method to provide information it has identified
+ * about a {@link Call.Details call}. This information will potentially be shown to the user
+ * in the {@link InCallService dialer} app. It will be logged to the
+ * {@link android.provider.CallLog}.
+ * <p>
+ * A {@link CallScreeningService} should only call this method for calls for which it is able to
+ * provide some {@link CallIdentification} for. {@link CallIdentification} instances with no
+ * fields set will be ignored by the system.
+ *
+ * @param callDetails The call to provide information for.
+ * <p>
+ * Must be the same {@link Call.Details call} which was provided to the
+ * {@link CallScreeningService} via {@link #onScreenCall(Call.Details)}.
+ * @param identification An instance of {@link CallIdentification} with information about the
+ * {@link Call.Details call}.
+ */
+ public final void provideCallIdentification(@NonNull Call.Details callDetails,
+ @NonNull CallIdentification identification) {
+ try {
+ mCallScreeningAdapter.provideCallIdentification(callDetails.getTelecomCallId(),
+ identification);
+ } catch (RemoteException e) {
+ }
+ }
}
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 8425603..05d5a13 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -505,6 +505,14 @@
"android.telecom.extra.ORIGINAL_CONNECTION_ID";
/**
+ * Boolean connection extra key set on the extras passed to
+ * {@link Connection#sendConnectionEvent} which indicates that audio is present
+ * on the RTT call when the extra value is true.
+ */
+ public static final String EXTRA_IS_RTT_AUDIO_PRESENT =
+ "android.telecom.extra.IS_RTT_AUDIO_PRESENT";
+
+ /**
* Connection event used to inform Telecom that it should play the on hold tone. This is used
* to play a tone when the peer puts the current call on hold. Sent to Telecom via
* {@link #sendConnectionEvent(String, Bundle)}.
@@ -619,6 +627,13 @@
*/
public static final String EXTRA_SIP_INVITE = "android.telecom.extra.SIP_INVITE";
+ /**
+ * Connection event used to inform an {@link InCallService} that the RTT audio indication
+ * has changed.
+ */
+ public static final String EVENT_RTT_AUDIO_INDICATION_CHANGED =
+ "android.telecom.event.RTT_AUDIO_INDICATION_CHANGED";
+
// Flag controlling whether PII is emitted into the logs
private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index 3ad0f0c..911786e 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -16,6 +16,7 @@
package android.telecom;
+import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.net.Uri;
import android.os.Build;
@@ -62,6 +63,7 @@
private final Bundle mIntentExtras;
private final Bundle mExtras;
private final long mCreationTimeMillis;
+ private final CallIdentification mCallIdentification;
public ParcelableCall(
String id,
@@ -89,7 +91,8 @@
List<String> conferenceableCallIds,
Bundle intentExtras,
Bundle extras,
- long creationTimeMillis) {
+ long creationTimeMillis,
+ CallIdentification callIdentification) {
mId = id;
mState = state;
mDisconnectCause = disconnectCause;
@@ -116,6 +119,7 @@
mIntentExtras = intentExtras;
mExtras = extras;
mCreationTimeMillis = creationTimeMillis;
+ mCallIdentification = callIdentification;
}
/** The unique ID of the call. */
@@ -133,7 +137,7 @@
* Reason for disconnection, as described by {@link android.telecomm.DisconnectCause}. Valid
* when call state is {@link CallState#DISCONNECTED}.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public DisconnectCause getDisconnectCause() {
return mDisconnectCause;
}
@@ -159,13 +163,13 @@
}
/** The time that the call switched to the active state. */
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public long getConnectTimeMillis() {
return mConnectTimeMillis;
}
/** The endpoint to which the call is connected. */
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public Uri getHandle() {
return mHandle;
}
@@ -305,8 +309,17 @@
return mCreationTimeMillis;
}
+ /**
+ * Contains call identification information returned by a {@link CallScreeningService}.
+ * @return The {@link CallIdentification} for this call, or {@code null} if a
+ * {@link CallScreeningService} did not provide information.
+ */
+ public @Nullable CallIdentification getCallIdentification() {
+ return mCallIdentification;
+ }
+
/** Responsible for creating ParcelableCall objects for deserialized Parcels. */
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public static final Parcelable.Creator<ParcelableCall> CREATOR =
new Parcelable.Creator<ParcelableCall> () {
@Override
@@ -342,6 +355,7 @@
boolean isRttCallChanged = source.readByte() == 1;
ParcelableRttCall rttCall = source.readParcelable(classLoader);
long creationTimeMillis = source.readLong();
+ CallIdentification callIdentification = source.readParcelable(classLoader);
return new ParcelableCall(
id,
state,
@@ -368,7 +382,8 @@
conferenceableCallIds,
intentExtras,
extras,
- creationTimeMillis);
+ creationTimeMillis,
+ callIdentification);
}
@Override
@@ -413,6 +428,7 @@
destination.writeByte((byte) (mIsRttCallChanged ? 1 : 0));
destination.writeParcelable(mRttCall, 0);
destination.writeLong(mCreationTimeMillis);
+ destination.writeParcelable(mCallIdentification, 0);
}
@Override
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index e7ce78a..6a61181 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -31,6 +31,7 @@
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -42,6 +43,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.Executor;
/**
* Provides access to information about active calls and registration/call-management functionality.
@@ -1184,8 +1186,10 @@
* Requires permission: {@link android.Manifest.permission#WRITE_SECURE_SETTINGS}
*
* @hide
+ * @deprecated Use RoleManager instead.
*/
@SystemApi
+ @Deprecated
@RequiresPermission(allOf = {
android.Manifest.permission.MODIFY_PHONE_STATE,
android.Manifest.permission.WRITE_SECURE_SETTINGS})
@@ -1217,79 +1221,6 @@
}
/**
- * Used to trigger display of the ChangeDefaultCallScreeningApp activity to prompt the user to
- * change the call screening app.
- *
- * A {@link SecurityException} will be thrown if calling package name doesn't match the package
- * of the passed {@link ComponentName}
- *
- * @param componentName to verify that the calling package name matches the package of the
- * passed ComponentName.
- */
- public void requestChangeDefaultCallScreeningApp(@NonNull ComponentName componentName) {
- try {
- if (isServiceConnected()) {
- getTelecomService().requestChangeDefaultCallScreeningApp(componentName, mContext
- .getOpPackageName());
- }
- } catch (RemoteException e) {
- Log.e(TAG,
- "RemoteException calling ITelecomService#requestChangeDefaultCallScreeningApp.",
- e);
- }
- }
-
- /**
- * Used to verify that the passed ComponentName is default call screening app.
- *
- * @param componentName to verify that the package of the passed ComponentName matched the default
- * call screening packageName.
- *
- * @return {@code true} if the passed componentName matches the default call screening's, {@code
- * false} if the passed componentName is null, or it doesn't match default call screening's.
- */
- public boolean isDefaultCallScreeningApp(ComponentName componentName) {
- try {
- if (isServiceConnected()) {
- return getTelecomService().isDefaultCallScreeningApp(componentName);
- }
- } catch (RemoteException e) {
- Log.e(TAG,
- "RemoteException calling ITelecomService#isDefaultCallScreeningApp.",
- e);
- }
- return false;
- }
-
- /**
- * Used to set the default call screening package.
- *
- * Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} Requires
- * permission: {@link android.Manifest.permission#WRITE_SECURE_SETTINGS}
- *
- * A {@link IllegalArgumentException} will be thrown if the specified package and component name
- * of {@link ComponentName} does't exist, or the specified component of {@link ComponentName}
- * does't have {@link android.Manifest.permission#BIND_SCREENING_SERVICE}.
- *
- * @param componentName to set the default call screening to.
- * @hide
- */
- @RequiresPermission(anyOf = {
- android.Manifest.permission.MODIFY_PHONE_STATE,
- android.Manifest.permission.WRITE_SECURE_SETTINGS
- })
- public void setDefaultCallScreeningApp(ComponentName componentName) {
- try {
- if (isServiceConnected()) {
- getTelecomService().setDefaultCallScreeningApp(componentName);
- }
- } catch (RemoteException e) {
- Log.e(TAG,
- "RemoteException calling ITelecomService#setDefaultCallScreeningApp.", e);
- }
- }
-
- /**
* Return whether a given phone number is the configured voicemail number for a
* particular phone account.
*
diff --git a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl
index d255ed1..a86c830 100644
--- a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl
@@ -17,6 +17,7 @@
package com.android.internal.telecom;
import android.content.ComponentName;
+import android.telecom.CallIdentification;
/**
* Internal remote callback interface for call screening services.
@@ -34,4 +35,8 @@
boolean shouldAddToCallLog,
boolean shouldShowNotification,
in ComponentName componentName);
+
+ void provideCallIdentification(
+ String callId,
+ in CallIdentification callIdentification);
}
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 6f1b66a..954a709 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -256,21 +256,6 @@
boolean setDefaultDialer(in String packageName);
/**
- * @see TelecomServiceImpl#requestChangeDefaultCallScreeningApp
- */
- void requestChangeDefaultCallScreeningApp(in ComponentName componentNamem, String callingPackage);
-
- /**
- * @see TelecomServiceImpl#isDefaultCallScreeningApp
- */
- boolean isDefaultCallScreeningApp(in ComponentName componentName);
-
- /**
- * @see TelecomServiceImpl#setDefaultCallScreeningApp
- */
- void setDefaultCallScreeningApp(in ComponentName componentName);
-
- /**
* @see TelecomServiceImpl#createManageBlockedNumbersIntent
**/
Intent createManageBlockedNumbersIntent();
diff --git a/telephony/java/android/telephony/AvailableNetworkInfo.java b/telephony/java/android/telephony/AvailableNetworkInfo.java
index fe07370..4da79b3 100644
--- a/telephony/java/android/telephony/AvailableNetworkInfo.java
+++ b/telephony/java/android/telephony/AvailableNetworkInfo.java
@@ -110,6 +110,7 @@
private AvailableNetworkInfo(Parcel in) {
mSubId = in.readInt();
mPriority = in.readInt();
+ mMccMncs = new ArrayList<>();
in.readStringList(mMccMncs);
}
diff --git a/telephony/java/android/telephony/CallAttributes.aidl b/telephony/java/android/telephony/CallAttributes.aidl
new file mode 100644
index 0000000..69127df
--- /dev/null
+++ b/telephony/java/android/telephony/CallAttributes.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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 android.telephony;
+
+parcelable CallAttributes;
+
diff --git a/telephony/java/android/telephony/CallAttributes.java b/telephony/java/android/telephony/CallAttributes.java
new file mode 100644
index 0000000..2b99ce1
--- /dev/null
+++ b/telephony/java/android/telephony/CallAttributes.java
@@ -0,0 +1,151 @@
+/*
+ * 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 android.telephony;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.TelephonyManager.NetworkType;
+
+import java.util.Objects;
+
+/**
+ * Contains information about a call's attributes as passed up from the HAL. If there are multiple
+ * ongoing calls, the CallAttributes will pertain to the call in the foreground.
+ * @hide
+ */
+@SystemApi
+public class CallAttributes implements Parcelable {
+ private PreciseCallState mPreciseCallState;
+ @NetworkType
+ private int mNetworkType; // TelephonyManager.NETWORK_TYPE_* ints
+ private CallQuality mCallQuality;
+
+
+ public CallAttributes(PreciseCallState state, @NetworkType int networkType,
+ CallQuality callQuality) {
+ this.mPreciseCallState = state;
+ this.mNetworkType = networkType;
+ this.mCallQuality = callQuality;
+ }
+
+ @Override
+ public String toString() {
+ return "mPreciseCallState=" + mPreciseCallState + " mNetworkType=" + mNetworkType
+ + " mCallQuality=" + mCallQuality;
+ }
+
+ private CallAttributes(Parcel in) {
+ mPreciseCallState = (PreciseCallState) in.readValue(mPreciseCallState.getClass()
+ .getClassLoader());
+ mNetworkType = in.readInt();
+ mCallQuality = (CallQuality) in.readValue(mCallQuality.getClass().getClassLoader());
+ }
+
+ // getters
+ /**
+ * Returns the {@link PreciseCallState} of the call.
+ */
+ public PreciseCallState getPreciseCallState() {
+ return mPreciseCallState;
+ }
+
+ /**
+ * Returns the {@link TelephonyManager#NetworkType} of the call.
+ *
+ * @see TelephonyManager#NETWORK_TYPE_UNKNOWN
+ * @see TelephonyManager#NETWORK_TYPE_GPRS
+ * @see TelephonyManager#NETWORK_TYPE_EDGE
+ * @see TelephonyManager#NETWORK_TYPE_UMTS
+ * @see TelephonyManager#NETWORK_TYPE_CDMA
+ * @see TelephonyManager#NETWORK_TYPE_EVDO_0
+ * @see TelephonyManager#NETWORK_TYPE_EVDO_A
+ * @see TelephonyManager#NETWORK_TYPE_1xRTT
+ * @see TelephonyManager#NETWORK_TYPE_HSDPA
+ * @see TelephonyManager#NETWORK_TYPE_HSUPA
+ * @see TelephonyManager#NETWORK_TYPE_HSPA
+ * @see TelephonyManager#NETWORK_TYPE_IDEN
+ * @see TelephonyManager#NETWORK_TYPE_EVDO_B
+ * @see TelephonyManager#NETWORK_TYPE_LTE
+ * @see TelephonyManager#NETWORK_TYPE_EHRPD
+ * @see TelephonyManager#NETWORK_TYPE_HSPAP
+ * @see TelephonyManager#NETWORK_TYPE_GSM
+ * @see TelephonyManager#NETWORK_TYPE_TD_SCDMA
+ * @see TelephonyManager#NETWORK_TYPE_IWLAN
+ * @see TelephonyManager#NETWORK_TYPE_LTE_CA
+ * @see TelephonyManager#NETWORK_TYPE_NR
+ */
+ @NetworkType
+ public int getNetworkType() {
+ return mNetworkType;
+ }
+
+ /**
+ * Returns the {#link CallQuality} of the call.
+ */
+ public CallQuality getCallQuality() {
+ return mCallQuality;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mPreciseCallState, mNetworkType, mCallQuality);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof CallAttributes) || hashCode() != o.hashCode()) {
+ return false;
+ }
+
+ if (this == o) {
+ return true;
+ }
+
+ CallAttributes s = (CallAttributes) o;
+
+ return (mPreciseCallState == s.mPreciseCallState
+ && mNetworkType == s.mNetworkType
+ && mCallQuality == s.mCallQuality);
+ }
+
+ /**
+ * {@link Parcelable#describeContents}
+ */
+ public @Parcelable.ContentsFlags int describeContents() {
+ return 0;
+ }
+
+ /**
+ * {@link Parcelable#writeToParcel}
+ */
+ public void writeToParcel(Parcel dest, @Parcelable.WriteFlags int flags) {
+ mPreciseCallState.writeToParcel(dest, flags);
+ dest.writeInt(mNetworkType);
+ mCallQuality.writeToParcel(dest, flags);
+ }
+
+ public static final Parcelable.Creator<CallAttributes> CREATOR = new Parcelable.Creator() {
+ public CallAttributes createFromParcel(Parcel in) {
+ return new CallAttributes(in);
+ }
+
+ public CallAttributes[] newArray(int size) {
+ return new CallAttributes[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/CallQuality.aidl b/telephony/java/android/telephony/CallQuality.aidl
new file mode 100644
index 0000000..f54355f
--- /dev/null
+++ b/telephony/java/android/telephony/CallQuality.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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 android.telephony;
+
+parcelable CallQuality;
+
diff --git a/telephony/java/android/telephony/CallQuality.java b/telephony/java/android/telephony/CallQuality.java
new file mode 100644
index 0000000..b27f6b4
--- /dev/null
+++ b/telephony/java/android/telephony/CallQuality.java
@@ -0,0 +1,341 @@
+/*
+ * 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 android.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Parcelable object to handle call quality.
+ * <p>
+ * Currently this supports IMS calls.
+ * <p>
+ * It provides the call quality level, duration, and additional information related to RTP packets,
+ * jitter and delay.
+ * <p>
+ * If there are multiple active calls, the CallQuality will pertain to the call in the foreground.
+ *
+ * @hide
+ */
+@SystemApi
+public final class CallQuality implements Parcelable {
+
+ // Constants representing the call quality level (see #CallQuality);
+ public static final int CALL_QUALITY_EXCELLENT = 0;
+ public static final int CALL_QUALITY_GOOD = 1;
+ public static final int CALL_QUALITY_FAIR = 2;
+ public static final int CALL_QUALITY_POOR = 3;
+ public static final int CALL_QUALITY_BAD = 4;
+ public static final int CALL_QUALITY_NOT_AVAILABLE = 5;
+
+ /**
+ * Call quality
+ * @hide
+ */
+ @IntDef(prefix = { "CALL_QUALITY_" }, value = {
+ CALL_QUALITY_EXCELLENT,
+ CALL_QUALITY_GOOD,
+ CALL_QUALITY_FAIR,
+ CALL_QUALITY_POOR,
+ CALL_QUALITY_BAD,
+ CALL_QUALITY_NOT_AVAILABLE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CallQualityLevel {}
+
+ @CallQualityLevel
+ private int mDownlinkCallQualityLevel;
+ @CallQualityLevel
+ private int mUplinkCallQualityLevel;
+ private int mCallDuration;
+ private int mNumRtpPacketsTransmitted;
+ private int mNumRtpPacketsReceived;
+ private int mNumRtpPacketsTransmittedLost;
+ private int mNumRtpPacketsNotReceived;
+ private int mAverageRelativeJitter;
+ private int mMaxRelativeJitter;
+ private int mAverageRoundTripTime;
+ private int mCodecType;
+
+ /** @hide **/
+ public CallQuality(Parcel in) {
+ mDownlinkCallQualityLevel = in.readInt();
+ mUplinkCallQualityLevel = in.readInt();
+ mCallDuration = in.readInt();
+ mNumRtpPacketsTransmitted = in.readInt();
+ mNumRtpPacketsReceived = in.readInt();
+ mNumRtpPacketsTransmittedLost = in.readInt();
+ mNumRtpPacketsNotReceived = in.readInt();
+ mAverageRelativeJitter = in.readInt();
+ mMaxRelativeJitter = in.readInt();
+ mAverageRoundTripTime = in.readInt();
+ mCodecType = in.readInt();
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param callQualityLevel the call quality level (see #CallQualityLevel)
+ * @param callDuration the call duration in milliseconds
+ * @param numRtpPacketsTransmitted RTP packets sent to network
+ * @param numRtpPacketsReceived RTP packets received from network
+ * @param numRtpPacketsTransmittedLost RTP packets which were lost in network and never
+ * transmitted
+ * @param numRtpPacketsNotReceived RTP packets which were lost in network and never recieved
+ * @param averageRelativeJitter average relative jitter in milliseconds
+ * @param maxRelativeJitter maximum relative jitter in milliseconds
+ * @param averageRoundTripTime average round trip delay in milliseconds
+ * @param codecType the codec type
+ */
+ public CallQuality(
+ @CallQualityLevel int downlinkCallQualityLevel,
+ @CallQualityLevel int uplinkCallQualityLevel,
+ int callDuration,
+ int numRtpPacketsTransmitted,
+ int numRtpPacketsReceived,
+ int numRtpPacketsTransmittedLost,
+ int numRtpPacketsNotReceived,
+ int averageRelativeJitter,
+ int maxRelativeJitter,
+ int averageRoundTripTime,
+ int codecType) {
+ this.mDownlinkCallQualityLevel = downlinkCallQualityLevel;
+ this.mUplinkCallQualityLevel = uplinkCallQualityLevel;
+ this.mCallDuration = callDuration;
+ this.mNumRtpPacketsTransmitted = numRtpPacketsTransmitted;
+ this.mNumRtpPacketsReceived = numRtpPacketsReceived;
+ this.mNumRtpPacketsTransmittedLost = numRtpPacketsTransmittedLost;
+ this.mNumRtpPacketsNotReceived = numRtpPacketsNotReceived;
+ this.mAverageRelativeJitter = averageRelativeJitter;
+ this.mMaxRelativeJitter = maxRelativeJitter;
+ this.mAverageRoundTripTime = averageRoundTripTime;
+ this.mCodecType = codecType;
+ }
+
+ // getters
+ /**
+ * Returns the downlink CallQualityLevel for a given ongoing call.
+ */
+ @CallQualityLevel
+ public int getDownlinkCallQualityLevel() {
+ return mDownlinkCallQualityLevel;
+ }
+
+ /**
+ * Returns the uplink CallQualityLevel for a given ongoing call.
+ */
+ @CallQualityLevel
+ public int getUplinkCallQualityLevel() {
+ return mUplinkCallQualityLevel;
+ }
+
+ /**
+ * Returns the duration of the call, in milliseconds.
+ */
+ public int getCallDuration() {
+ return mCallDuration;
+ }
+
+ /**
+ * Returns the total number of RTP packets transmitted by this device for a given ongoing call.
+ */
+ public int getNumRtpPacketsTransmitted() {
+ return mNumRtpPacketsTransmitted;
+ }
+
+ /**
+ * Returns the total number of RTP packets received by this device for a given ongoing call.
+ */
+ public int getNumRtpPacketsReceived() {
+ return mNumRtpPacketsReceived;
+ }
+
+ /**
+ * Returns the number of RTP packets which were sent by this device but were lost in the
+ * network before reaching the other party.
+ */
+ public int getNumRtpPacketsTransmittedLost() {
+ return mNumRtpPacketsTransmittedLost;
+ }
+
+ /**
+ * Returns the number of RTP packets which were sent by the other party but were lost in the
+ * network before reaching this device.
+ */
+ public int getNumRtpPacketsNotReceived() {
+ return mNumRtpPacketsNotReceived;
+ }
+
+ /**
+ * Returns the average relative jitter in milliseconds. Jitter represents the amount of variance
+ * in interarrival time of packets, for example, if two packets are sent 2 milliseconds apart
+ * but received 3 milliseconds apart, the relative jitter between those packets is 1
+ * millisecond.
+ *
+ * <p>See RFC 3550 for more information on jitter calculations.
+ */
+ public int getAverageRelativeJitter() {
+ return mAverageRelativeJitter;
+ }
+
+ /**
+ * Returns the maximum relative jitter for a given ongoing call. Jitter represents the amount of
+ * variance in interarrival time of packets, for example, if two packets are sent 2 milliseconds
+ * apart but received 3 milliseconds apart, the relative jitter between those packets is 1
+ * millisecond.
+ *
+ * <p>See RFC 3550 for more information on jitter calculations.
+ */
+ public int getMaxRelativeJitter() {
+ return mMaxRelativeJitter;
+ }
+
+ /**
+ * Returns the average round trip time in milliseconds.
+ */
+ public int getAverageRoundTripTime() {
+ return mAverageRoundTripTime;
+ }
+
+ /**
+ * Returns the codec type. This value corresponds to the AUDIO_QUALITY_* constants in
+ * {@link ImsStreamMediaProfile}.
+ *
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_NONE
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_AMR
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_AMR_WB
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_QCELP13K
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVRC
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVRC_B
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVRC_WB
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVRC_NW
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_GSM_EFR
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_GSM_FR
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_GSM_HR
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_G711U
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_G723
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_G711A
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_G722
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_G711AB
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_G729
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVS_NB
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVS_WB
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVS_SWB
+ * @see ImsStreamMediaProfile#AUDIO_QUALITY_EVS_FB
+ */
+ public int getCodecType() {
+ return mCodecType;
+ }
+
+ // Parcelable things
+ @Override
+ public String toString() {
+ return "CallQuality: {downlinkCallQualityLevel=" + mDownlinkCallQualityLevel
+ + " uplinkCallQualityLevel=" + mUplinkCallQualityLevel
+ + " callDuration=" + mCallDuration
+ + " numRtpPacketsTransmitted=" + mNumRtpPacketsTransmitted
+ + " numRtpPacketsReceived=" + mNumRtpPacketsReceived
+ + " numRtpPacketsTransmittedLost=" + mNumRtpPacketsTransmittedLost
+ + " numRtpPacketsNotReceived=" + mNumRtpPacketsNotReceived
+ + " averageRelativeJitter=" + mAverageRelativeJitter
+ + " maxRelativeJitter=" + mMaxRelativeJitter
+ + " averageRoundTripTime=" + mAverageRoundTripTime
+ + " codecType=" + mCodecType
+ + "}";
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(
+ mDownlinkCallQualityLevel,
+ mUplinkCallQualityLevel,
+ mCallDuration,
+ mNumRtpPacketsTransmitted,
+ mNumRtpPacketsReceived,
+ mNumRtpPacketsTransmittedLost,
+ mNumRtpPacketsNotReceived,
+ mAverageRelativeJitter,
+ mMaxRelativeJitter,
+ mAverageRoundTripTime,
+ mCodecType);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof CallQuality) || hashCode() != o.hashCode()) {
+ return false;
+ }
+
+ if (this == o) {
+ return true;
+ }
+
+ CallQuality s = (CallQuality) o;
+
+ return (mDownlinkCallQualityLevel == s.mDownlinkCallQualityLevel
+ && mUplinkCallQualityLevel == s.mUplinkCallQualityLevel
+ && mCallDuration == s.mCallDuration
+ && mNumRtpPacketsTransmitted == s.mNumRtpPacketsTransmitted
+ && mNumRtpPacketsReceived == s.mNumRtpPacketsReceived
+ && mNumRtpPacketsTransmittedLost == s.mNumRtpPacketsTransmittedLost
+ && mNumRtpPacketsNotReceived == s.mNumRtpPacketsNotReceived
+ && mAverageRelativeJitter == s.mAverageRelativeJitter
+ && mMaxRelativeJitter == s.mMaxRelativeJitter
+ && mAverageRoundTripTime == s.mAverageRoundTripTime
+ && mCodecType == s.mCodecType);
+ }
+
+ /**
+ * {@link Parcelable#describeContents}
+ */
+ public @Parcelable.ContentsFlags int describeContents() {
+ return 0;
+ }
+
+ /**
+ * {@link Parcelable#writeToParcel}
+ */
+ public void writeToParcel(Parcel dest, @Parcelable.WriteFlags int flags) {
+ dest.writeInt(mDownlinkCallQualityLevel);
+ dest.writeInt(mUplinkCallQualityLevel);
+ dest.writeInt(mCallDuration);
+ dest.writeInt(mNumRtpPacketsTransmitted);
+ dest.writeInt(mNumRtpPacketsReceived);
+ dest.writeInt(mNumRtpPacketsTransmittedLost);
+ dest.writeInt(mNumRtpPacketsNotReceived);
+ dest.writeInt(mAverageRelativeJitter);
+ dest.writeInt(mMaxRelativeJitter);
+ dest.writeInt(mAverageRoundTripTime);
+ dest.writeInt(mCodecType);
+ }
+
+ public static final Parcelable.Creator<CallQuality> CREATOR = new Parcelable.Creator() {
+ public CallQuality createFromParcel(Parcel in) {
+ return new CallQuality(in);
+ }
+
+ public CallQuality[] newArray(int size) {
+ return new CallQuality[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/ICellInfoCallback.aidl b/telephony/java/android/telephony/ICellInfoCallback.aidl
index 7fb62682..ee3c1b1 100644
--- a/telephony/java/android/telephony/ICellInfoCallback.aidl
+++ b/telephony/java/android/telephony/ICellInfoCallback.aidl
@@ -16,6 +16,7 @@
package android.telephony;
+import android.os.ParcelableException;
import android.telephony.CellInfo;
import java.util.List;
@@ -27,4 +28,5 @@
oneway interface ICellInfoCallback
{
void onCellInfo(in List<CellInfo> state);
+ void onError(in int errorCode, in ParcelableException detail);
}
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index e27b385..c816701 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -296,7 +296,7 @@
/**
* Listen for changes to preferred data subId.
- * See {@link SubscriptionManager#setPreferredData(int)}
+ * See {@link SubscriptionManager#setPreferredDataSubId(int)}
* for more details.
*
* @see #onPreferredDataSubIdChanged
@@ -335,6 +335,18 @@
@SystemApi
public static final int LISTEN_CALL_DISCONNECT_CAUSES = 0x02000000;
+ /**
+ * Listen for changes to the call attributes of a currently active call.
+ * {@more}
+ * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
+ * READ_PRECISE_PHONE_STATE}
+ *
+ * @see #onCallAttributesChanged
+ * @hide
+ */
+ @SystemApi
+ public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 0x04000000;
+
/*
* Subscription used to listen to the phone state changes
* @hide
@@ -683,6 +695,17 @@
}
/**
+ * Callback invoked when the call attributes changes. Requires
+ * the READ_PRIVILEGED_PHONE_STATE permission.
+ * @param callAttributes the call attributes
+ * @hide
+ */
+ @SystemApi
+ public void onCallAttributesChanged(CallAttributes callAttributes) {
+ // default implementation empty
+ }
+
+ /**
* Callback invoked when modem radio power state changes. Requires
* the READ_PRIVILEGED_PHONE_STATE permission.
* @param state the modem radio power state
@@ -941,6 +964,14 @@
() -> mExecutor.execute(() -> psl.onRadioPowerStateChanged(state)));
}
+ public void onCallAttributesChanged(CallAttributes callAttributes) {
+ PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
+ if (psl == null) return;
+
+ Binder.withCleanCallingIdentity(
+ () -> mExecutor.execute(() -> psl.onCallAttributesChanged(callAttributes)));
+ }
+
public void onPreferredDataSubIdChanged(int subId) {
PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
if (psl == null) return;
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 2271069..e77042d 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -24,6 +24,8 @@
import android.os.Parcelable;
import android.os.PersistableBundle;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
/**
@@ -178,6 +180,35 @@
return mLte;
}
+ /**
+ * Returns a List of CellSignalStrength Components of this SignalStrength Report.
+ *
+ * Use this API to access underlying
+ * {@link android.telephony#CellSignalStrength CellSignalStrength} objects that provide more
+ * granular information about the SignalStrength report. Only valid (non-empty)
+ * CellSignalStrengths will be returned. The order of any returned elements is not guaranteed,
+ * and the list may contain more than one instance of a CellSignalStrength type.
+ *
+ * @return a List of CellSignalStrength or an empty List if there are no valid measurements.
+ *
+ * @see android.telephony#CellSignalStrength
+ * @see android.telephony#CellSignalStrengthNr
+ * @see android.telephony#CellSignalStrengthLte
+ * @see android.telephony#CellSignalStrengthTdscdma
+ * @see android.telephony#CellSignalStrengthWcdma
+ * @see android.telephony#CellSignalStrengthCdma
+ * @see android.telephony#CellSignalStrengthGsm
+ */
+ public @NonNull List<CellSignalStrength> getCellSignalStrengths() {
+ List<CellSignalStrength> cssList = new ArrayList<>(2); // Usually have 2 or fewer elems
+ if (mLte.isValid()) cssList.add(mLte);
+ if (mCdma.isValid()) cssList.add(mCdma);
+ if (mTdscdma.isValid()) cssList.add(mTdscdma);
+ if (mWcdma.isValid()) cssList.add(mWcdma);
+ if (mGsm.isValid()) cssList.add(mGsm);
+ return cssList;
+ }
+
/** @hide */
public void updateLevel(PersistableBundle cc, ServiceState ss) {
mLteRsrpBoost = ss.getLteEarfcnRsrpBoost();
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index fae5d30..c9d0eb1 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -583,7 +583,6 @@
* TelephonyProvider column name for whether a subscription is opportunistic, that is,
* whether the network it connects to is limited in functionality or coverage.
* For example, CBRS.
- * IS_EMBEDDED should always be true.
* <p>Type: INTEGER (int), 1 for opportunistic or 0 for non-opportunistic.
* @hide
*/
@@ -1270,7 +1269,8 @@
}
/**
- * Request a refresh of the platform cache of profile information.
+ * Request a refresh of the platform cache of profile information for the eUICC which
+ * corresponds to the card ID returned by {@link TelephonyManager#getCardIdForDefaultEuicc()}.
*
* <p>Should be called by the EuiccService implementation whenever this information changes due
* to an operation done outside the scope of a request initiated by the platform to the
@@ -1278,17 +1278,50 @@
* were made through the EuiccService.
*
* <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
+ *
+ * @see {@link TelephonyManager#getCardIdForDefaultEuicc()} for more information on the card ID.
+ *
* @hide
*/
@SystemApi
public void requestEmbeddedSubscriptionInfoListRefresh() {
+ int cardId = TelephonyManager.from(mContext).getCardIdForDefaultEuicc();
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
- iSub.requestEmbeddedSubscriptionInfoListRefresh();
+ iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId);
}
} catch (RemoteException ex) {
- // ignore it
+ logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed.");
+ }
+ }
+
+ /**
+ * Request a refresh of the platform cache of profile information for the eUICC with the given
+ * {@code cardId}.
+ *
+ * <p>Should be called by the EuiccService implementation whenever this information changes due
+ * to an operation done outside the scope of a request initiated by the platform to the
+ * EuiccService. There is no need to refresh for downloads, deletes, or other operations that
+ * were made through the EuiccService.
+ *
+ * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
+ *
+ * @param cardId the card ID of the eUICC.
+ *
+ * @see {@link TelephonyManager#getCardIdForDefaultEuicc()} for more information on the card ID.
+ *
+ * @hide
+ */
+ @SystemApi
+ public void requestEmbeddedSubscriptionInfoListRefresh(int cardId) {
+ try {
+ ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+ if (iSub != null) {
+ iSub.requestEmbeddedSubscriptionInfoListRefresh(cardId);
+ }
+ } catch (RemoteException ex) {
+ logd("requestEmbeddedSubscriptionInfoListFresh for card = " + cardId + " failed.");
}
}
@@ -2405,10 +2438,39 @@
*
*/
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
- public void setPreferredData(int subId) {
- if (VDBG) logd("[setPreferredData]+ subId:" + subId);
- setSubscriptionPropertyHelper(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
- "setPreferredData", (iSub)-> iSub.setPreferredData(subId));
+ public void setPreferredDataSubscriptionId(int subId) {
+ if (VDBG) logd("[setPreferredDataSubscriptionId]+ subId:" + subId);
+ setSubscriptionPropertyHelper(DEFAULT_SUBSCRIPTION_ID, "setPreferredDataSubscriptionId",
+ (iSub)-> iSub.setPreferredDataSubscriptionId(subId));
+ }
+
+ /**
+ * Get which subscription is preferred for cellular data.
+ * It's also usually the subscription we set up internet connection on.
+ *
+ * PreferredData overwrites user setting of default data subscription. And it's used
+ * by AlternativeNetworkService or carrier apps to switch primary and CBRS
+ * subscription dynamically in multi-SIM devices.
+ *
+ * @return preferred subscription id for cellular data. {@link DEFAULT_SUBSCRIPTION_ID} if
+ * there's no prefered subscription.
+ *
+ * @hide
+ *
+ */
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public int getPreferredDataSubscriptionId() {
+ int preferredSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
+ try {
+ ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+ if (iSub != null) {
+ preferredSubId = iSub.getPreferredDataSubscriptionId();
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+
+ return preferredSubId;
}
/**
@@ -2458,18 +2520,32 @@
}
/**
- * Set opportunistic by simInfo index
+ * Set whether a subscription is opportunistic, that is, whether the network it connects
+ * to has limited coverage. For example, CBRS. Setting a subscription opportunistic has
+ * following impacts:
+ * 1) Even if it's active, it will be dormant most of the time. The modem will not try
+ * to scan or camp until it knows an available network is nearby to save power.
+ * 2) Telephony relies on system app or carrier input to notify nearby available networks.
+ * See {@link TelephonyManager#updateAvailableNetworks(List)} for more information.
+ * 3) In multi-SIM devices, when the network is nearby and camped, system may automatically
+ * switch internet data between it and default data subscription, based on carrier
+ * recommendation and its signal strength and metered-ness, etc.
+ *
+ *
+ * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier
+ * privilege permission of the subscription.
*
* @param opportunistic whether it’s opportunistic subscription.
* @param subId the unique SubscriptionInfo index in database
- * @return the number of records updated
- * @hide
+ * @return {@code true} if the operation is succeed, {@code false} otherwise.
*/
+ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
- public int setOpportunistic(boolean opportunistic, int subId) {
+ public boolean setOpportunistic(boolean opportunistic, int subId) {
if (VDBG) logd("[setOpportunistic]+ opportunistic:" + opportunistic + " subId:" + subId);
return setSubscriptionPropertyHelper(subId, "setOpportunistic",
- (iSub)-> iSub.setOpportunistic(opportunistic, subId));
+ (iSub)-> iSub.setOpportunistic(
+ opportunistic, subId, mContext.getOpPackageName())) == 1;
}
/**
@@ -2589,18 +2665,26 @@
}
/**
- * Set metered by simInfo index
+ * Set if a subscription is metered or not. Similar to Wi-Fi, metered means
+ * user may be charged more if more data is used.
+ *
+ * By default all Cellular networks are considered metered. System or carrier privileged apps
+ * can set a subscription un-metered which will be considered when system switches data between
+ * primary subscription and opportunistic subscription.
+ *
+ * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier
+ * privilege permission of the subscription.
*
* @param isMetered whether it’s a metered subscription.
* @param subId the unique SubscriptionInfo index in database
- * @return the number of records updated
- * @hide
+ * @return {@code true} if the operation is succeed, {@code false} otherwise.
*/
+ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
- public int setMetered(boolean isMetered, int subId) {
+ public boolean setMetered(boolean isMetered, int subId) {
if (VDBG) logd("[setIsMetered]+ isMetered:" + isMetered + " subId:" + subId);
return setSubscriptionPropertyHelper(subId, "setIsMetered",
- (iSub)-> iSub.setMetered(isMetered, subId));
+ (iSub)-> iSub.setMetered(isMetered, subId, mContext.getOpPackageName())) == 1;
}
/**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c0ce0b3..71b18fd 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -4871,19 +4871,53 @@
/** Callback for providing asynchronous {@link CellInfo} on request */
public abstract static class CellInfoCallback {
/**
- * Response to
+ * Success response to
* {@link android.telephony.TelephonyManager#requestCellInfoUpdate requestCellInfoUpdate()}.
*
- * <p>Invoked when there is a response to
+ * Invoked when there is a response to
* {@link android.telephony.TelephonyManager#requestCellInfoUpdate requestCellInfoUpdate()}
* to provide a list of {@link CellInfo}. If no {@link CellInfo} is available then an empty
- * list will be provided. If an error occurs, null will be provided.
+ * list will be provided. If an error occurs, null will be provided unless the onError
+ * callback is overridden.
*
* @param cellInfo a list of {@link CellInfo}, an empty list, or null.
*
* {@see android.telephony.TelephonyManager#getAllCellInfo getAllCellInfo()}
*/
- public abstract void onCellInfo(List<CellInfo> cellInfo);
+ public abstract void onCellInfo(@NonNull List<CellInfo> cellInfo);
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"ERROR_"}, value = {ERROR_TIMEOUT, ERROR_MODEM_ERROR})
+ public @interface CellInfoCallbackError {}
+
+ /**
+ * The system timed out waiting for a response from the Radio.
+ */
+ public static final int ERROR_TIMEOUT = 1;
+
+ /**
+ * The modem returned a failure.
+ */
+ public static final int ERROR_MODEM_ERROR = 2;
+
+ /**
+ * Error response to
+ * {@link android.telephony.TelephonyManager#requestCellInfoUpdate requestCellInfoUpdate()}.
+ *
+ * Invoked when an error condition prevents updated {@link CellInfo} from being fetched
+ * and returned from the modem. Callers of requestCellInfoUpdate() should override this
+ * function to receive detailed status information in the event of an error. By default,
+ * this function will invoke onCellInfo() with null.
+ *
+ * @param errorCode an error code indicating the type of failure.
+ * @param detail a Throwable object with additional detail regarding the failure if
+ * available, otherwise null.
+ */
+ public void onError(@CellInfoCallbackError int errorCode, @Nullable Throwable detail) {
+ // By default, simply invoke the success callback with an empty list.
+ onCellInfo(new ArrayList<CellInfo>());
+ }
};
/**
@@ -4910,6 +4944,12 @@
Binder.withCleanCallingIdentity(() ->
executor.execute(() -> callback.onCellInfo(cellInfo)));
}
+
+ public void onError(int errorCode, android.os.ParcelableException detail) {
+ Binder.withCleanCallingIdentity(() ->
+ executor.execute(() -> callback.onError(
+ errorCode, detail.getCause())));
+ }
}, getOpPackageName());
} catch (RemoteException ex) {
@@ -4944,6 +4984,12 @@
Binder.withCleanCallingIdentity(() ->
executor.execute(() -> callback.onCellInfo(cellInfo)));
}
+
+ public void onError(int errorCode, android.os.ParcelableException detail) {
+ Binder.withCleanCallingIdentity(() ->
+ executor.execute(() -> callback.onError(
+ errorCode, detail.getCause())));
+ }
}, getOpPackageName(), workSource);
} catch (RemoteException ex) {
}
@@ -5831,9 +5877,14 @@
/**
* Returns the IMS Service Table (IST) that was loaded from the ISIM.
+ *
+ * See 3GPP TS 31.103 (Section 4.2.7) for the definition and more information on this table.
+ *
* @return IMS Service Table or null if not present or not loaded
* @hide
*/
+ @SystemApi
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public String getIsimIst() {
try {
IPhoneSubInfo info = getSubscriberInfo();
@@ -6683,8 +6734,8 @@
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
- return telephony.getCarrierPrivilegeStatus(subId) ==
- CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
+ return telephony.getCarrierPrivilegeStatus(subId)
+ == CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
}
} catch (RemoteException ex) {
Rlog.e(TAG, "hasCarrierPrivileges RemoteException", ex);
@@ -9692,10 +9743,11 @@
try {
IOns iOpportunisticNetworkService = getIOns();
if (iOpportunisticNetworkService != null) {
- return iOpportunisticNetworkService.setPreferredData(subId, pkgForDebug);
+ return iOpportunisticNetworkService
+ .setPreferredDataSubscriptionId(subId, pkgForDebug);
}
} catch (RemoteException ex) {
- Rlog.e(TAG, "setPreferredData RemoteException", ex);
+ Rlog.e(TAG, "setPreferredDataSubscriptionId RemoteException", ex);
}
return false;
}
@@ -9716,10 +9768,10 @@
try {
IOns iOpportunisticNetworkService = getIOns();
if (iOpportunisticNetworkService != null) {
- subId = iOpportunisticNetworkService.getPreferredData(pkgForDebug);
+ subId = iOpportunisticNetworkService.getPreferredDataSubscriptionId(pkgForDebug);
}
} catch (RemoteException ex) {
- Rlog.e(TAG, "getPreferredData RemoteException", ex);
+ Rlog.e(TAG, "getPreferredDataSubscriptionId RemoteException", ex);
}
return subId;
}
@@ -9744,7 +9796,7 @@
boolean ret = false;
try {
IOns iOpportunisticNetworkService = getIOns();
- if (iOpportunisticNetworkService != null) {
+ if (iOpportunisticNetworkService != null && availableNetworks != null) {
ret = iOpportunisticNetworkService.updateAvailableNetworks(availableNetworks,
pkgForDebug);
}
diff --git a/telephony/java/android/telephony/euicc/EuiccCardManager.java b/telephony/java/android/telephony/euicc/EuiccCardManager.java
index 3b1ef3f..994c49c 100644
--- a/telephony/java/android/telephony/euicc/EuiccCardManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccCardManager.java
@@ -155,7 +155,7 @@
* Requests all the profiles on eUicc.
*
* @param cardId The Id of the eUICC.
- * @param executor The executor through which the callback should be invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback The callback to get the result code and all the profiles.
*/
public void requestAllProfiles(String cardId, @CallbackExecutor Executor executor,
@@ -179,7 +179,7 @@
*
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile.
- * @param executor The executor through which the callback should be invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback The callback to get the result code and profile.
*/
public void requestProfile(String cardId, String iccid, @CallbackExecutor Executor executor,
@@ -204,7 +204,7 @@
* @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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback The callback to get the result code.
*/
public void disableProfile(String cardId, String iccid, boolean refresh,
@@ -230,7 +230,7 @@
* @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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback The callback to get the result code and the EuiccProfileInfo enabled.
*/
public void switchToProfile(String cardId, String iccid, boolean refresh,
@@ -255,7 +255,7 @@
* @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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback The callback to get the result code.
*/
public void setNickname(String cardId, String iccid, String nickname,
@@ -279,7 +279,7 @@
*
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile.
- * @param executor The executor through which the callback should be invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback The callback to get the result code.
*/
public void deleteProfile(String cardId, String iccid, @CallbackExecutor Executor executor,
@@ -304,7 +304,7 @@
* @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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback The callback to get the result code.
*/
public void resetMemory(String cardId, @ResetOption int options,
@@ -327,7 +327,7 @@
* 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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback The callback to get the result code and the default SM-DP+ address.
*/
public void requestDefaultSmdpAddress(String cardId, @CallbackExecutor Executor executor,
@@ -350,7 +350,7 @@
* Requests the SM-DS address from eUICC.
*
* @param cardId The Id of the eUICC.
- * @param executor The executor through which the callback should be invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback The callback to get the result code and the SM-DS address.
*/
public void requestSmdsAddress(String cardId, @CallbackExecutor Executor executor,
@@ -374,7 +374,7 @@
*
* @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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback The callback to get the result code.
*/
public void setDefaultSmdpAddress(String cardId, String defaultSmdpAddress,
@@ -398,7 +398,7 @@
* Requests Rules Authorisation Table.
*
* @param cardId The Id of the eUICC.
- * @param executor The executor through which the callback should be invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback the callback to get the result code and the rule authorisation table.
*/
public void requestRulesAuthTable(String cardId, @CallbackExecutor Executor executor,
@@ -421,7 +421,7 @@
* 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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback the callback to get the result code and the challenge.
*/
public void requestEuiccChallenge(String cardId, @CallbackExecutor Executor executor,
@@ -444,7 +444,7 @@
* 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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback the callback to get the result code and the info1.
*/
public void requestEuiccInfo1(String cardId, @CallbackExecutor Executor executor,
@@ -467,7 +467,7 @@
* 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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback the callback to get the result code and the info2.
*/
public void requestEuiccInfo2(String cardId, @CallbackExecutor Executor executor,
@@ -500,7 +500,7 @@
* 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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback the callback to get the result code and a byte array which represents a
* {@code AuthenticateServerResponse} defined in GSMA RSP v2.0+.
*/
@@ -540,7 +540,7 @@
* 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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback the callback to get the result code and a byte array which represents a
* {@code PrepareDownloadResponse} defined in GSMA RSP v2.0+
*/
@@ -572,7 +572,7 @@
*
* @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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback the callback to get the result code and a byte array which represents a
* {@code LoadBoundProfilePackageResponse} defined in GSMA RSP v2.0+.
*/
@@ -601,7 +601,7 @@
* @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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback the callback to get the result code and an byte[] which represents a
* {@code CancelSessionResponse} defined in GSMA RSP v2.0+.
*/
@@ -630,7 +630,7 @@
*
* @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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback the callback to get the result code and the list of notifications.
*/
public void listNotifications(String cardId, @EuiccNotification.Event int events,
@@ -654,7 +654,7 @@
*
* @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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback the callback to get the result code and the list of notifications.
*/
public void retrieveNotificationList(String cardId, @EuiccNotification.Event int events,
@@ -678,7 +678,7 @@
*
* @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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback the callback to get the result code and the notification.
*/
public void retrieveNotification(String cardId, int seqNumber,
@@ -702,7 +702,7 @@
*
* @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 invoke.
+ * @param executor The executor through which the callback should be invoked.
* @param callback the callback to get the result code.
*/
public void removeNotificationFromList(String cardId, int seqNumber,
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index b732d4d..9164402 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -335,7 +335,7 @@
}
try {
getIEuiccController().downloadSubscription(subscription, switchAfterDownload,
- mContext.getOpPackageName(), callbackIntent);
+ mContext.getOpPackageName(), null /* resolvedBundle */, callbackIntent);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -546,14 +546,13 @@
/**
* Update the nickname for the given subscription.
*
- * <p>Requires that the calling app has the
- * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
- * internal system use only.
+ * <p>Requires that the calling app has carrier privileges according to the metadata of the
+ * profile to be updated, or the
+ * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
*
* @param subscriptionId the ID of the subscription to update.
* @param nickname the new nickname to apply.
* @param callbackIntent a PendingIntent to launch when the operation completes.
- * @hide
*/
@RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
public void updateSubscriptionNickname(
@@ -564,7 +563,7 @@
}
try {
getIEuiccController().updateSubscriptionNickname(
- subscriptionId, nickname, callbackIntent);
+ subscriptionId, nickname, mContext.getOpPackageName(), callbackIntent);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/telephony/java/android/telephony/ims/ImsCallSession.java b/telephony/java/android/telephony/ims/ImsCallSession.java
index df903cc2..397d5d9 100644
--- a/telephony/java/android/telephony/ims/ImsCallSession.java
+++ b/telephony/java/android/telephony/ims/ImsCallSession.java
@@ -443,6 +443,13 @@
public void callSessionRttMessageReceived(String rttMessage) {
// no-op
}
+
+ /**
+ * While in call, there has been a change in RTT audio indicator.
+ */
+ public void callSessionRttAudioIndicatorChanged(ImsStreamMediaProfile profile) {
+ // no-op
+ }
}
private final IImsCallSession miSession;
@@ -1397,6 +1404,16 @@
mListener.callSessionRttMessageReceived(rttMessage);
}
}
+
+ /**
+ * While in call, there has been a change in RTT audio indicator.
+ */
+ @Override
+ public void callSessionRttAudioIndicatorChanged(ImsStreamMediaProfile profile) {
+ if (mListener != null) {
+ mListener.callSessionRttAudioIndicatorChanged(profile);
+ }
+ }
}
/**
diff --git a/telephony/java/android/telephony/ims/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
index a7f124a..a4696a3 100644
--- a/telephony/java/android/telephony/ims/ImsCallSessionListener.java
+++ b/telephony/java/android/telephony/ims/ImsCallSessionListener.java
@@ -599,5 +599,18 @@
throw new RuntimeException(e);
}
}
+
+ /**
+ * While in call, there has been a change in RTT audio indicator.
+ *
+ * @param profile updated ImsStreamMediaProfile
+ */
+ public void callSessionRttAudioIndicatorChanged(ImsStreamMediaProfile profile) {
+ try {
+ mListener.callSessionRttAudioIndicatorChanged(profile);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index 122626f..e2350fe 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -714,7 +714,7 @@
* @see #setVoWiFiRoamingSetting(boolean)
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- @WiFiCallingMode int getVoWiFiRoamingModeSetting() {
+ public @WiFiCallingMode int getVoWiFiRoamingModeSetting() {
try {
return getITelephony().getVoWiFiRoamingModeSetting(mSubId);
} catch (RemoteException e) {
diff --git a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
index 52d72b5..837ef54 100644
--- a/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
+++ b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java
@@ -97,6 +97,9 @@
// Rtt related information
/** @hide */
public int mRttMode;
+ // RTT Audio Speech Indicator
+ /** @hide */
+ public boolean mHasRttAudioSpeech = false;
/** @hide */
public ImsStreamMediaProfile(Parcel in) {
@@ -197,7 +200,8 @@
", audioDirection=" + mAudioDirection +
", videoQuality=" + mVideoQuality +
", videoDirection=" + mVideoDirection +
- ", rttMode=" + mRttMode + " }";
+ ", rttMode=" + mRttMode +
+ ", hasRttAudioSpeech=" + mHasRttAudioSpeech + " }";
}
@Override
@@ -212,6 +216,7 @@
out.writeInt(mVideoQuality);
out.writeInt(mVideoDirection);
out.writeInt(mRttMode);
+ out.writeBoolean(mHasRttAudioSpeech);
}
private void readFromParcel(Parcel in) {
@@ -220,6 +225,7 @@
mVideoQuality = in.readInt();
mVideoDirection = in.readInt();
mRttMode = in.readInt();
+ mHasRttAudioSpeech = in.readBoolean();
}
public static final Creator<ImsStreamMediaProfile> CREATOR =
@@ -250,6 +256,10 @@
mRttMode = rttMode;
}
+ public void setRttAudioSpeech(boolean audioOn) {
+ mHasRttAudioSpeech = audioOn;
+ }
+
public int getAudioQuality() {
return mAudioQuality;
}
@@ -269,4 +279,8 @@
public int getRttMode() {
return mRttMode;
}
+
+ public boolean getRttAudioSpeech() {
+ return mHasRttAudioSpeech;
+ }
}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl b/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl
index f25b4b1..d0b31e1 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl
@@ -138,4 +138,10 @@
* @param rttMessage Received RTT message
*/
void callSessionRttMessageReceived(in String rttMessage);
+
+ /*
+ * While in call, there has been a change in RTT audio indicator.
+ * @param profile updated ImsStreamMediaProfile
+ */
+ void callSessionRttAudioIndicatorChanged(in ImsStreamMediaProfile profile);
}
diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java
index 23de2fd..bc58e46 100644
--- a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java
+++ b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java
@@ -591,5 +591,11 @@
public void callSessionRttMessageReceived(String rttMessage) throws RemoteException {
mNewListener.callSessionRttMessageReceived(rttMessage);
}
+
+ @Override
+ public void callSessionRttAudioIndicatorChanged(ImsStreamMediaProfile profile)
+ throws RemoteException {
+ mNewListener.callSessionRttAudioIndicatorChanged(profile);
+ }
}
}
diff --git a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
index a8e8b7dd..bbb27af 100644
--- a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl
@@ -152,4 +152,10 @@
* @param rttMessage Received RTT message
*/
void callSessionRttMessageReceived(in String rttMessage);
+
+ /*
+ * While in call, there has been a change in RTT audio indicator.
+ * @param profile updated ImsStreamMediaProfile
+ */
+ void callSessionRttAudioIndicatorChanged(in ImsStreamMediaProfile profile);
}
diff --git a/telephony/java/com/android/internal/telephony/IOns.aidl b/telephony/java/com/android/internal/telephony/IOns.aidl
index d6779f1..0e3d12b 100755
--- a/telephony/java/com/android/internal/telephony/IOns.aidl
+++ b/telephony/java/com/android/internal/telephony/IOns.aidl
@@ -66,7 +66,7 @@
* @return true if request is accepted, else false.
*
*/
- boolean setPreferredData(int subId, String callingPackage);
+ boolean setPreferredDataSubscriptionId(int subId, String callingPackage);
/**
* Get preferred opportunistic data subscription Id
@@ -78,7 +78,7 @@
* subscription id
*
*/
- int getPreferredData(String callingPackage);
+ int getPreferredDataSubscriptionId(String callingPackage);
/**
* Update availability of a list of networks in the current location.
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 00cf9c3..3dbebe8 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -17,14 +17,15 @@
package com.android.internal.telephony;
import android.os.Bundle;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
+import android.telephony.CallAttributes;
import android.telephony.CellInfo;
import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.PhoneCapability;
import android.telephony.PhysicalChannelConfig;
import android.telephony.PreciseCallState;
import android.telephony.PreciseDataConnectionState;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
import android.telephony.emergency.EmergencyNumber;
oneway interface IPhoneStateListener {
@@ -54,6 +55,7 @@
void onPhoneCapabilityChanged(in PhoneCapability capability);
void onPreferredDataSubIdChanged(in int subId);
void onRadioPowerStateChanged(in int state);
+ void onCallAttributesChanged(in CallAttributes callAttributes);
void onEmergencyNumberListChanged(in Map emergencyNumberList);
void onCallDisconnectCauseChanged(in int disconnectCause, in int preciseDisconnectCause);
}
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 65d1a920..577ddbd 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -104,7 +104,7 @@
/**
* @see android.telephony.SubscriptionManager#requestEmbeddedSubscriptionInfoListRefresh
*/
- oneway void requestEmbeddedSubscriptionInfoListRefresh();
+ oneway void requestEmbeddedSubscriptionInfoListRefresh(int cardId);
/**
* Add a new SubscriptionInfo to subinfo database if needed
@@ -162,7 +162,7 @@
* @param subId the unique SubscriptionInfo index in database
* @return the number of records updated
*/
- int setOpportunistic(boolean opportunistic, int subId);
+ int setOpportunistic(boolean opportunistic, int subId, String callingPackage);
/**
* Inform SubscriptionManager that subscriptions in the list are bundled
@@ -190,7 +190,7 @@
* @param subId the unique SubscriptionInfo index in database
* @return the number of records updated
*/
- int setMetered(boolean isMetered, int subId);
+ int setMetered(boolean isMetered, int subId, String callingPackage);
/**
* Set which subscription is preferred for cellular data. It's
@@ -200,7 +200,15 @@
* @hide
*
*/
- int setPreferredData(int subId);
+ int setPreferredDataSubscriptionId(int subId);
+
+ /**
+ * Get which subscription is preferred for cellular data.
+ *
+ * @hide
+ *
+ */
+ int getPreferredDataSubscriptionId();
/**
* Get User downloaded Profiles.
diff --git a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
index 0a0ad90..dd40d56 100644
--- a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
+++ b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl
@@ -32,14 +32,14 @@
String getEid();
int getOtaStatus();
oneway void downloadSubscription(in DownloadableSubscription subscription,
- boolean switchAfterDownload, String callingPackage, in PendingIntent callbackIntent);
+ boolean switchAfterDownload, String callingPackage, in Bundle resolvedBundle, in PendingIntent callbackIntent);
EuiccInfo getEuiccInfo();
oneway void deleteSubscription(int subscriptionId, String callingPackage,
in PendingIntent callbackIntent);
oneway void switchToSubscription(int subscriptionId, String callingPackage,
in PendingIntent callbackIntent);
oneway void updateSubscriptionNickname(int subscriptionId, String nickname,
- in PendingIntent callbackIntent);
+ String callingPackage, in PendingIntent callbackIntent);
oneway void eraseSubscriptions(in PendingIntent callbackIntent);
oneway void retainSubscriptionsForFactoryReset(in PendingIntent callbackIntent);
}
\ No newline at end of file
diff --git a/test-base/api/current.txt b/test-base/api/current.txt
index 7ebd6aa..91fcca5 100644
--- a/test-base/api/current.txt
+++ b/test-base/api/current.txt
@@ -48,6 +48,9 @@
method public abstract void startTiming(boolean);
}
+ public abstract deprecated class RepetitiveTest implements java.lang.annotation.Annotation {
+ }
+
public abstract deprecated class UiThreadTest implements java.lang.annotation.Annotation {
}
diff --git a/test-base/src/android/test/RepetitiveTest.java b/test-base/src/android/test/RepetitiveTest.java
index 6a7130e..13e89d2 100644
--- a/test-base/src/android/test/RepetitiveTest.java
+++ b/test-base/src/android/test/RepetitiveTest.java
@@ -26,8 +26,10 @@
* When the annotation is present, the test method is executed the number of times specified by
* numIterations and defaults to 1.
*
- * {@hide} Not needed for public API.
+ * @deprecated New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
*/
+@Deprecated
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RepetitiveTest {
@@ -37,4 +39,4 @@
* @return The total number of iterations, the default is 1.
*/
int numIterations() default 1;
-}
\ No newline at end of file
+}
diff --git a/tests/net/java/android/net/LinkPropertiesTest.java b/tests/net/java/android/net/LinkPropertiesTest.java
index f82b380..299fbef 100644
--- a/tests/net/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/java/android/net/LinkPropertiesTest.java
@@ -18,6 +18,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -33,6 +34,9 @@
import android.system.OsConstants;
import android.util.ArraySet;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
@@ -41,9 +45,6 @@
import java.util.List;
import java.util.Set;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
@RunWith(AndroidJUnit4.class)
@SmallTest
public class LinkPropertiesTest {
@@ -504,6 +505,40 @@
}
@Test
+ public void testNat64Prefix() throws Exception {
+ LinkProperties lp = new LinkProperties();
+ lp.addLinkAddress(LINKADDRV4);
+ lp.addLinkAddress(LINKADDRV6);
+
+ assertNull(lp.getNat64Prefix());
+
+ IpPrefix p = new IpPrefix("64:ff9b::/96");
+ lp.setNat64Prefix(p);
+ assertEquals(p, lp.getNat64Prefix());
+
+ p = new IpPrefix("2001:db8:a:b:1:2:3::/96");
+ lp.setNat64Prefix(p);
+ assertEquals(p, lp.getNat64Prefix());
+
+ p = new IpPrefix("2001:db8:a:b:1:2::/80");
+ try {
+ lp.setNat64Prefix(p);
+ } catch (IllegalArgumentException expected) {
+ }
+
+ p = new IpPrefix("64:ff9b::/64");
+ try {
+ lp.setNat64Prefix(p);
+ } catch (IllegalArgumentException expected) {
+ }
+
+ assertEquals(new IpPrefix("2001:db8:a:b:1:2:3::/96"), lp.getNat64Prefix());
+
+ lp.setNat64Prefix(null);
+ assertNull(lp.getNat64Prefix());
+ }
+
+ @Test
public void testIsProvisioned() {
LinkProperties lp4 = new LinkProperties();
assertFalse("v4only:empty", lp4.isProvisioned());
@@ -814,8 +849,20 @@
assertEquals(new ArraySet<>(expectRemoved), (new ArraySet<>(result.removed)));
}
+ private void assertParcelingIsLossless(LinkProperties source) {
+ Parcel p = Parcel.obtain();
+ source.writeToParcel(p, /* flags */ 0);
+ p.setDataPosition(0);
+ final byte[] marshalled = p.marshall();
+ p = Parcel.obtain();
+ p.unmarshall(marshalled, 0, marshalled.length);
+ p.setDataPosition(0);
+ LinkProperties dest = LinkProperties.CREATOR.createFromParcel(p);
+ assertEquals(source, dest);
+ }
+
@Test
- public void testLinkPropertiesParcelable() {
+ public void testLinkPropertiesParcelable() throws Exception {
LinkProperties source = new LinkProperties();
source.setInterfaceName(NAME);
// set 2 link addresses
@@ -833,15 +880,14 @@
source.setMtu(MTU);
- Parcel p = Parcel.obtain();
- source.writeToParcel(p, /* flags */ 0);
- p.setDataPosition(0);
- final byte[] marshalled = p.marshall();
- p = Parcel.obtain();
- p.unmarshall(marshalled, 0, marshalled.length);
- p.setDataPosition(0);
- LinkProperties dest = LinkProperties.CREATOR.createFromParcel(p);
+ source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96"));
- assertEquals(source, dest);
+ assertParcelingIsLossless(source);
+ }
+
+ @Test
+ public void testParcelUninitialized() throws Exception {
+ LinkProperties empty = new LinkProperties();
+ assertParcelingIsLossless(empty);
}
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index bf39644..2a92a7d 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -4683,7 +4683,7 @@
mCellNetworkAgent.sendLinkProperties(cellLp);
mCellNetworkAgent.connect(true);
networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
- verify(mNetworkManagementService, times(1)).startClatd(MOBILE_IFNAME);
+ verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME);
Nat464Xlat clat = mService.getNat464Xlat(mCellNetworkAgent);
// Clat iface up, expect stack link updated.
@@ -4710,7 +4710,7 @@
mCellNetworkAgent.sendLinkProperties(cellLp);
waitForIdle();
networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
- verify(mNetworkManagementService, times(1)).stopClatd(MOBILE_IFNAME);
+ verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
// Clat iface removed, expect linkproperties revert to original one
clat.interfaceRemoved(CLAT_PREFIX + MOBILE_IFNAME);
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 4c52d81..9578ded 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -32,11 +32,13 @@
import android.content.Context;
import android.content.res.Resources;
import android.net.ConnectivityManager;
+import android.net.INetd;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkMisc;
import android.net.NetworkStack;
+import android.os.INetworkManagementService;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.text.format.DateUtils;
@@ -66,6 +68,8 @@
LingerMonitor mMonitor;
@Mock ConnectivityService mConnService;
+ @Mock INetd mNetd;
+ @Mock INetworkManagementService mNMS;
@Mock Context mCtx;
@Mock NetworkMisc mMisc;
@Mock NetworkNotificationManager mNotifier;
@@ -352,7 +356,7 @@
caps.addCapability(0);
caps.addTransportType(transport);
NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null,
- caps, 50, mCtx, null, mMisc, mConnService);
+ caps, 50, mCtx, null, mMisc, mConnService, mNetd, mNMS);
nai.everValidated = true;
return nai;
}
diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
index bf42412..07b1d05 100644
--- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
+++ b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
@@ -17,9 +17,7 @@
package com.android.server.connectivity;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -27,6 +25,7 @@
import static org.mockito.Mockito.when;
import android.net.ConnectivityManager;
+import android.net.INetd;
import android.net.InterfaceConfiguration;
import android.net.LinkAddress;
import android.net.LinkProperties;
@@ -57,6 +56,7 @@
@Mock ConnectivityService mConnectivity;
@Mock NetworkMisc mMisc;
+ @Mock INetd mNetd;
@Mock INetworkManagementService mNms;
@Mock InterfaceConfiguration mConfig;
@Mock NetworkAgentInfo mNai;
@@ -65,7 +65,7 @@
Handler mHandler;
Nat464Xlat makeNat464Xlat() {
- return new Nat464Xlat(mNms, mNai);
+ return new Nat464Xlat(mNai, mNetd, mNms);
}
@Before
@@ -129,7 +129,7 @@
nat.start();
verify(mNms).registerObserver(eq(nat));
- verify(mNms).startClatd(eq(BASE_IFACE));
+ verify(mNetd).clatdStart(eq(BASE_IFACE));
// Stacked interface up notification arrives.
nat.interfaceLinkStateChanged(STACKED_IFACE, true);
@@ -144,7 +144,7 @@
// ConnectivityService stops clat (Network disconnects, IPv4 addr appears, ...).
nat.stop();
- verify(mNms).stopClatd(eq(BASE_IFACE));
+ verify(mNetd).clatdStop(eq(BASE_IFACE));
// Stacked interface removed notification arrives.
nat.interfaceRemoved(STACKED_IFACE);
@@ -156,7 +156,7 @@
assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
assertIdle(nat);
- verifyNoMoreInteractions(mNms, mConnectivity);
+ verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
}
@Test
@@ -168,7 +168,7 @@
nat.start();
verify(mNms).registerObserver(eq(nat));
- verify(mNms).startClatd(eq(BASE_IFACE));
+ verify(mNetd).clatdStart(eq(BASE_IFACE));
// Stacked interface up notification arrives.
nat.interfaceLinkStateChanged(STACKED_IFACE, true);
@@ -185,7 +185,7 @@
mLooper.dispatchNext();
verify(mNms).unregisterObserver(eq(nat));
- verify(mNms).stopClatd(eq(BASE_IFACE));
+ verify(mNetd).clatdStop(eq(BASE_IFACE));
verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture());
assertTrue(c.getValue().getStackedLinks().isEmpty());
assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
@@ -194,7 +194,7 @@
// ConnectivityService stops clat: no-op.
nat.stop();
- verifyNoMoreInteractions(mNms, mConnectivity);
+ verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
}
@Test
@@ -205,13 +205,13 @@
nat.start();
verify(mNms).registerObserver(eq(nat));
- verify(mNms).startClatd(eq(BASE_IFACE));
+ verify(mNetd).clatdStart(eq(BASE_IFACE));
// ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...)
nat.stop();
verify(mNms).unregisterObserver(eq(nat));
- verify(mNms).stopClatd(eq(BASE_IFACE));
+ verify(mNetd).clatdStop(eq(BASE_IFACE));
assertIdle(nat);
// In-flight interface up notification arrives: no-op
@@ -225,7 +225,7 @@
assertIdle(nat);
- verifyNoMoreInteractions(mNms, mConnectivity);
+ verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
}
@Test
@@ -236,16 +236,16 @@
nat.start();
verify(mNms).registerObserver(eq(nat));
- verify(mNms).startClatd(eq(BASE_IFACE));
+ verify(mNetd).clatdStart(eq(BASE_IFACE));
// ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...)
nat.stop();
verify(mNms).unregisterObserver(eq(nat));
- verify(mNms).stopClatd(eq(BASE_IFACE));
+ verify(mNetd).clatdStop(eq(BASE_IFACE));
assertIdle(nat);
- verifyNoMoreInteractions(mNms, mConnectivity);
+ verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
}
static void assertIdle(Nat464Xlat nat) {
diff --git a/tests/net/java/com/android/server/net/ipmemorystore/IpMemoryStoreServiceTest.java b/tests/net/java/com/android/server/net/ipmemorystore/IpMemoryStoreServiceTest.java
index 859a54d..e63c3b0 100644
--- a/tests/net/java/com/android/server/net/ipmemorystore/IpMemoryStoreServiceTest.java
+++ b/tests/net/java/com/android/server/net/ipmemorystore/IpMemoryStoreServiceTest.java
@@ -16,6 +16,9 @@
package com.android.server.net.ipmemorystore;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+
import android.content.Context;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -26,6 +29,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.io.File;
+
/** Unit tests for {@link IpMemoryStoreServiceTest}. */
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -36,6 +41,7 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ doReturn(new File("/tmp/test.db")).when(mMockContext).getDatabasePath(anyString());
}
@Test
diff --git a/tests/net/java/com/android/server/net/ipmemorystore/RelevanceUtilsTests.java b/tests/net/java/com/android/server/net/ipmemorystore/RelevanceUtilsTests.java
new file mode 100644
index 0000000..8d367e2
--- /dev/null
+++ b/tests/net/java/com/android/server/net/ipmemorystore/RelevanceUtilsTests.java
@@ -0,0 +1,149 @@
+/*
+ * 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.server.net.ipmemorystore;
+
+import static com.android.server.net.ipmemorystore.RelevanceUtils.CAPPED_RELEVANCE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Unit tests for {@link RelevanceUtils}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RelevanceUtilsTests {
+ @Test
+ public void testComputeRelevanceForTargetDate() {
+ final long dayInMillis = 24L * 60 * 60 * 1000;
+ final long base = 1_000_000L; // any given point in time
+ // Relevance when the network expires in 1000 years must be capped
+ assertEquals(CAPPED_RELEVANCE, RelevanceUtils.computeRelevanceForTargetDate(
+ base + 1000L * dayInMillis, base));
+ // Relevance when expiry is before the date must be 0
+ assertEquals(0, RelevanceUtils.computeRelevanceForTargetDate(base - 1, base));
+ // Make sure the relevance for a given target date is higher if the expiry is further
+ // in the future
+ assertTrue(RelevanceUtils.computeRelevanceForTargetDate(base + 100 * dayInMillis, base)
+ < RelevanceUtils.computeRelevanceForTargetDate(base + 150 * dayInMillis, base));
+
+ // Make sure the relevance falls slower as the expiry is closing in. This is to ensure
+ // the decay is indeed logarithmic.
+ final int relevanceAtExpiry = RelevanceUtils.computeRelevanceForTargetDate(base, base);
+ final int relevance50DaysBeforeExpiry =
+ RelevanceUtils.computeRelevanceForTargetDate(base + 50 * dayInMillis, base);
+ final int relevance100DaysBeforeExpiry =
+ RelevanceUtils.computeRelevanceForTargetDate(base + 100 * dayInMillis, base);
+ final int relevance150DaysBeforeExpiry =
+ RelevanceUtils.computeRelevanceForTargetDate(base + 150 * dayInMillis, base);
+ assertEquals(0, relevanceAtExpiry);
+ assertTrue(relevance50DaysBeforeExpiry - relevanceAtExpiry
+ < relevance100DaysBeforeExpiry - relevance50DaysBeforeExpiry);
+ assertTrue(relevance100DaysBeforeExpiry - relevance50DaysBeforeExpiry
+ < relevance150DaysBeforeExpiry - relevance100DaysBeforeExpiry);
+ }
+
+ @Test
+ public void testIncreaseRelevance() {
+ long expiry = System.currentTimeMillis();
+
+ final long firstBump = RelevanceUtils.bumpExpiryDate(expiry);
+ // Though a few milliseconds might have elapsed, the first bump should push the duration
+ // to days in the future, so unless this test takes literal days between these two lines,
+ // this should always pass.
+ assertTrue(firstBump > expiry);
+
+ expiry = 0;
+ long lastDifference = Long.MAX_VALUE;
+ // The relevance should be capped in at most this many steps. Otherwise, fail.
+ final int steps = 1000;
+ for (int i = 0; i < steps; ++i) {
+ final long newExpiry = RelevanceUtils.bumpExpiryDuration(expiry);
+ if (newExpiry == expiry) {
+ // The relevance should be capped. Make sure it is, then exit without failure.
+ assertEquals(newExpiry, RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS);
+ return;
+ }
+ // Make sure the new expiry is further in the future than last time.
+ assertTrue(newExpiry > expiry);
+ // Also check that it was not bumped as much as the last bump, because the
+ // decay must be exponential.
+ assertTrue(newExpiry - expiry < lastDifference);
+ lastDifference = newExpiry - expiry;
+ expiry = newExpiry;
+ }
+ fail("Relevance failed to go to the maximum value after " + steps + " bumps");
+ }
+
+ @Test
+ public void testContinuity() {
+ final long expiry = System.currentTimeMillis();
+
+ // Relevance at expiry and after expiry should be the cap.
+ final int relevanceBeforeMaxLifetime = RelevanceUtils.computeRelevanceForTargetDate(expiry,
+ expiry - (RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS + 1_000_000));
+ assertEquals(relevanceBeforeMaxLifetime, CAPPED_RELEVANCE);
+ final int relevanceForMaxLifetime = RelevanceUtils.computeRelevanceForTargetDate(expiry,
+ expiry - RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS);
+ assertEquals(relevanceForMaxLifetime, CAPPED_RELEVANCE);
+
+ // If the max relevance is reached at the cap lifetime, one millisecond less than this
+ // should be very close. Strictly speaking this is a bit brittle, but it should be
+ // good enough for the purposes of the memory store.
+ final int relevanceForOneMillisecLessThanCap = RelevanceUtils.computeRelevanceForTargetDate(
+ expiry, expiry - RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS + 1);
+ assertTrue(relevanceForOneMillisecLessThanCap <= CAPPED_RELEVANCE);
+ assertTrue(relevanceForOneMillisecLessThanCap >= CAPPED_RELEVANCE - 10);
+
+ // Likewise the relevance one millisecond before expiry should be very close to 0. It's
+ // fine if it rounds down to 0.
+ final int relevanceOneMillisecBeforeExpiry = RelevanceUtils.computeRelevanceForTargetDate(
+ expiry, expiry - 1);
+ assertTrue(relevanceOneMillisecBeforeExpiry <= 10);
+ assertTrue(relevanceOneMillisecBeforeExpiry >= 0);
+
+ final int relevanceAtExpiry = RelevanceUtils.computeRelevanceForTargetDate(expiry, expiry);
+ assertEquals(relevanceAtExpiry, 0);
+ final int relevanceAfterExpiry = RelevanceUtils.computeRelevanceForTargetDate(expiry,
+ expiry + 1_000_000);
+ assertEquals(relevanceAfterExpiry, 0);
+ }
+
+ // testIncreaseRelevance makes sure bumping the expiry continuously always yields a
+ // monotonically increasing date as a side effect, but this tests that the relevance (as
+ // opposed to the expiry date) increases monotonically with increasing periods.
+ @Test
+ public void testMonotonicity() {
+ // Hopefully the relevance is granular enough to give a different value for every one
+ // of this number of steps.
+ final int steps = 40;
+ final long expiry = System.currentTimeMillis();
+
+ int lastRelevance = -1;
+ for (int i = 0; i < steps; ++i) {
+ final long date = expiry - i * (RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS / steps);
+ final int relevance = RelevanceUtils.computeRelevanceForTargetDate(expiry, date);
+ assertTrue(relevance > lastRelevance);
+ lastRelevance = relevance;
+ }
+ }
+}