diff options
107 files changed, 5899 insertions, 2955 deletions
diff --git a/Android.bp b/Android.bp index 0cd985d04596..985d73476142 100644 --- a/Android.bp +++ b/Android.bp @@ -462,16 +462,19 @@ java_library { "telecomm/java/com/android/internal/telecom/RemoteServiceCallback.aidl", "telephony/java/android/telephony/data/IDataService.aidl", "telephony/java/android/telephony/data/IDataServiceCallback.aidl", - "telephony/java/android/telephony/ims/internal/aidl/IImsCallSessionListener.aidl", - "telephony/java/android/telephony/ims/internal/aidl/IImsCapabilityCallback.aidl", - "telephony/java/android/telephony/ims/internal/aidl/IImsConfig.aidl", - "telephony/java/android/telephony/ims/internal/aidl/IImsConfigCallback.aidl", - "telephony/java/android/telephony/ims/internal/aidl/IImsMmTelFeature.aidl", - "telephony/java/android/telephony/ims/internal/aidl/IImsMmTelListener.aidl", - "telephony/java/android/telephony/ims/internal/aidl/IImsRcsFeature.aidl", - "telephony/java/android/telephony/ims/internal/aidl/IImsServiceController.aidl", - "telephony/java/android/telephony/ims/internal/aidl/IImsServiceControllerListener.aidl", - "telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl", + "telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl", + "telephony/java/android/telephony/ims/aidl/IImsCapabilityCallback.aidl", + "telephony/java/android/telephony/ims/aidl/IImsConfig.aidl", + "telephony/java/android/telephony/ims/aidl/IImsConfigCallback.aidl", + "telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl", + "telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl", + "telephony/java/android/telephony/ims/aidl/IImsRegistration.aidl", + "telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl", + "telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl", + "telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl", + "telephony/java/android/telephony/ims/aidl/IImsServiceControllerListener.aidl", + "telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl", + "telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl", "telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl", "telephony/java/android/telephony/mbms/IDownloadStateCallback.aidl", "telephony/java/android/telephony/mbms/IStreamingServiceCallback.aidl", @@ -489,13 +492,10 @@ java_library { "telephony/java/com/android/ims/internal/IImsFeatureStatusCallback.aidl", "telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl", "telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl", - "telephony/java/com/android/ims/internal/IImsRegistration.aidl", - "telephony/java/com/android/ims/internal/IImsRegistrationCallback.aidl", "telephony/java/com/android/ims/internal/IImsRcsFeature.aidl", "telephony/java/com/android/ims/internal/IImsService.aidl", "telephony/java/com/android/ims/internal/IImsServiceController.aidl", "telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl", - "telephony/java/com/android/ims/internal/IImsSmsListener.aidl", "telephony/java/com/android/ims/internal/IImsStreamMediaSession.aidl", "telephony/java/com/android/ims/internal/IImsUt.aidl", "telephony/java/com/android/ims/internal/IImsUtListener.aidl", diff --git a/api/current.txt b/api/current.txt index e047bdc0ef61..14f44ecf7e83 100644 --- a/api/current.txt +++ b/api/current.txt @@ -41672,6 +41672,10 @@ package android.test { package android.test.mock { + public deprecated class MockAccountManager { + method public static android.accounts.AccountManager newMockAccountManager(android.content.Context); + } + public deprecated class MockApplication extends android.app.Application { ctor public MockApplication(); } @@ -41681,6 +41685,7 @@ package android.test.mock { ctor public MockContentProvider(android.content.Context); ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]); method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>); + method public static deprecated void attachInfoForTesting(android.content.ContentProvider, android.content.Context, android.content.pm.ProviderInfo); method public int delete(android.net.Uri, java.lang.String, java.lang.String[]); method public java.lang.String getType(android.net.Uri); method public android.net.Uri insert(android.net.Uri, android.content.ContentValues); @@ -41961,6 +41966,10 @@ package android.test.mock { method public void updateConfiguration(android.content.res.Configuration, android.util.DisplayMetrics); } + public deprecated class MockService { + method public static <T extends android.app.Service> void attachForTesting(android.app.Service, android.content.Context, java.lang.String, android.app.Application); + } + } package android.test.suitebuilder { diff --git a/api/system-current.txt b/api/system-current.txt index 0371f91ad06d..d8a84a94e702 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -29,6 +29,7 @@ package android { field public static final java.lang.String BIND_RESOLVER_RANKER_SERVICE = "android.permission.BIND_RESOLVER_RANKER_SERVICE"; field public static final java.lang.String BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE = "android.permission.BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE"; field public static final java.lang.String BIND_TELEPHONY_DATA_SERVICE = "android.permission.BIND_TELEPHONY_DATA_SERVICE"; + field public static final java.lang.String BIND_TELEPHONY_NETWORK_SERVICE = "android.permission.BIND_TELEPHONY_NETWORK_SERVICE"; field public static final java.lang.String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT"; field public static final java.lang.String BIND_TV_REMOTE_SERVICE = "android.permission.BIND_TV_REMOTE_SERVICE"; field public static final java.lang.String BLUETOOTH_PRIVILEGED = "android.permission.BLUETOOTH_PRIVILEGED"; @@ -4300,16 +4301,669 @@ package android.telephony.data { package android.telephony.ims { + public final class ImsCallForwardInfo implements android.os.Parcelable { + method public int describeContents(); + method public int getCondition(); + method public java.lang.String getNumber(); + method public int getServiceClass(); + method public int getStatus(); + method public int getTimeSeconds(); + method public int getToA(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallForwardInfo> CREATOR; + } + + public final class ImsCallProfile implements android.os.Parcelable { + method public int describeContents(); + method public java.lang.String getCallExtra(java.lang.String); + method public java.lang.String getCallExtra(java.lang.String, java.lang.String); + method public boolean getCallExtraBoolean(java.lang.String); + method public boolean getCallExtraBoolean(java.lang.String, boolean); + method public int getCallExtraInt(java.lang.String); + method public int getCallExtraInt(java.lang.String, int); + method public android.os.Bundle getCallExtras(); + method public int getCallType(); + method public static int getCallTypeFromVideoState(int); + method public android.telephony.ims.ImsStreamMediaProfile getMediaProfile(); + method public int getRestrictCause(); + method public int getServiceType(); + method public static int getVideoStateFromCallType(int); + method public static int getVideoStateFromImsCallProfile(android.telephony.ims.ImsCallProfile); + method public boolean isVideoCall(); + method public boolean isVideoPaused(); + method public static int presentationToOir(int); + method public void setCallExtra(java.lang.String, java.lang.String); + method public void setCallExtraBoolean(java.lang.String, boolean); + method public void setCallExtraInt(java.lang.String, int); + method public void updateCallExtras(android.telephony.ims.ImsCallProfile); + method public void updateCallType(android.telephony.ims.ImsCallProfile); + method public void writeToParcel(android.os.Parcel, int); + field public static final int CALL_RESTRICT_CAUSE_DISABLED = 2; // 0x2 + field public static final int CALL_RESTRICT_CAUSE_HD = 3; // 0x3 + field public static final int CALL_RESTRICT_CAUSE_NONE = 0; // 0x0 + field public static final int CALL_RESTRICT_CAUSE_RAT = 1; // 0x1 + field public static final int CALL_TYPE_VIDEO_N_VOICE = 3; // 0x3 + field public static final int CALL_TYPE_VOICE = 2; // 0x2 + field public static final int CALL_TYPE_VOICE_N_VIDEO = 1; // 0x1 + field public static final int CALL_TYPE_VS = 8; // 0x8 + field public static final int CALL_TYPE_VS_RX = 10; // 0xa + field public static final int CALL_TYPE_VS_TX = 9; // 0x9 + field public static final int CALL_TYPE_VT = 4; // 0x4 + field public static final int CALL_TYPE_VT_NODIR = 7; // 0x7 + field public static final int CALL_TYPE_VT_RX = 6; // 0x6 + field public static final int CALL_TYPE_VT_TX = 5; // 0x5 + field public static final android.os.Parcelable.Creator<android.telephony.ims.ImsCallProfile> CREATOR; + field public static final int DIALSTRING_NORMAL = 0; // 0x0 + field public static final int DIALSTRING_SS_CONF = 1; // 0x1 + field public static final int DIALSTRING_USSD = 2; // 0x2 + field public static final java.lang.String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo"; + field public static final java.lang.String EXTRA_CALL_RAT_TYPE = "CallRadioTech"; + field public static final java.lang.String EXTRA_CHILD_NUMBER = "ChildNum"; + field public static final java.lang.String EXTRA_CNA = "cna"; + field public static final java.lang.String EXTRA_CNAP = "cnap"; + field public static final java.lang.String EXTRA_CODEC = "Codec"; + field public static final java.lang.String EXTRA_DIALSTRING = "dialstring"; + field public static final java.lang.String EXTRA_DISPLAY_TEXT = "DisplayText"; + field public static final java.lang.String EXTRA_IS_CALL_PULL = "CallPull"; + field public static final java.lang.String EXTRA_OI = "oi"; + field public static final java.lang.String EXTRA_OIR = "oir"; + field public static final java.lang.String EXTRA_REMOTE_URI = "remote_uri"; + field public static final java.lang.String EXTRA_USSD = "ussd"; + field public static final int OIR_DEFAULT = 0; // 0x0 + field public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2; // 0x2 + field public static final int OIR_PRESENTATION_PAYPHONE = 4; // 0x4 + field public static final int OIR_PRESENTATION_RESTRICTED = 1; // 0x1 + field public static final int OIR_PRESENTATION_UNKNOWN = 3; // 0x3 + field public static final int SERVICE_TYPE_EMERGENCY = 2; // 0x2 + field public static final int SERVICE_TYPE_NONE = 0; // 0x0 + field public static final int SERVICE_TYPE_NORMAL = 1; // 0x1 + } + + public class ImsCallSessionListener { + method public void callSessionConferenceExtendFailed(android.telephony.ims.ImsReasonInfo); + method public void callSessionConferenceExtendReceived(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile); + method public void callSessionConferenceExtended(android.telephony.ims.stub.ImsCallSessionImplBase, android.telephony.ims.ImsCallProfile); + method public void callSessionConferenceStateUpdated(android.telephony.ims.ImsConferenceState); + method public void callSessionHandover(int, int, android.telephony.ims.ImsReasonInfo); + method public void callSessionHandoverFailed(int, int, android.telephony.ims.ImsReasonInfo); + method public void callSessionHeld(android.telephony.ims.ImsCallProfile); + method public void callSessionHoldFailed(android.telephony.ims.ImsReasonInfo); + method public void callSessionHoldReceived(android.telephony.ims.ImsCallProfile); + method public void callSessionInitiated(android.telephony.ims.ImsCallProfile); + method public void callSessionInitiatedFailed(android.telephony.ims.ImsReasonInfo); + method public void callSessionInviteParticipantsRequestDelivered(); + method public void callSessionInviteParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo); + method public void callSessionMayHandover(int, int); + 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); + method public void callSessionMultipartyStateChanged(boolean); + method public void callSessionProgressing(android.telephony.ims.ImsStreamMediaProfile); + method public void callSessionRemoveParticipantsRequestDelivered(); + method public void callSessionRemoveParticipantsRequestFailed(android.telephony.ims.ImsReasonInfo); + method public void callSessionResumeFailed(android.telephony.ims.ImsReasonInfo); + method public void callSessionResumeReceived(android.telephony.ims.ImsCallProfile); + method public void callSessionResumed(android.telephony.ims.ImsCallProfile); + method public void callSessionRttMessageReceived(java.lang.String); + method public void callSessionRttModifyRequestReceived(android.telephony.ims.ImsCallProfile); + method public void callSessionRttModifyResponseReceived(int); + method public void callSessionSuppServiceReceived(android.telephony.ims.ImsSuppServiceNotification); + method public void callSessionTerminated(android.telephony.ims.ImsReasonInfo); + method public void callSessionTtyModeReceived(int); + method public void callSessionUpdateFailed(android.telephony.ims.ImsReasonInfo); + method public void callSessionUpdateReceived(android.telephony.ims.ImsCallProfile); + method public void callSessionUpdated(android.telephony.ims.ImsCallProfile); + method public void callSessionUssdMessageReceived(int, java.lang.String); + } + + public final class ImsConferenceState implements android.os.Parcelable { + method public int describeContents(); + method public static int getConnectionStateForStatus(java.lang.String); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.ImsConferenceState> CREATOR; + field public static final java.lang.String DISPLAY_TEXT = "display-text"; + field public static final java.lang.String ENDPOINT = "endpoint"; + field public static final java.lang.String SIP_STATUS_CODE = "sipstatuscode"; + field public static final java.lang.String STATUS = "status"; + field public static final java.lang.String STATUS_ALERTING = "alerting"; + field public static final java.lang.String STATUS_CONNECTED = "connected"; + field public static final java.lang.String STATUS_CONNECT_FAIL = "connect-fail"; + field public static final java.lang.String STATUS_DIALING_IN = "dialing-in"; + field public static final java.lang.String STATUS_DIALING_OUT = "dialing-out"; + field public static final java.lang.String STATUS_DISCONNECTED = "disconnected"; + field public static final java.lang.String STATUS_DISCONNECTING = "disconnecting"; + field public static final java.lang.String STATUS_MUTED_VIA_FOCUS = "muted-via-focus"; + field public static final java.lang.String STATUS_ON_HOLD = "on-hold"; + field public static final java.lang.String STATUS_PENDING = "pending"; + field public static final java.lang.String STATUS_SEND_ONLY = "sendonly"; + field public static final java.lang.String STATUS_SEND_RECV = "sendrecv"; + field public static final java.lang.String USER = "user"; + field public final java.util.HashMap<java.lang.String, android.os.Bundle> mParticipants; + } + + public final class ImsExternalCallState implements android.os.Parcelable { + method public int describeContents(); + method public android.net.Uri getAddress(); + method public int getCallId(); + method public int getCallState(); + method public int getCallType(); + method public boolean isCallHeld(); + method public boolean isCallPullable(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int CALL_STATE_CONFIRMED = 1; // 0x1 + field public static final int CALL_STATE_TERMINATED = 2; // 0x2 + field public static final android.os.Parcelable.Creator<android.telephony.ims.ImsExternalCallState> CREATOR; + } + + public final class ImsReasonInfo implements android.os.Parcelable { + method public int describeContents(); + method public int getCode(); + method public int getExtraCode(); + method public java.lang.String getExtraMessage(); + method public void writeToParcel(android.os.Parcel, int); + field public static final int CODE_ACCESS_CLASS_BLOCKED = 1512; // 0x5e8 + field public static final int CODE_ANSWERED_ELSEWHERE = 1014; // 0x3f6 + field public static final int CODE_BLACKLISTED_CALL_ID = 506; // 0x1fa + field public static final int CODE_CALL_BARRED = 240; // 0xf0 + field public static final int CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE = 1100; // 0x44c + field public static final int CODE_CALL_END_CAUSE_CALL_PULL = 1016; // 0x3f8 + field public static final int CODE_CALL_PULL_OUT_OF_SYNC = 1015; // 0x3f7 + field public static final int CODE_DATA_DISABLED = 1406; // 0x57e + field public static final int CODE_DATA_LIMIT_REACHED = 1405; // 0x57d + field public static final int CODE_DIAL_MODIFIED_TO_DIAL = 246; // 0xf6 + field public static final int CODE_DIAL_MODIFIED_TO_DIAL_VIDEO = 247; // 0xf7 + field public static final int CODE_DIAL_MODIFIED_TO_SS = 245; // 0xf5 + field public static final int CODE_DIAL_MODIFIED_TO_USSD = 244; // 0xf4 + field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL = 248; // 0xf8 + field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 249; // 0xf9 + field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_SS = 250; // 0xfa + field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_USSD = 251; // 0xfb + field public static final int CODE_ECBM_NOT_SUPPORTED = 901; // 0x385 + field public static final int CODE_EMERGENCY_PERM_FAILURE = 364; // 0x16c + field public static final int CODE_EMERGENCY_TEMP_FAILURE = 363; // 0x16b + field public static final int CODE_EPDG_TUNNEL_ESTABLISH_FAILURE = 1400; // 0x578 + field public static final int CODE_EPDG_TUNNEL_LOST_CONNECTION = 1402; // 0x57a + field public static final int CODE_EPDG_TUNNEL_REKEY_FAILURE = 1401; // 0x579 + field public static final int CODE_FDN_BLOCKED = 241; // 0xf1 + field public static final int CODE_IKEV2_AUTH_FAILURE = 1408; // 0x580 + field public static final int CODE_IMEI_NOT_ACCEPTED = 243; // 0xf3 + field public static final int CODE_IWLAN_DPD_FAILURE = 1300; // 0x514 + field public static final int CODE_LOCAL_CALL_BUSY = 142; // 0x8e + field public static final int CODE_LOCAL_CALL_CS_RETRY_REQUIRED = 146; // 0x92 + field public static final int CODE_LOCAL_CALL_DECLINE = 143; // 0x8f + field public static final int CODE_LOCAL_CALL_EXCEEDED = 141; // 0x8d + field public static final int CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED = 145; // 0x91 + field public static final int CODE_LOCAL_CALL_TERMINATED = 148; // 0x94 + field public static final int CODE_LOCAL_CALL_VCC_ON_PROGRESSING = 144; // 0x90 + field public static final int CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED = 147; // 0x93 + field public static final int CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE = 108; // 0x6c + field public static final int CODE_LOCAL_HO_NOT_FEASIBLE = 149; // 0x95 + field public static final int CODE_LOCAL_ILLEGAL_ARGUMENT = 101; // 0x65 + field public static final int CODE_LOCAL_ILLEGAL_STATE = 102; // 0x66 + field public static final int CODE_LOCAL_IMS_SERVICE_DOWN = 106; // 0x6a + field public static final int CODE_LOCAL_INTERNAL_ERROR = 103; // 0x67 + field public static final int CODE_LOCAL_LOW_BATTERY = 112; // 0x70 + field public static final int CODE_LOCAL_NETWORK_IP_CHANGED = 124; // 0x7c + field public static final int CODE_LOCAL_NETWORK_NO_LTE_COVERAGE = 122; // 0x7a + field public static final int CODE_LOCAL_NETWORK_NO_SERVICE = 121; // 0x79 + field public static final int CODE_LOCAL_NETWORK_ROAMING = 123; // 0x7b + field public static final int CODE_LOCAL_NOT_REGISTERED = 132; // 0x84 + field public static final int CODE_LOCAL_NO_PENDING_CALL = 107; // 0x6b + field public static final int CODE_LOCAL_POWER_OFF = 111; // 0x6f + field public static final int CODE_LOCAL_SERVICE_UNAVAILABLE = 131; // 0x83 + field public static final int CODE_LOW_BATTERY = 505; // 0x1f9 + field public static final int CODE_MAXIMUM_NUMBER_OF_CALLS_REACHED = 1403; // 0x57b + field public static final int CODE_MEDIA_INIT_FAILED = 401; // 0x191 + field public static final int CODE_MEDIA_NOT_ACCEPTABLE = 403; // 0x193 + field public static final int CODE_MEDIA_NO_DATA = 402; // 0x192 + field public static final int CODE_MEDIA_UNSPECIFIED = 404; // 0x194 + field public static final int CODE_MULTIENDPOINT_NOT_SUPPORTED = 902; // 0x386 + field public static final int CODE_NETWORK_DETACH = 1513; // 0x5e9 + field public static final int CODE_NETWORK_REJECT = 1504; // 0x5e0 + field public static final int CODE_NETWORK_RESP_TIMEOUT = 1503; // 0x5df + field public static final int CODE_NO_VALID_SIM = 1501; // 0x5dd + field public static final int CODE_OEM_CAUSE_1 = 61441; // 0xf001 + field public static final int CODE_OEM_CAUSE_10 = 61450; // 0xf00a + field public static final int CODE_OEM_CAUSE_11 = 61451; // 0xf00b + field public static final int CODE_OEM_CAUSE_12 = 61452; // 0xf00c + field public static final int CODE_OEM_CAUSE_13 = 61453; // 0xf00d + field public static final int CODE_OEM_CAUSE_14 = 61454; // 0xf00e + field public static final int CODE_OEM_CAUSE_15 = 61455; // 0xf00f + field public static final int CODE_OEM_CAUSE_2 = 61442; // 0xf002 + field public static final int CODE_OEM_CAUSE_3 = 61443; // 0xf003 + field public static final int CODE_OEM_CAUSE_4 = 61444; // 0xf004 + field public static final int CODE_OEM_CAUSE_5 = 61445; // 0xf005 + field public static final int CODE_OEM_CAUSE_6 = 61446; // 0xf006 + field public static final int CODE_OEM_CAUSE_7 = 61447; // 0xf007 + field public static final int CODE_OEM_CAUSE_8 = 61448; // 0xf008 + field public static final int CODE_OEM_CAUSE_9 = 61449; // 0xf009 + field public static final int CODE_RADIO_ACCESS_FAILURE = 1505; // 0x5e1 + field public static final int CODE_RADIO_INTERNAL_ERROR = 1502; // 0x5de + field public static final int CODE_RADIO_LINK_FAILURE = 1506; // 0x5e2 + field public static final int CODE_RADIO_LINK_LOST = 1507; // 0x5e3 + field public static final int CODE_RADIO_OFF = 1500; // 0x5dc + field public static final int CODE_RADIO_RELEASE_ABNORMAL = 1511; // 0x5e7 + field public static final int CODE_RADIO_RELEASE_NORMAL = 1510; // 0x5e6 + field public static final int CODE_RADIO_SETUP_FAILURE = 1509; // 0x5e5 + field public static final int CODE_RADIO_UPLINK_FAILURE = 1508; // 0x5e4 + field public static final int CODE_REGISTRATION_ERROR = 1000; // 0x3e8 + field public static final int CODE_REMOTE_CALL_DECLINE = 1404; // 0x57c + field public static final int CODE_SIP_ALTERNATE_EMERGENCY_CALL = 1514; // 0x5ea + field public static final int CODE_SIP_BAD_ADDRESS = 337; // 0x151 + field public static final int CODE_SIP_BAD_REQUEST = 331; // 0x14b + field public static final int CODE_SIP_BUSY = 338; // 0x152 + field public static final int CODE_SIP_CLIENT_ERROR = 342; // 0x156 + field public static final int CODE_SIP_FORBIDDEN = 332; // 0x14c + field public static final int CODE_SIP_GLOBAL_ERROR = 362; // 0x16a + field public static final int CODE_SIP_NOT_ACCEPTABLE = 340; // 0x154 + field public static final int CODE_SIP_NOT_FOUND = 333; // 0x14d + field public static final int CODE_SIP_NOT_REACHABLE = 341; // 0x155 + field public static final int CODE_SIP_NOT_SUPPORTED = 334; // 0x14e + field public static final int CODE_SIP_REDIRECTED = 321; // 0x141 + field public static final int CODE_SIP_REQUEST_CANCELLED = 339; // 0x153 + field public static final int CODE_SIP_REQUEST_TIMEOUT = 335; // 0x14f + field public static final int CODE_SIP_SERVER_ERROR = 354; // 0x162 + field public static final int CODE_SIP_SERVER_INTERNAL_ERROR = 351; // 0x15f + field public static final int CODE_SIP_SERVER_TIMEOUT = 353; // 0x161 + field public static final int CODE_SIP_SERVICE_UNAVAILABLE = 352; // 0x160 + field public static final int CODE_SIP_TEMPRARILY_UNAVAILABLE = 336; // 0x150 + field public static final int CODE_SIP_USER_REJECTED = 361; // 0x169 + field public static final int CODE_SUPP_SVC_CANCELLED = 1202; // 0x4b2 + field public static final int CODE_SUPP_SVC_FAILED = 1201; // 0x4b1 + field public static final int CODE_SUPP_SVC_REINVITE_COLLISION = 1203; // 0x4b3 + field public static final int CODE_TIMEOUT_1XX_WAITING = 201; // 0xc9 + field public static final int CODE_TIMEOUT_NO_ANSWER = 202; // 0xca + field public static final int CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE = 203; // 0xcb + field public static final int CODE_UNSPECIFIED = 0; // 0x0 + field public static final int CODE_USER_DECLINE = 504; // 0x1f8 + field public static final int CODE_USER_IGNORE = 503; // 0x1f7 + field public static final int CODE_USER_NOANSWER = 502; // 0x1f6 + field public static final int CODE_USER_TERMINATED = 501; // 0x1f5 + field public static final int CODE_USER_TERMINATED_BY_REMOTE = 510; // 0x1fe + field public static final int CODE_UT_CB_PASSWORD_MISMATCH = 821; // 0x335 + field public static final int CODE_UT_NETWORK_ERROR = 804; // 0x324 + field public static final int CODE_UT_NOT_SUPPORTED = 801; // 0x321 + field public static final int CODE_UT_OPERATION_NOT_ALLOWED = 803; // 0x323 + field public static final int CODE_UT_SERVICE_UNAVAILABLE = 802; // 0x322 + field public static final int CODE_UT_SS_MODIFIED_TO_DIAL = 822; // 0x336 + field public static final int CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO = 825; // 0x339 + field public static final int CODE_UT_SS_MODIFIED_TO_SS = 824; // 0x338 + field public static final int CODE_UT_SS_MODIFIED_TO_USSD = 823; // 0x337 + field public static final int CODE_WIFI_LOST = 1407; // 0x57f + field public static final android.os.Parcelable.Creator<android.telephony.ims.ImsReasonInfo> CREATOR; + field public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3; // 0x3 + field public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1; // 0x1 + field public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; // 0x2 + field public static final java.lang.String EXTRA_MSG_SERVICE_NOT_AUTHORIZED = "Forbidden. Not Authorized for Service"; + } + public class ImsService extends android.app.Service { ctor public ImsService(); + method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int); + method public android.telephony.ims.feature.RcsFeature createRcsFeature(int); + method public void disableIms(int); + method public void enableIms(int); + method public android.telephony.ims.stub.ImsConfigImplBase getConfig(int); + method public android.telephony.ims.stub.ImsRegistrationImplBase getRegistration(int); + method public final void onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) throws android.os.RemoteException; + method public android.telephony.ims.stub.ImsFeatureConfiguration querySupportedImsFeatures(); + method public void readyForFeatureCreation(); + } + + public final class ImsSsData implements android.os.Parcelable { + ctor public ImsSsData(); + method public int describeContents(); + method public boolean isTypeBarring(); + method public boolean isTypeCf(); + method public boolean isTypeClip(); + method public boolean isTypeClir(); + method public boolean isTypeColp(); + method public boolean isTypeColr(); + method public boolean isTypeCw(); + method public boolean isTypeIcb(); + method public boolean isTypeInterrogation(); + method public boolean isTypeUnConditional(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsData> CREATOR; + field public static final int SS_ACTIVATION = 0; // 0x0 + field public static final int SS_ALL_BARRING = 18; // 0x12 + field public static final int SS_ALL_DATA_TELESERVICES = 3; // 0x3 + field public static final int SS_ALL_TELESERVICES_EXCEPT_SMS = 5; // 0x5 + field public static final int SS_ALL_TELESEVICES = 1; // 0x1 + field public static final int SS_ALL_TELE_AND_BEARER_SERVICES = 0; // 0x0 + field public static final int SS_BAIC = 16; // 0x10 + field public static final int SS_BAIC_ROAMING = 17; // 0x11 + field public static final int SS_BAOC = 13; // 0xd + field public static final int SS_BAOIC = 14; // 0xe + field public static final int SS_BAOIC_EXC_HOME = 15; // 0xf + field public static final int SS_CFU = 0; // 0x0 + field public static final int SS_CFUT = 6; // 0x6 + field public static final int SS_CF_ALL = 4; // 0x4 + field public static final int SS_CF_ALL_CONDITIONAL = 5; // 0x5 + field public static final int SS_CF_BUSY = 1; // 0x1 + field public static final int SS_CF_NOT_REACHABLE = 3; // 0x3 + field public static final int SS_CF_NO_REPLY = 2; // 0x2 + field public static final int SS_CLIP = 7; // 0x7 + field public static final int SS_CLIR = 8; // 0x8 + field public static final int SS_CNAP = 11; // 0xb + field public static final int SS_COLP = 9; // 0x9 + field public static final int SS_COLR = 10; // 0xa + field public static final int SS_DEACTIVATION = 1; // 0x1 + field public static final int SS_ERASURE = 4; // 0x4 + field public static final int SS_INCOMING_BARRING = 20; // 0x14 + field public static final int SS_INCOMING_BARRING_ANONYMOUS = 22; // 0x16 + field public static final int SS_INCOMING_BARRING_DN = 21; // 0x15 + field public static final int SS_INTERROGATION = 2; // 0x2 + field public static final int SS_OUTGOING_BARRING = 19; // 0x13 + field public static final int SS_REGISTRATION = 3; // 0x3 + field public static final int SS_SMS_SERVICES = 4; // 0x4 + field public static final int SS_TELEPHONY = 2; // 0x2 + field public static final int SS_WAIT = 12; // 0xc + } + + public final class ImsSsInfo implements android.os.Parcelable { + ctor public ImsSsInfo(); + method public int describeContents(); + method public java.lang.String getIcbNum(); + method public int getStatus(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsInfo> CREATOR; + field public static final int DISABLED = 0; // 0x0 + field public static final int ENABLED = 1; // 0x1 + field public static final int NOT_REGISTERED = -1; // 0xffffffff + } + + public final class ImsStreamMediaProfile implements android.os.Parcelable { + method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile); + method public int describeContents(); + method public int getAudioDirection(); + method public int getAudioQuality(); + method public int getRttMode(); + method public int getVideoDirection(); + method public int getVideoQuality(); + method public boolean isRttCall(); + method public void setRttMode(int); + method public void writeToParcel(android.os.Parcel, int); + field public static final int AUDIO_QUALITY_AMR = 1; // 0x1 + field public static final int AUDIO_QUALITY_AMR_WB = 2; // 0x2 + field public static final int AUDIO_QUALITY_EVRC = 4; // 0x4 + field public static final int AUDIO_QUALITY_EVRC_B = 5; // 0x5 + field public static final int AUDIO_QUALITY_EVRC_NW = 7; // 0x7 + field public static final int AUDIO_QUALITY_EVRC_WB = 6; // 0x6 + field public static final int AUDIO_QUALITY_EVS_FB = 20; // 0x14 + field public static final int AUDIO_QUALITY_EVS_NB = 17; // 0x11 + field public static final int AUDIO_QUALITY_EVS_SWB = 19; // 0x13 + field public static final int AUDIO_QUALITY_EVS_WB = 18; // 0x12 + field public static final int AUDIO_QUALITY_G711A = 13; // 0xd + field public static final int AUDIO_QUALITY_G711AB = 15; // 0xf + field public static final int AUDIO_QUALITY_G711U = 11; // 0xb + field public static final int AUDIO_QUALITY_G722 = 14; // 0xe + field public static final int AUDIO_QUALITY_G723 = 12; // 0xc + field public static final int AUDIO_QUALITY_G729 = 16; // 0x10 + field public static final int AUDIO_QUALITY_GSM_EFR = 8; // 0x8 + field public static final int AUDIO_QUALITY_GSM_FR = 9; // 0x9 + field public static final int AUDIO_QUALITY_GSM_HR = 10; // 0xa + field public static final int AUDIO_QUALITY_NONE = 0; // 0x0 + field public static final int AUDIO_QUALITY_QCELP13K = 3; // 0x3 + field public static final android.os.Parcelable.Creator<android.telephony.ims.ImsStreamMediaProfile> CREATOR; + field public static final int DIRECTION_INACTIVE = 0; // 0x0 + field public static final int DIRECTION_INVALID = -1; // 0xffffffff + field public static final int DIRECTION_RECEIVE = 1; // 0x1 + field public static final int DIRECTION_SEND = 2; // 0x2 + field public static final int DIRECTION_SEND_RECEIVE = 3; // 0x3 + field public static final int RTT_MODE_DISABLED = 0; // 0x0 + field public static final int RTT_MODE_FULL = 1; // 0x1 + field public static final int VIDEO_QUALITY_NONE = 0; // 0x0 + field public static final int VIDEO_QUALITY_QCIF = 1; // 0x1 + field public static final int VIDEO_QUALITY_QVGA_LANDSCAPE = 2; // 0x2 + field public static final int VIDEO_QUALITY_QVGA_PORTRAIT = 4; // 0x4 + field public static final int VIDEO_QUALITY_VGA_LANDSCAPE = 8; // 0x8 + field public static final int VIDEO_QUALITY_VGA_PORTRAIT = 16; // 0x10 + } + + public final class ImsSuppServiceNotification implements android.os.Parcelable { + ctor public ImsSuppServiceNotification(int, int, int, int, java.lang.String, java.lang.String[]); + method public int describeContents(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSuppServiceNotification> CREATOR; + field public final int code; + field public final java.lang.String[] history; + field public final int index; + field public final int notificationType; + field public final java.lang.String number; + field public final int type; + } + + public class ImsUtListener { + method public void onSupplementaryServiceIndication(android.telephony.ims.ImsSsData); + method public void onUtConfigurationCallBarringQueried(int, android.telephony.ims.ImsSsInfo[]); + method public void onUtConfigurationCallForwardQueried(int, android.telephony.ims.ImsCallForwardInfo[]); + method public void onUtConfigurationCallWaitingQueried(int, android.telephony.ims.ImsSsInfo[]); + method public void onUtConfigurationQueried(int, android.os.Bundle); + method public void onUtConfigurationQueryFailed(int, android.telephony.ims.ImsReasonInfo); + method public void onUtConfigurationUpdateFailed(int, android.telephony.ims.ImsReasonInfo); + method public void onUtConfigurationUpdated(int); + } + + public abstract class ImsVideoCallProvider { + ctor public ImsVideoCallProvider(); + method public void changeCallDataUsage(long); + method public void changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities); + method public void changePeerDimensions(int, int); + method public void changeVideoQuality(int); + method public void handleCallSessionEvent(int); + method public abstract void onRequestCallDataUsage(); + method public abstract void onRequestCameraCapabilities(); + method public abstract void onSendSessionModifyRequest(android.telecom.VideoProfile, android.telecom.VideoProfile); + method public abstract void onSendSessionModifyResponse(android.telecom.VideoProfile); + method public abstract void onSetCamera(java.lang.String); + method public void onSetCamera(java.lang.String, int); + method public abstract void onSetDeviceOrientation(int); + method public abstract void onSetDisplaySurface(android.view.Surface); + method public abstract void onSetPauseImage(android.net.Uri); + method public abstract void onSetPreviewSurface(android.view.Surface); + method public abstract void onSetZoom(float); + method public void receiveSessionModifyRequest(android.telecom.VideoProfile); + method public void receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile); + } + +} + +package android.telephony.ims.feature { + + public final class CapabilityChangeRequest implements android.os.Parcelable { + method public void addCapabilitiesToDisableForTech(int, int); + method public void addCapabilitiesToEnableForTech(int, int); + method public int describeContents(); + method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToDisable(); + method public java.util.List<android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair> getCapabilitiesToEnable(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.feature.CapabilityChangeRequest> CREATOR; + } + + public static class CapabilityChangeRequest.CapabilityPair { + ctor public CapabilityChangeRequest.CapabilityPair(int, int); + method public int getCapability(); + method public int getRadioTech(); + } + + public abstract class ImsFeature { + ctor public ImsFeature(); + method public abstract void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy); + method public abstract void onFeatureReady(); + method public abstract void onFeatureRemoved(); + method public final void setFeatureState(int); + field public static final int CAPABILITY_ERROR_GENERIC = -1; // 0xffffffff + field public static final int CAPABILITY_SUCCESS = 0; // 0x0 + field public static final int FEATURE_EMERGENCY_MMTEL = 0; // 0x0 + field public static final int FEATURE_MMTEL = 1; // 0x1 + field public static final int FEATURE_RCS = 2; // 0x2 + field public static final int STATE_INITIALIZING = 1; // 0x1 + field public static final int STATE_READY = 2; // 0x2 + field public static final int STATE_UNAVAILABLE = 0; // 0x0 + } + + protected static class ImsFeature.CapabilityCallbackProxy { + method public void onChangeCapabilityConfigurationError(int, int, int); + } + + public class MmTelFeature extends android.telephony.ims.feature.ImsFeature { + ctor public MmTelFeature(); + method public void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy); + method public android.telephony.ims.ImsCallProfile createCallProfile(int, int); + method public android.telephony.ims.stub.ImsCallSessionImplBase createCallSession(android.telephony.ims.ImsCallProfile); + method public android.telephony.ims.stub.ImsEcbmImplBase getEcbm(); + method public android.telephony.ims.stub.ImsMultiEndpointImplBase getMultiEndpoint(); + method public android.telephony.ims.stub.ImsSmsImplBase getSmsImplementation(); + method public android.telephony.ims.stub.ImsUtImplBase getUt(); + method public final void notifyCapabilitiesStatusChanged(android.telephony.ims.feature.MmTelFeature.MmTelCapabilities); + method public final void notifyIncomingCall(android.telephony.ims.stub.ImsCallSessionImplBase, android.os.Bundle); + method public final void notifyVoiceMessageCountUpdate(int); + method public void onFeatureReady(); + method public void onFeatureRemoved(); + method public boolean queryCapabilityConfiguration(int, int); + method public final android.telephony.ims.feature.MmTelFeature.MmTelCapabilities queryCapabilityStatus(); + method public void setUiTtyMode(int, android.os.Message); + method public int shouldProcessCall(java.lang.String[]); + field public static final int PROCESS_CALL_CSFB = 1; // 0x1 + field public static final int PROCESS_CALL_EMERGENCY_CSFB = 2; // 0x2 + field public static final int PROCESS_CALL_IMS = 0; // 0x0 + } + + public static class MmTelFeature.MmTelCapabilities { + ctor public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities); + ctor public MmTelFeature.MmTelCapabilities(int); + method public final void addCapabilities(int); + method public final boolean isCapable(int); + method public final void removeCapabilities(int); + field public static final int CAPABILITY_TYPE_SMS = 8; // 0x8 + field public static final int CAPABILITY_TYPE_UT = 4; // 0x4 + field public static final int CAPABILITY_TYPE_VIDEO = 2; // 0x2 + field public static final int CAPABILITY_TYPE_VOICE = 1; // 0x1 + } + + public static abstract class MmTelFeature.MmTelCapabilities.MmTelCapability implements java.lang.annotation.Annotation { + } + + public static abstract class MmTelFeature.ProcessCallResult implements java.lang.annotation.Annotation { + } + + public class RcsFeature extends android.telephony.ims.feature.ImsFeature { + ctor public RcsFeature(); + method public void changeEnabledCapabilities(android.telephony.ims.feature.CapabilityChangeRequest, android.telephony.ims.feature.ImsFeature.CapabilityCallbackProxy); + method public void onFeatureReady(); + method public void onFeatureRemoved(); } } -package android.telephony.ims.internal.stub { +package android.telephony.ims.stub { + + public class ImsCallSessionImplBase implements java.lang.AutoCloseable { + ctor public ImsCallSessionImplBase(); + method public void accept(int, android.telephony.ims.ImsStreamMediaProfile); + method public void close(); + method public void extendToConference(java.lang.String[]); + method public java.lang.String getCallId(); + method public android.telephony.ims.ImsCallProfile getCallProfile(); + method public android.telephony.ims.ImsVideoCallProvider getImsVideoCallProvider(); + method public android.telephony.ims.ImsCallProfile getLocalCallProfile(); + method public java.lang.String getProperty(java.lang.String); + method public android.telephony.ims.ImsCallProfile getRemoteCallProfile(); + method public int getState(); + method public void hold(android.telephony.ims.ImsStreamMediaProfile); + method public void inviteParticipants(java.lang.String[]); + method public boolean isInCall(); + method public boolean isMultiparty(); + method public void merge(); + method public void reject(int); + method public void removeParticipants(java.lang.String[]); + method public void resume(android.telephony.ims.ImsStreamMediaProfile); + method public void sendDtmf(char, android.os.Message); + method public void sendRttMessage(java.lang.String); + method public void sendRttModifyRequest(android.telephony.ims.ImsCallProfile); + method public void sendRttModifyResponse(boolean); + method public void sendUssd(java.lang.String); + method public void setListener(android.telephony.ims.ImsCallSessionListener); + method public void setMute(boolean); + method public void start(java.lang.String, android.telephony.ims.ImsCallProfile); + method public void startConference(java.lang.String[], android.telephony.ims.ImsCallProfile); + method public void startDtmf(char); + method public void stopDtmf(); + method public void terminate(int); + method public void update(int, android.telephony.ims.ImsStreamMediaProfile); + field public static final int USSD_MODE_NOTIFY = 0; // 0x0 + field public static final int USSD_MODE_REQUEST = 1; // 0x1 + } + + public static class ImsCallSessionImplBase.State { + method public static java.lang.String toString(int); + field public static final int ESTABLISHED = 4; // 0x4 + field public static final int ESTABLISHING = 3; // 0x3 + field public static final int IDLE = 0; // 0x0 + field public static final int INITIATED = 1; // 0x1 + field public static final int INVALID = -1; // 0xffffffff + field public static final int NEGOTIATING = 2; // 0x2 + field public static final int REESTABLISHING = 6; // 0x6 + field public static final int RENEGOTIATING = 5; // 0x5 + field public static final int TERMINATED = 8; // 0x8 + field public static final int TERMINATING = 7; // 0x7 + } + + public class ImsConfigImplBase { + ctor public ImsConfigImplBase(); + method public int getConfigInt(int); + method public java.lang.String getConfigString(int); + method public final void notifyProvisionedValueChanged(int, int); + method public final void notifyProvisionedValueChanged(int, java.lang.String); + method public int setConfig(int, int); + method public int setConfig(int, java.lang.String); + field public static final int CONFIG_RESULT_FAILED = 1; // 0x1 + field public static final int CONFIG_RESULT_SUCCESS = 0; // 0x0 + field public static final int CONFIG_RESULT_UNKNOWN = -1; // 0xffffffff + } + + public class ImsEcbmImplBase { + ctor public ImsEcbmImplBase(); + method public final void enteredEcbm(); + method public void exitEmergencyCallbackMode(); + method public final void exitedEcbm(); + } + + public final class ImsFeatureConfiguration implements android.os.Parcelable { + ctor public ImsFeatureConfiguration(); + method public int describeContents(); + method public int[] getServiceFeatures(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.ims.stub.ImsFeatureConfiguration> CREATOR; + } + + public static class ImsFeatureConfiguration.Builder { + ctor public ImsFeatureConfiguration.Builder(); + method public android.telephony.ims.stub.ImsFeatureConfiguration.Builder addFeature(int); + method public android.telephony.ims.stub.ImsFeatureConfiguration build(); + } - public class SmsImplBase { - ctor public SmsImplBase(); + public class ImsMultiEndpointImplBase { + ctor public ImsMultiEndpointImplBase(); + method public final void onImsExternalCallStateUpdate(java.util.List<android.telephony.ims.ImsExternalCallState>); + method public void requestImsExternalCallStateInfo(); + } + + public class ImsRegistrationImplBase { + ctor public ImsRegistrationImplBase(); + method public final void onDeregistered(android.telephony.ims.ImsReasonInfo); + method public final void onRegistered(int); + method public final void onRegistering(int); + method public final void onSubscriberAssociatedUriChanged(android.net.Uri[]); + method public final void onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo); + field public static final int REGISTRATION_TECH_IWLAN = 1; // 0x1 + field public static final int REGISTRATION_TECH_LTE = 0; // 0x0 + field public static final int REGISTRATION_TECH_NONE = -1; // 0xffffffff + } + + public class ImsSmsImplBase { + ctor public ImsSmsImplBase(); method public void acknowledgeSms(int, int, int); method public void acknowledgeSmsReport(int, int, int); method public java.lang.String getSmsFormat(); @@ -4328,6 +4982,29 @@ package android.telephony.ims.internal.stub { field public static final int STATUS_REPORT_STATUS_OK = 1; // 0x1 } + public class ImsUtImplBase { + ctor public ImsUtImplBase(); + method public void close(); + method public int queryCallBarring(int); + method public int queryCallBarringForServiceClass(int, int); + method public int queryCallForward(int, java.lang.String); + method public int queryCallWaiting(); + method public int queryClip(); + method public int queryClir(); + method public int queryColp(); + method public int queryColr(); + method public void setListener(android.telephony.ims.ImsUtListener); + method public int transact(android.os.Bundle); + method public int updateCallBarring(int, int, java.lang.String[]); + method public int updateCallBarringForServiceClass(int, int, java.lang.String[], int); + method public int updateCallForward(int, int, java.lang.String, int, int); + method public int updateCallWaiting(boolean, int); + method public int updateClip(boolean); + method public int updateClir(int); + method public int updateColp(boolean); + method public int updateColr(int); + } + } package android.telephony.mbms { diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java index 09f96840f918..09a5b593e521 100644 --- a/core/java/android/bluetooth/BluetoothSocket.java +++ b/core/java/android/bluetooth/BluetoothSocket.java @@ -676,6 +676,35 @@ public final class BluetoothSocket implements Closeable { mExcludeSdp = excludeSdp; } + /** + * Set the LE Transmit Data Length to be the maximum that the BT Controller is capable of. This + * parameter is used by the BT Controller to set the maximum transmission packet size on this + * connection. This function is currently used for testing only. + * @hide + */ + public void requestMaximumTxDataLength() throws IOException { + if (mDevice == null) { + throw new IOException("requestMaximumTxDataLength is called on null device"); + } + + try { + if (mSocketState == SocketState.CLOSED) { + throw new IOException("socket closed"); + } + IBluetooth bluetoothProxy = + BluetoothAdapter.getDefaultAdapter().getBluetoothService(null); + if (bluetoothProxy == null) { + throw new IOException("Bluetooth is off"); + } + + if (DBG) Log.d(TAG, "requestMaximumTxDataLength"); + bluetoothProxy.getSocketManager().requestMaximumTxDataLength(mDevice); + } catch (RemoteException e) { + Log.e(TAG, Log.getStackTraceString(new Throwable())); + throw new IOException("unable to send RPC: " + e.getMessage()); + } + } + private String convertAddr(final byte[] addr) { return String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index ada9bd76935e..b165ab122ba1 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1765,6 +1765,15 @@ <permission android:name="android.permission.BIND_TELEPHONY_DATA_SERVICE" android:protectionLevel="signature" /> + <!-- Must be required by a NetworkService to ensure that only the + system can bind to it. + <p>Protection level: signature + @SystemApi + @hide + --> + <permission android:name="android.permission.BIND_TELEPHONY_NETWORK_SERVICE" + android:protectionLevel="signature" /> + <!-- Allows an application to manage embedded subscriptions (those on a eUICC) through EuiccManager APIs. <p>Protection level: signature|privileged|development diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index a8a57000ba95..701ed556bc70 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3122,4 +3122,11 @@ <bool name="config_display_no_service_when_sim_unready">false</bool> <bool name="config_supportBluetoothPersistedState">true</bool> + + <!-- Cellular network service package name to bind to by default. --> + <string name="config_wwan_network_service_package" translatable="false">com.android.phone</string> + + <!-- IWLAN network service package name to bind to by default. If none is specified in an overlay, an + empty string is passed in --> + <string name="config_wlan_network_service_package" translatable="false"></string> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 08be23d94a59..0aec47e66aa1 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -266,6 +266,8 @@ <java-symbol type="bool" name="config_dynamic_bind_ims" /> <java-symbol type="string" name="config_wwan_data_service_package" /> <java-symbol type="string" name="config_wlan_data_service_package" /> + <java-symbol type="string" name="config_wwan_network_service_package" /> + <java-symbol type="string" name="config_wlan_network_service_package" /> <java-symbol type="bool" name="config_networkSamplingWakesDevice" /> <java-symbol type="bool" name="config_showMenuShortcutsWhenKeyboardPresent" /> <java-symbol type="bool" name="config_sip_wifi_only" /> diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 5b6577fd98aa..6974bbb08cc0 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -147,7 +147,6 @@ applications that come with the platform <permission name="android.permission.LOCAL_MAC_ADDRESS"/> <permission name="android.permission.MANAGE_USERS"/> <permission name="android.permission.MODIFY_PHONE_STATE"/> - <permission name="android.permission.PACKAGE_USAGE_STATS"/> <permission name="android.permission.PERFORM_CDMA_PROVISIONING"/> <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/> <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 6743484b91c4..6747be340d46 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -35,7 +35,6 @@ import android.os.UserHandle; import android.telephony.CellInfo; import android.telephony.CellLocation; import android.telephony.DisconnectCause; -import android.telephony.LocationAccessPolicy; import android.telephony.PhoneStateListener; import android.telephony.PreciseCallState; import android.telephony.PreciseDataConnectionState; @@ -94,8 +93,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { IPhoneStateListener callback; IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback; - int callerUid; - int callerPid; + int callerUserId; int events; @@ -119,7 +117,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { + " callback=" + callback + " onSubscriptionsChangedListenererCallback=" + onSubscriptionsChangedListenerCallback - + " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId + + " callerUserId=" + callerUserId + " subId=" + subId + " phoneId=" + phoneId + " events=" + Integer.toHexString(events) + " canReadPhoneState=" + canReadPhoneState + "}"; } @@ -358,8 +356,6 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { public void addOnSubscriptionsChangedListener(String callingPackage, IOnSubscriptionsChangedListener callback) { int callerUserId = UserHandle.getCallingUserId(); - mContext.getSystemService(AppOpsManager.class) - .checkPackage(Binder.getCallingUid(), callingPackage); if (VDBG) { log("listen oscl: E pkg=" + callingPackage + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId + " callback=" + callback @@ -403,8 +399,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { r.onSubscriptionsChangedListenerCallback = callback; r.callingPackage = callingPackage; - r.callerUid = Binder.getCallingUid(); - r.callerPid = Binder.getCallingPid(); + r.callerUserId = callerUserId; r.events = 0; r.canReadPhoneState = true; // permission has been enforced above if (DBG) { @@ -475,8 +470,6 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private void listen(String callingPackage, IPhoneStateListener callback, int events, boolean notifyNow, int subId) { int callerUserId = UserHandle.getCallingUserId(); - mContext.getSystemService(AppOpsManager.class) - .checkPackage(Binder.getCallingUid(), callingPackage); if (VDBG) { log("listen: E pkg=" + callingPackage + " events=0x" + Integer.toHexString(events) + " notifyNow=" + notifyNow + " subId=" + subId + " myUserId=" @@ -521,8 +514,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { r.callback = callback; r.callingPackage = callingPackage; - r.callerUid = Binder.getCallingUid(); - r.callerPid = Binder.getCallingPid(); + r.callerUserId = callerUserId; boolean isPhoneStateEvent = (events & (CHECK_PHONE_STATE_PERMISSION_MASK | ENFORCE_PHONE_STATE_PERMISSION_MASK)) != 0; r.canReadPhoneState = isPhoneStateEvent && canReadPhoneState(callingPackage); @@ -580,10 +572,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { try { if (DBG_LOC) log("listen: mCellLocation = " + mCellLocation[phoneId]); - if (checkLocationAccess(r)) { - r.callback.onCellLocationChanged( - new Bundle(mCellLocation[phoneId])); - } + r.callback.onCellLocationChanged( + new Bundle(mCellLocation[phoneId])); } catch (RemoteException ex) { remove(r.binder); } @@ -629,9 +619,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { try { if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = " + mCellInfo.get(phoneId)); - if (checkLocationAccess(r)) { - r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); - } + r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); } catch (RemoteException ex) { remove(r.binder); } @@ -991,8 +979,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { mCellInfo.set(phoneId, cellInfo); for (Record r : mRecords) { if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) && - idMatch(r.subId, subId, phoneId) && - checkLocationAccess(r)) { + idMatch(r.subId, subId, phoneId)) { try { if (DBG_LOC) { log("notifyCellInfo: mCellInfo=" + cellInfo + " r=" + r); @@ -1275,8 +1262,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { mCellLocation[phoneId] = cellLocation; for (Record r : mRecords) { if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) && - idMatch(r.subId, subId, phoneId) && - checkLocationAccess(r)) { + idMatch(r.subId, subId, phoneId)) { try { if (DBG_LOC) { log("notifyCellLocation: cellLocation=" + cellLocation @@ -1720,11 +1706,10 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { boolean valid = false; try { foregroundUser = ActivityManager.getCurrentUser(); - valid = UserHandle.getUserId(r.callerUid) == foregroundUser - && r.matchPhoneStateListenerEvent(events); + valid = r.callerUserId == foregroundUser && r.matchPhoneStateListenerEvent(events); if (DBG | DBG_LOC) { log("validateEventsAndUserLocked: valid=" + valid - + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser + + " r.callerUserId=" + r.callerUserId + " foregroundUser=" + foregroundUser + " r.events=" + r.events + " events=" + events); } } finally { @@ -1756,16 +1741,6 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - private boolean checkLocationAccess(Record r) { - long token = Binder.clearCallingIdentity(); - try { - return LocationAccessPolicy.canAccessCellLocation(mContext, - r.callingPackage, r.callerUid, r.callerPid); - } finally { - Binder.restoreCallingIdentity(token); - } - } - private void checkPossibleMissNotify(Record r, int phoneId) { int events = r.events; @@ -1813,9 +1788,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = " + mCellInfo.get(phoneId)); } - if (checkLocationAccess(r)) { - r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); - } + r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); } catch (RemoteException ex) { mRemoveList.add(r.binder); } @@ -1863,9 +1836,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { try { if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = " + mCellLocation[phoneId]); - if (checkLocationAccess(r)) { - r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId])); - } + r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId])); } catch (RemoteException ex) { mRemoveList.add(r.binder); } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index dc3195c5564c..046b8be90a77 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -27,8 +27,8 @@ import android.os.PersistableBundle; import android.os.RemoteException; import android.os.ServiceManager; import android.service.carrier.CarrierService; +import android.telephony.ims.ImsReasonInfo; -import com.android.ims.ImsReasonInfo; import com.android.internal.telephony.ICarrierConfigLoader; /** @@ -1423,7 +1423,7 @@ public class CarrierConfigManager { "allow_video_calling_fallback_bool"; /** - * Defines operator-specific {@link com.android.ims.ImsReasonInfo} mappings. + * Defines operator-specific {@link ImsReasonInfo} mappings. * * Format: "ORIGINAL_CODE|MESSAGE|NEW_CODE" * Where {@code ORIGINAL_CODE} corresponds to a {@link ImsReasonInfo#getCode()} code, @@ -1800,6 +1800,22 @@ public class CarrierConfigManager { public static final String KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY = "lte_rsrp_thresholds_int_array"; + /** + * Decides when clients try to bind to iwlan network service, which package name will + * the binding intent go to. + * @hide + */ + public static final String KEY_CARRIER_NETWORK_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING + = "carrier_network_service_wlan_package_override_string"; + + /** + * Decides when clients try to bind to wwan (cellular) network service, which package name will + * the binding intent go to. + * @hide + */ + public static final String KEY_CARRIER_NETWORK_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING + = "carrier_network_service_wwan_package_override_string"; + /** The default value for every variable. */ private final static PersistableBundle sDefaults; @@ -1839,6 +1855,8 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL, true); sDefaults.putString(KEY_CARRIER_DATA_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING, ""); sDefaults.putString(KEY_CARRIER_DATA_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING, ""); + sDefaults.putString(KEY_CARRIER_NETWORK_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING, ""); + sDefaults.putString(KEY_CARRIER_NETWORK_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING, ""); sDefaults.putString(KEY_CARRIER_INSTANT_LETTERING_INVALID_CHARS_STRING, ""); sDefaults.putString(KEY_CARRIER_INSTANT_LETTERING_ESCAPED_CHARS_STRING, ""); sDefaults.putString(KEY_CARRIER_INSTANT_LETTERING_ENCODING_STRING, ""); diff --git a/telephony/java/android/telephony/LocationAccessPolicy.java b/telephony/java/android/telephony/LocationAccessPolicy.java deleted file mode 100644 index b362df9ff677..000000000000 --- a/telephony/java/android/telephony/LocationAccessPolicy.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package android.telephony; - -import android.Manifest; -import android.annotation.NonNull; -import android.annotation.UserIdInt; -import android.app.ActivityManager; -import android.app.AppOpsManager; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.content.pm.UserInfo; -import android.location.LocationManager; -import android.os.Binder; -import android.os.Build; -import android.os.Process; -import android.os.Trace; -import android.os.UserHandle; -import android.os.UserManager; -import android.provider.Settings; -import android.util.SparseBooleanArray; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Helper for performing location access checks. - * @hide - */ -public final class LocationAccessPolicy { - /** - * API to determine if the caller has permissions to get cell location. - * - * @param pkgName Package name of the application requesting access - * @param uid The uid of the package - * @param pid The pid of the package - * @return boolean true or false if permissions is granted - */ - public static boolean canAccessCellLocation(@NonNull Context context, @NonNull String pkgName, - int uid, int pid) throws SecurityException { - Trace.beginSection("TelephonyLocationCheck"); - try { - // Always allow the phone process to access location. This avoid breaking legacy code - // that rely on public-facing APIs to access cell location, and it doesn't create a - // info leak risk because the cell location is stored in the phone process anyway. - if (uid == Process.PHONE_UID) { - return true; - } - - // We always require the location permission and also require the - // location mode to be on for non-legacy apps. Legacy apps are - // required to be in the foreground to at least mitigate the case - // where a legacy app the user is not using tracks their location. - // Granting ACCESS_FINE_LOCATION to an app automatically grants it - // ACCESS_COARSE_LOCATION. - - if (context.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, pid, uid) == - PackageManager.PERMISSION_DENIED) { - return false; - } - final int opCode = AppOpsManager.permissionToOpCode( - Manifest.permission.ACCESS_COARSE_LOCATION); - if (opCode != AppOpsManager.OP_NONE && context.getSystemService(AppOpsManager.class) - .noteOpNoThrow(opCode, uid, pkgName) != AppOpsManager.MODE_ALLOWED) { - return false; - } - if (!isLocationModeEnabled(context, UserHandle.getUserId(uid)) - && !isLegacyForeground(context, pkgName, uid)) { - return false; - } - // If the user or profile is current, permission is granted. - // Otherwise, uid must have INTERACT_ACROSS_USERS_FULL permission. - return isCurrentProfile(context, uid) || checkInteractAcrossUsersFull(context); - } finally { - Trace.endSection(); - } - } - - private static boolean isLocationModeEnabled(@NonNull Context context, @UserIdInt int userId) { - int locationMode = Settings.Secure.getIntForUser(context.getContentResolver(), - Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF, userId); - return locationMode != Settings.Secure.LOCATION_MODE_OFF - && locationMode != Settings.Secure.LOCATION_MODE_SENSORS_ONLY; - } - - private static boolean isLegacyForeground(@NonNull Context context, @NonNull String pkgName, - int uid) { - long token = Binder.clearCallingIdentity(); - try { - return isLegacyVersion(context, pkgName) && isForegroundApp(context, uid); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - private static boolean isLegacyVersion(@NonNull Context context, @NonNull String pkgName) { - try { - if (context.getPackageManager().getApplicationInfo(pkgName, 0) - .targetSdkVersion <= Build.VERSION_CODES.O) { - return true; - } - } catch (PackageManager.NameNotFoundException e) { - // In case of exception, assume known app (more strict checking) - // Note: This case will never happen since checkPackage is - // called to verify validity before checking app's version. - } - return false; - } - - private static boolean isForegroundApp(@NonNull Context context, int uid) { - final ActivityManager am = context.getSystemService(ActivityManager.class); - return am.getUidImportance(uid) <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; - } - - private static boolean checkInteractAcrossUsersFull(@NonNull Context context) { - return context.checkCallingOrSelfPermission( - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) - == PackageManager.PERMISSION_GRANTED; - } - - private static boolean isCurrentProfile(@NonNull Context context, int uid) { - long token = Binder.clearCallingIdentity(); - try { - final int currentUser = ActivityManager.getCurrentUser(); - final int callingUserId = UserHandle.getUserId(uid); - if (callingUserId == currentUser) { - return true; - } else { - List<UserInfo> userProfiles = context.getSystemService( - UserManager.class).getProfiles(currentUser); - for (UserInfo user : userProfiles) { - if (user.id == callingUserId) { - return true; - } - } - } - return false; - } finally { - Binder.restoreCallingIdentity(token); - } - } -} diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java index 4f137bea69f7..bba779d0c175 100644 --- a/telephony/java/android/telephony/NetworkRegistrationState.java +++ b/telephony/java/android/telephony/NetworkRegistrationState.java @@ -298,9 +298,9 @@ public class NetworkRegistrationState implements Parcelable { && mEmergencyOnly == other.mEmergencyOnly && (mAvailableServices == other.mAvailableServices || Arrays.equals(mAvailableServices, other.mAvailableServices)) - && mCellIdentity == other.mCellIdentity - && mVoiceSpecificStates == other.mVoiceSpecificStates - && mDataSpecificStates == other.mDataSpecificStates; + && equals(mCellIdentity, other.mCellIdentity) + && equals(mVoiceSpecificStates, other.mVoiceSpecificStates) + && equals(mDataSpecificStates, other.mDataSpecificStates); } @Override @@ -329,4 +329,14 @@ public class NetworkRegistrationState implements Parcelable { return new NetworkRegistrationState[size]; } }; + + private static boolean equals(Object o1, Object o2) { + if (o1 == o2) { + return true; + } else if (o1 == null) { + return false; + } else { + return o1.equals(o2); + } + } } diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java index 94921de6829b..35682a74744e 100644 --- a/telephony/java/android/telephony/NetworkService.java +++ b/telephony/java/android/telephony/NetworkService.java @@ -28,6 +28,8 @@ import android.os.Message; import android.os.RemoteException; import android.util.SparseArray; +import com.android.internal.annotations.VisibleForTesting; + import java.util.ArrayList; import java.util.List; @@ -38,7 +40,7 @@ import java.util.List; * follow the following format: * ... * <service android:name=".xxxNetworkService" - * android:permission="android.permission.BIND_NETWORK_SERVICE" > + * android:permission="android.permission.BIND_TELEPHONY_NETWORK_SERVICE" > * <intent-filter> * <action android:name="android.telephony.NetworkService" /> * </intent-filter> @@ -68,7 +70,11 @@ public abstract class NetworkService extends Service { private final SparseArray<NetworkServiceProvider> mServiceMap = new SparseArray<>(); - private final INetworkServiceWrapper mBinder = new INetworkServiceWrapper(); + /** + * @hide + */ + @VisibleForTesting + public final INetworkServiceWrapper mBinder = new INetworkServiceWrapper(); /** * The abstract class of the actual network service implementation. The network service provider diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 1176491907ce..cb867abb74d4 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -94,47 +94,6 @@ public class ServiceState implements Parcelable { */ public static final int DUPLEX_MODE_TDD = 2; - /** - * RIL level registration state values from ril.h - * ((const char **)response)[0] is registration state 0-6, - * 0 - Not registered, MT is not currently searching - * a new operator to register - * 1 - Registered, home network - * 2 - Not registered, but MT is currently searching - * a new operator to register - * 3 - Registration denied - * 4 - Unknown - * 5 - Registered, roaming - * 10 - Same as 0, but indicates that emergency calls - * are enabled. - * 12 - Same as 2, but indicates that emergency calls - * are enabled. - * 13 - Same as 3, but indicates that emergency calls - * are enabled. - * 14 - Same as 4, but indicates that emergency calls - * are enabled. - * @hide - */ - public static final int RIL_REG_STATE_NOT_REG = 0; - /** @hide */ - public static final int RIL_REG_STATE_HOME = 1; - /** @hide */ - public static final int RIL_REG_STATE_SEARCHING = 2; - /** @hide */ - public static final int RIL_REG_STATE_DENIED = 3; - /** @hide */ - public static final int RIL_REG_STATE_UNKNOWN = 4; - /** @hide */ - public static final int RIL_REG_STATE_ROAMING = 5; - /** @hide */ - public static final int RIL_REG_STATE_NOT_REG_EMERGENCY_CALL_ENABLED = 10; - /** @hide */ - public static final int RIL_REG_STATE_SEARCHING_EMERGENCY_CALL_ENABLED = 12; - /** @hide */ - public static final int RIL_REG_STATE_DENIED_EMERGENCY_CALL_ENABLED = 13; - /** @hide */ - public static final int RIL_REG_STATE_UNKNOWN_EMERGENCY_CALL_ENABLED = 14; - /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "RIL_RADIO_TECHNOLOGY_" }, @@ -233,22 +192,6 @@ public class ServiceState implements Parcelable { | (1 << (RIL_RADIO_TECHNOLOGY_EVDO_B - 1)) | (1 << (RIL_RADIO_TECHNOLOGY_EHRPD - 1)); - /** - * Available registration states for GSM, UMTS and CDMA. - */ - /** @hide */ - public static final int REGISTRATION_STATE_NOT_REGISTERED_AND_NOT_SEARCHING = 0; - /** @hide */ - public static final int REGISTRATION_STATE_HOME_NETWORK = 1; - /** @hide */ - public static final int REGISTRATION_STATE_NOT_REGISTERED_AND_SEARCHING = 2; - /** @hide */ - public static final int REGISTRATION_STATE_REGISTRATION_DENIED = 3; - /** @hide */ - public static final int REGISTRATION_STATE_UNKNOWN = 4; - /** @hide */ - public static final int REGISTRATION_STATE_ROAMING = 5; - private int mVoiceRegState = STATE_OUT_OF_SERVICE; private int mDataRegState = STATE_OUT_OF_SERVICE; @@ -1373,6 +1316,51 @@ public class ServiceState implements Parcelable { } /** @hide */ + public static int networkTypeToRilRadioTechnology(int networkType) { + switch(networkType) { + case TelephonyManager.NETWORK_TYPE_GPRS: + return ServiceState.RIL_RADIO_TECHNOLOGY_GPRS; + case TelephonyManager.NETWORK_TYPE_EDGE: + return ServiceState.RIL_RADIO_TECHNOLOGY_EDGE; + case TelephonyManager.NETWORK_TYPE_UMTS: + return ServiceState.RIL_RADIO_TECHNOLOGY_UMTS; + case TelephonyManager.NETWORK_TYPE_HSDPA: + return ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA; + case TelephonyManager.NETWORK_TYPE_HSUPA: + return ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA; + case TelephonyManager.NETWORK_TYPE_HSPA: + return ServiceState.RIL_RADIO_TECHNOLOGY_HSPA; + case TelephonyManager.NETWORK_TYPE_CDMA: + return ServiceState.RIL_RADIO_TECHNOLOGY_IS95A; + case TelephonyManager.NETWORK_TYPE_1xRTT: + return ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT; + case TelephonyManager.NETWORK_TYPE_EVDO_0: + return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0; + case TelephonyManager.NETWORK_TYPE_EVDO_A: + return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A; + case TelephonyManager.NETWORK_TYPE_EVDO_B: + return ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B; + case TelephonyManager.NETWORK_TYPE_EHRPD: + return ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD; + case TelephonyManager.NETWORK_TYPE_LTE: + return ServiceState.RIL_RADIO_TECHNOLOGY_LTE; + case TelephonyManager.NETWORK_TYPE_HSPAP: + return ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP; + case TelephonyManager.NETWORK_TYPE_GSM: + return ServiceState.RIL_RADIO_TECHNOLOGY_GSM; + case TelephonyManager.NETWORK_TYPE_TD_SCDMA: + return ServiceState.RIL_RADIO_TECHNOLOGY_TD_SCDMA; + case TelephonyManager.NETWORK_TYPE_IWLAN: + return ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN; + case TelephonyManager.NETWORK_TYPE_LTE_CA: + return ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA; + default: + return ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN; + } + } + + + /** @hide */ public int getDataNetworkType() { return rilRadioTechnologyToNetworkType(mRilDataRadioTechnology); } diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 137f491b3e09..1fae04b17d03 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -541,9 +541,9 @@ public class SubscriptionManager { * onSubscriptionsChanged overridden. */ public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { - String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>"; + String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>"; if (DBG) { - logd("register OnSubscriptionsChangedListener pkgName=" + pkgName + logd("register OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug + " listener=" + listener); } try { @@ -552,7 +552,7 @@ public class SubscriptionManager { ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( "telephony.registry")); if (tr != null) { - tr.addOnSubscriptionsChangedListener(pkgName, listener.callback); + tr.addOnSubscriptionsChangedListener(pkgForDebug, listener.callback); } } catch (RemoteException ex) { // Should not happen diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 4138e2950d93..96ed20b841bd 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -47,12 +47,13 @@ import android.service.carrier.CarrierIdentifier; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telephony.VisualVoicemailService.VisualVoicemailTask; +import android.telephony.ims.aidl.IImsConfig; +import android.telephony.ims.aidl.IImsMmTelFeature; +import android.telephony.ims.aidl.IImsRcsFeature; +import android.telephony.ims.aidl.IImsRegistration; import android.telephony.ims.feature.ImsFeature; import android.util.Log; -import com.android.ims.internal.IImsMMTelFeature; -import com.android.ims.internal.IImsRcsFeature; -import com.android.ims.internal.IImsRegistration; import com.android.ims.internal.IImsServiceFeatureCallback; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telecom.ITelecomService; @@ -4889,57 +4890,60 @@ public class TelephonyManager { } } - /** @hide */ - @IntDef({ImsFeature.EMERGENCY_MMTEL, ImsFeature.MMTEL, ImsFeature.RCS}) - @Retention(RetentionPolicy.SOURCE) - public @interface Feature {} + /** + * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability + * status updates, if not already enabled. + * @hide + */ + public void enableIms(int slotId) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + telephony.enableIms(slotId); + } + } catch (RemoteException e) { + Rlog.e(TAG, "enableIms, RemoteException: " + + e.getMessage()); + } + } /** - * Returns the {@link IImsMMTelFeature} that corresponds to the given slot Id and MMTel - * feature or {@link null} if the service is not available. If an MMTelFeature is available, the - * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates. - * @param slotIndex The SIM slot that we are requesting the {@link IImsMMTelFeature} for. - * @param callback Listener that will send updates to ImsManager when there are updates to - * ImsServiceController. - * @return {@link IImsMMTelFeature} interface for the feature specified or {@code null} if - * it is unavailable. + * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature + * status updates to disabled. * @hide */ - public @Nullable IImsMMTelFeature getImsMMTelFeatureAndListen(int slotIndex, - IImsServiceFeatureCallback callback) { + public void disableIms(int slotId) { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getMMTelFeatureAndListen(slotIndex, callback); + telephony.disableIms(slotId); } } catch (RemoteException e) { - Rlog.e(TAG, "getImsMMTelFeatureAndListen, RemoteException: " + Rlog.e(TAG, "disableIms, RemoteException: " + e.getMessage()); } - return null; } /** - * Returns the {@link IImsMMTelFeature} that corresponds to the given slot Id and MMTel - * feature for emergency calling or {@link null} if the service is not available. If an - * MMTelFeature is available, the {@link IImsServiceFeatureCallback} callback is registered as a - * listener for feature updates. - * @param slotIndex The SIM slot that we are requesting the {@link IImsMMTelFeature} for. + * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id and MMTel + * feature or {@link null} if the service is not available. If an MMTelFeature is available, the + * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates. + * @param slotIndex The SIM slot that we are requesting the {@link IImsMmTelFeature} for. * @param callback Listener that will send updates to ImsManager when there are updates to * ImsServiceController. - * @return {@link IImsMMTelFeature} interface for the feature specified or {@code null} if + * @return {@link IImsMmTelFeature} interface for the feature specified or {@code null} if * it is unavailable. * @hide */ - public @Nullable IImsMMTelFeature getImsEmergencyMMTelFeatureAndListen(int slotIndex, + public @Nullable IImsMmTelFeature getImsMmTelFeatureAndListen(int slotIndex, IImsServiceFeatureCallback callback) { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getEmergencyMMTelFeatureAndListen(slotIndex, callback); + return telephony.getMmTelFeatureAndListen(slotIndex, callback); } } catch (RemoteException e) { - Rlog.e(TAG, "getImsEmergencyMMTelFeatureAndListen, RemoteException: " + Rlog.e(TAG, "getImsMmTelFeatureAndListen, RemoteException: " + e.getMessage()); } return null; @@ -4991,6 +4995,25 @@ public class TelephonyManager { } /** + * @return the {@IImsConfig} interface that corresponds with the slot index and feature. + * @param slotIndex The SIM slot corresponding to the ImsService ImsConfig is active for. + * @param feature An integer indicating the feature that we wish to get the ImsConfig for. + * Corresponds to features defined in ImsFeature. + * @hide + */ + public @Nullable IImsConfig getImsConfig(int slotIndex, int feature) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.getImsConfig(slotIndex, feature); + } + } catch (RemoteException e) { + Rlog.e(TAG, "getImsRegistration, RemoteException: " + e.getMessage()); + } + return null; + } + + /** * Set IMS registration state * * @param Registration state diff --git a/telephony/java/com/android/ims/ImsCallForwardInfo.aidl b/telephony/java/android/telephony/ims/ImsCallForwardInfo.aidl index a7c3f9a5f722..b322b39be7e4 100644 --- a/telephony/java/com/android/ims/ImsCallForwardInfo.aidl +++ b/telephony/java/android/telephony/ims/ImsCallForwardInfo.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package com.android.ims; +package android.telephony.ims; parcelable ImsCallForwardInfo; diff --git a/telephony/java/com/android/ims/ImsCallForwardInfo.java b/telephony/java/android/telephony/ims/ImsCallForwardInfo.java index eeee0fc938bc..6d7218179067 100644 --- a/telephony/java/com/android/ims/ImsCallForwardInfo.java +++ b/telephony/java/android/telephony/ims/ImsCallForwardInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The Android Open Source Project + * 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. @@ -11,11 +11,12 @@ * 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. + * limitations under the License */ -package com.android.ims; +package android.telephony.ims; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -24,23 +25,32 @@ import android.os.Parcelable; * * @hide */ -public class ImsCallForwardInfo implements Parcelable { +@SystemApi +public final class ImsCallForwardInfo implements Parcelable { // Refer to ImsUtInterface#CDIV_CF_XXX + /** @hide */ public int mCondition; // 0: disabled, 1: enabled + /** @hide */ public int mStatus; // 0x91: International, 0x81: Unknown + /** @hide */ public int mToA; // Service class + /** @hide */ public int mServiceClass; // Number (it will not include the "sip" or "tel" URI scheme) + /** @hide */ public String mNumber; // No reply timer for CF + /** @hide */ public int mTimeSeconds; + /** @hide */ public ImsCallForwardInfo() { } + /** @hide */ public ImsCallForwardInfo(Parcel in) { readFromParcel(in); } @@ -91,4 +101,28 @@ public class ImsCallForwardInfo implements Parcelable { return new ImsCallForwardInfo[size]; } }; + + public int getCondition() { + return mCondition; + } + + public int getStatus() { + return mStatus; + } + + public int getToA() { + return mToA; + } + + public int getServiceClass() { + return mServiceClass; + } + + public String getNumber() { + return mNumber; + } + + public int getTimeSeconds() { + return mTimeSeconds; + } } diff --git a/telephony/java/com/android/ims/ImsCallProfile.aidl b/telephony/java/android/telephony/ims/ImsCallProfile.aidl index a356d1352eb2..e24e14530916 100644 --- a/telephony/java/com/android/ims/ImsCallProfile.aidl +++ b/telephony/java/android/telephony/ims/ImsCallProfile.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package com.android.ims; +package android.telephony.ims; parcelable ImsCallProfile; diff --git a/telephony/java/com/android/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java index 693aaff8ce0f..27e5f943982b 100644 --- a/telephony/java/com/android/ims/ImsCallProfile.java +++ b/telephony/java/android/telephony/ims/ImsCallProfile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The Android Open Source Project + * 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. @@ -11,11 +11,12 @@ * 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. + * limitations under the License */ -package com.android.ims; +package android.telephony.ims; +import android.annotation.SystemApi; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -32,7 +33,8 @@ import com.android.internal.telephony.PhoneConstants; * * @hide */ -public class ImsCallProfile implements Parcelable { +@SystemApi +public final class ImsCallProfile implements Parcelable { private static final String TAG = "ImsCallProfile"; /** @@ -110,52 +112,92 @@ public class ImsCallProfile implements Parcelable { * the video during voice call. * conference_avail : Indicates if the session can be extended to the conference. */ + /** + * @hide + */ public static final String EXTRA_CONFERENCE = "conference"; + /** + * @hide + */ public static final String EXTRA_E_CALL = "e_call"; + /** + * @hide + */ public static final String EXTRA_VMS = "vms"; + /** + * @hide + */ public static final String EXTRA_CALL_MODE_CHANGEABLE = "call_mode_changeable"; + /** + * @hide + */ public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail"; // Extra string for internal use only. OEMs should not use // this for packing extras. + /** + * @hide + */ public static final String EXTRA_OEM_EXTRAS = "OemCallExtras"; /** - * Integer extra properties - * oir : Rule for originating identity (number) presentation, MO/MT. + * Rule for originating identity (number) presentation, MO/MT. * {@link ImsCallProfile#OIR_DEFAULT} * {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED} * {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED} - * cnap : Rule for calling name presentation + */ + public static final String EXTRA_OIR = "oir"; + /** + * Rule for calling name presentation * {@link ImsCallProfile#OIR_DEFAULT} * {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED} * {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED} - * dialstring : To identify the Ims call type, MO - * {@link ImsCallProfile#DIALSTRING_NORMAL_CALL} + */ + public static final String EXTRA_CNAP = "cnap"; + /** + * To identify the Ims call type, MO + * {@link ImsCallProfile#DIALSTRING_NORMAL} * {@link ImsCallProfile#DIALSTRING_SS_CONF} * {@link ImsCallProfile#DIALSTRING_USSD} */ - public static final String EXTRA_OIR = "oir"; - public static final String EXTRA_CNAP = "cnap"; public static final String EXTRA_DIALSTRING = "dialstring"; /** * Values for EXTRA_OIR / EXTRA_CNAP */ + /** + * Default presentation for Originating Identity. + */ public static final int OIR_DEFAULT = 0; // "user subscription default value" + /** + * Restricted presentation for Originating Identity. + */ public static final int OIR_PRESENTATION_RESTRICTED = 1; + /** + * Not restricted presentation for Originating Identity. + */ public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2; + /** + * Presentation unknown for Originating Identity. + */ public static final int OIR_PRESENTATION_UNKNOWN = 3; + /** + * Payphone presentation for Originating Identity. + */ public static final int OIR_PRESENTATION_PAYPHONE = 4; + //Values for EXTRA_DIALSTRING /** - * Values for EXTRA_DIALSTRING + * A default or normal normal call. */ - // default (normal call) public static final int DIALSTRING_NORMAL = 0; - // Call for SIP-based user configuration + /** + * Call for SIP-based user configuration + */ public static final int DIALSTRING_SS_CONF = 1; - // Call for USSD message + /** + * Call for USSD message + */ public static final int DIALSTRING_USSD = 2; /** @@ -215,8 +257,11 @@ public class ImsCallProfile implements Parcelable { */ public static final String EXTRA_CALL_RAT_TYPE_ALT = "callRadioTech"; + /** @hide */ public int mServiceType; + /** @hide */ public int mCallType; + /** @hide */ public int mRestrictCause = CALL_RESTRICT_CAUSE_NONE; /** @@ -241,13 +286,17 @@ public class ImsCallProfile implements Parcelable { * Invalid types will be removed when the {@link ImsCallProfile} is parceled for transmit across * a {@link android.os.Binder}. */ + /** @hide */ public Bundle mCallExtras; + /** @hide */ public ImsStreamMediaProfile mMediaProfile; + /** @hide */ public ImsCallProfile(Parcel in) { readFromParcel(in); } + /** @hide */ public ImsCallProfile() { mServiceType = SERVICE_TYPE_NORMAL; mCallType = CALL_TYPE_VOICE_N_VIDEO; @@ -255,6 +304,7 @@ public class ImsCallProfile implements Parcelable { mMediaProfile = new ImsStreamMediaProfile(); } + /** @hide */ public ImsCallProfile(int serviceType, int callType) { mServiceType = serviceType; mCallType = callType; @@ -366,8 +416,28 @@ public class ImsCallProfile implements Parcelable { } }; + public int getServiceType() { + return mServiceType; + } + + public int getCallType() { + return mCallType; + } + + public int getRestrictCause() { + return mRestrictCause; + } + + public Bundle getCallExtras() { + return mCallExtras; + } + + public ImsStreamMediaProfile getMediaProfile() { + return mMediaProfile; + } + /** - * Converts from the call types defined in {@link com.android.ims.ImsCallProfile} to the + * Converts from the call types defined in {@link ImsCallProfile} to the * video state values defined in {@link VideoProfile}. * * @param callProfile The call profile. @@ -434,9 +504,9 @@ public class ImsCallProfile implements Parcelable { } /** - * Translate presentation value to OIR value - * @param presentation - * @return OIR valuse + * Badly named old method, kept for compatibility. + * See {@link #presentationToOir(int)}. + * @hide */ public static int presentationToOIR(int presentation) { switch (presentation) { @@ -454,9 +524,19 @@ public class ImsCallProfile implements Parcelable { } /** + * Translate presentation value to OIR value + * @param presentation + * @return OIR values + */ + public static int presentationToOir(int presentation) { + return presentationToOIR(presentation); + } + + /** * Translate OIR value to presentation value * @param oir value * @return presentation value + * @hide */ public static int OIRToPresentation(int oir) { switch(oir) { diff --git a/telephony/java/com/android/ims/internal/ImsCallSession.java b/telephony/java/android/telephony/ims/ImsCallSession.java index 1736b80c562b..207965d5a2f6 100644 --- a/telephony/java/com/android/ims/internal/ImsCallSession.java +++ b/telephony/java/android/telephony/ims/ImsCallSession.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The Android Open Source Project + * 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. @@ -11,23 +11,25 @@ * 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. + * limitations under the License */ -package com.android.ims.internal; +package android.telephony.ims; +import android.annotation.NonNull; +import android.annotation.SystemApi; import android.os.Message; import android.os.RemoteException; +import android.telephony.ims.aidl.IImsCallSessionListener; import java.util.Objects; +import java.util.concurrent.Executor; -import android.telephony.ims.stub.ImsCallSessionListenerImplBase; +import android.telephony.ims.stub.ImsCallSessionImplBase; import android.util.Log; -import com.android.ims.ImsCallProfile; -import com.android.ims.ImsConferenceState; -import com.android.ims.ImsReasonInfo; -import com.android.ims.ImsStreamMediaProfile; -import com.android.ims.ImsSuppServiceNotification; + +import com.android.ims.internal.IImsCallSession; +import com.android.ims.internal.IImsVideoCallProvider; /** * Provides the call initiation/termination, and media exchange between two IMS endpoints. @@ -39,7 +41,8 @@ public class ImsCallSession { private static final String TAG = "ImsCallSession"; /** - * Defines IMS call session state. + * Defines IMS call session state. Please use {@link ImsCallSessionImplBase.State} definition. + * This is kept around for capability reasons. */ public static class State { public static final int IDLE = 0; @@ -92,6 +95,7 @@ public class ImsCallSession { * Listener for events relating to an IMS session, such as when a session is being * recieved ("on ringing") or a call is outgoing ("on calling"). * <p>Many of these events are also received by {@link ImsCall.Listener}.</p> + * @hide */ public static class Listener { /** @@ -449,6 +453,7 @@ public class ImsCallSession { private boolean mClosed = false; private Listener mListener; + /** @hide */ public ImsCallSession(IImsCallSession iSession) { miSession = iSession; @@ -462,6 +467,7 @@ public class ImsCallSession { } } + /** @hide */ public ImsCallSession(IImsCallSession iSession, Listener listener) { this(iSession); setListener(listener); @@ -470,15 +476,17 @@ public class ImsCallSession { /** * Closes this object. This object is not usable after being closed. */ - public synchronized void close() { - if (mClosed) { - return; - } + public void close() { + synchronized (this) { + if (mClosed) { + return; + } - try { - miSession.close(); - mClosed = true; - } catch (RemoteException e) { + try { + miSession.close(); + mClosed = true; + } catch (RemoteException e) { + } } } @@ -554,6 +562,7 @@ public class ImsCallSession { * Gets the video call provider for the session. * * @return The video call provider. + * @hide */ public IImsVideoCallProvider getVideoCallProvider() { if (mClosed) { @@ -659,6 +668,7 @@ public class ImsCallSession { * override the previous listener. * * @param listener to listen to the session events of this object + * @hide */ public void setListener(Listener listener) { mListener = listener; @@ -987,7 +997,6 @@ public class ImsCallSession { * Sends Rtt Message * * @param rttMessage rtt text to be sent - * @throws ImsException if call is absent */ public void sendRttMessage(String rttMessage) { if (mClosed) { @@ -1004,7 +1013,6 @@ public class ImsCallSession { * Sends RTT Upgrade request * * @param to : expected profile - * @throws CallStateException */ public void sendRttModifyRequest(ImsCallProfile to) { if (mClosed) { @@ -1021,7 +1029,6 @@ public class ImsCallSession { * Sends RTT Upgrade response * * @param response : response for upgrade - * @throws CallStateException */ public void sendRttModifyResponse(boolean response) { if (mClosed) { @@ -1040,37 +1047,33 @@ public class ImsCallSession { * the application is notified by having one of the methods called on * the {@link IImsCallSessionListener}. */ - private class IImsCallSessionListenerProxy extends ImsCallSessionListenerImplBase { + private class IImsCallSessionListenerProxy extends IImsCallSessionListener.Stub { /** * Notifies the result of the basic session operation (setup / terminate). */ @Override - public void callSessionProgressing(IImsCallSession session, - ImsStreamMediaProfile profile) { + public void callSessionProgressing(ImsStreamMediaProfile profile) { if (mListener != null) { mListener.callSessionProgressing(ImsCallSession.this, profile); } } @Override - public void callSessionStarted(IImsCallSession session, - ImsCallProfile profile) { + public void callSessionInitiated(ImsCallProfile profile) { if (mListener != null) { mListener.callSessionStarted(ImsCallSession.this, profile); } } @Override - public void callSessionStartFailed(IImsCallSession session, - ImsReasonInfo reasonInfo) { + public void callSessionInitiatedFailed(ImsReasonInfo reasonInfo) { if (mListener != null) { mListener.callSessionStartFailed(ImsCallSession.this, reasonInfo); } } @Override - public void callSessionTerminated(IImsCallSession session, - ImsReasonInfo reasonInfo) { + public void callSessionTerminated(ImsReasonInfo reasonInfo) { if (mListener != null) { mListener.callSessionTerminated(ImsCallSession.this, reasonInfo); } @@ -1080,48 +1083,42 @@ public class ImsCallSession { * Notifies the result of the call hold/resume operation. */ @Override - public void callSessionHeld(IImsCallSession session, - ImsCallProfile profile) { + public void callSessionHeld(ImsCallProfile profile) { if (mListener != null) { mListener.callSessionHeld(ImsCallSession.this, profile); } } @Override - public void callSessionHoldFailed(IImsCallSession session, - ImsReasonInfo reasonInfo) { + public void callSessionHoldFailed(ImsReasonInfo reasonInfo) { if (mListener != null) { mListener.callSessionHoldFailed(ImsCallSession.this, reasonInfo); } } @Override - public void callSessionHoldReceived(IImsCallSession session, - ImsCallProfile profile) { + public void callSessionHoldReceived(ImsCallProfile profile) { if (mListener != null) { mListener.callSessionHoldReceived(ImsCallSession.this, profile); } } @Override - public void callSessionResumed(IImsCallSession session, - ImsCallProfile profile) { + public void callSessionResumed(ImsCallProfile profile) { if (mListener != null) { mListener.callSessionResumed(ImsCallSession.this, profile); } } @Override - public void callSessionResumeFailed(IImsCallSession session, - ImsReasonInfo reasonInfo) { + public void callSessionResumeFailed(ImsReasonInfo reasonInfo) { if (mListener != null) { mListener.callSessionResumeFailed(ImsCallSession.this, reasonInfo); } } @Override - public void callSessionResumeReceived(IImsCallSession session, - ImsCallProfile profile) { + public void callSessionResumeReceived(ImsCallProfile profile) { if (mListener != null) { mListener.callSessionResumeReceived(ImsCallSession.this, profile); } @@ -1130,13 +1127,11 @@ public class ImsCallSession { /** * Notifies the start of a call merge operation. * - * @param session The call session. * @param newSession The merged call session. * @param profile The call profile. */ @Override - public void callSessionMergeStarted(IImsCallSession session, - IImsCallSession newSession, ImsCallProfile profile) { + public void callSessionMergeStarted(IImsCallSession newSession, ImsCallProfile profile) { // This callback can be used for future use to add additional // functionality that may be needed between conference start and complete Log.d(TAG, "callSessionMergeStarted"); @@ -1173,12 +1168,10 @@ public class ImsCallSession { /** * Notifies of a failure to perform a call merge operation. * - * @param session The call session. * @param reasonInfo The merge failure reason. */ @Override - public void callSessionMergeFailed(IImsCallSession session, - ImsReasonInfo reasonInfo) { + public void callSessionMergeFailed(ImsReasonInfo reasonInfo) { if (mListener != null) { mListener.callSessionMergeFailed(ImsCallSession.this, reasonInfo); } @@ -1188,24 +1181,21 @@ public class ImsCallSession { * Notifies the result of call upgrade / downgrade or any other call updates. */ @Override - public void callSessionUpdated(IImsCallSession session, - ImsCallProfile profile) { + public void callSessionUpdated(ImsCallProfile profile) { if (mListener != null) { mListener.callSessionUpdated(ImsCallSession.this, profile); } } @Override - public void callSessionUpdateFailed(IImsCallSession session, - ImsReasonInfo reasonInfo) { + public void callSessionUpdateFailed(ImsReasonInfo reasonInfo) { if (mListener != null) { mListener.callSessionUpdateFailed(ImsCallSession.this, reasonInfo); } } @Override - public void callSessionUpdateReceived(IImsCallSession session, - ImsCallProfile profile) { + public void callSessionUpdateReceived(ImsCallProfile profile) { if (mListener != null) { mListener.callSessionUpdateReceived(ImsCallSession.this, profile); } @@ -1215,8 +1205,8 @@ public class ImsCallSession { * Notifies the result of conference extension. */ @Override - public void callSessionConferenceExtended(IImsCallSession session, - IImsCallSession newSession, ImsCallProfile profile) { + public void callSessionConferenceExtended(IImsCallSession newSession, + ImsCallProfile profile) { if (mListener != null) { mListener.callSessionConferenceExtended(ImsCallSession.this, new ImsCallSession(newSession), profile); @@ -1224,16 +1214,15 @@ public class ImsCallSession { } @Override - public void callSessionConferenceExtendFailed(IImsCallSession session, - ImsReasonInfo reasonInfo) { + public void callSessionConferenceExtendFailed(ImsReasonInfo reasonInfo) { if (mListener != null) { mListener.callSessionConferenceExtendFailed(ImsCallSession.this, reasonInfo); } } @Override - public void callSessionConferenceExtendReceived(IImsCallSession session, - IImsCallSession newSession, ImsCallProfile profile) { + public void callSessionConferenceExtendReceived(IImsCallSession newSession, + ImsCallProfile profile) { if (mListener != null) { mListener.callSessionConferenceExtendReceived(ImsCallSession.this, new ImsCallSession(newSession), profile); @@ -1245,15 +1234,14 @@ public class ImsCallSession { * the conference session. */ @Override - public void callSessionInviteParticipantsRequestDelivered(IImsCallSession session) { + public void callSessionInviteParticipantsRequestDelivered() { if (mListener != null) { mListener.callSessionInviteParticipantsRequestDelivered(ImsCallSession.this); } } @Override - public void callSessionInviteParticipantsRequestFailed(IImsCallSession session, - ImsReasonInfo reasonInfo) { + public void callSessionInviteParticipantsRequestFailed(ImsReasonInfo reasonInfo) { if (mListener != null) { mListener.callSessionInviteParticipantsRequestFailed(ImsCallSession.this, reasonInfo); @@ -1261,15 +1249,14 @@ public class ImsCallSession { } @Override - public void callSessionRemoveParticipantsRequestDelivered(IImsCallSession session) { + public void callSessionRemoveParticipantsRequestDelivered() { if (mListener != null) { mListener.callSessionRemoveParticipantsRequestDelivered(ImsCallSession.this); } } @Override - public void callSessionRemoveParticipantsRequestFailed(IImsCallSession session, - ImsReasonInfo reasonInfo) { + public void callSessionRemoveParticipantsRequestFailed(ImsReasonInfo reasonInfo) { if (mListener != null) { mListener.callSessionRemoveParticipantsRequestFailed(ImsCallSession.this, reasonInfo); @@ -1280,8 +1267,7 @@ public class ImsCallSession { * Notifies the changes of the conference info. in the conference session. */ @Override - public void callSessionConferenceStateUpdated(IImsCallSession session, - ImsConferenceState state) { + public void callSessionConferenceStateUpdated(ImsConferenceState state) { if (mListener != null) { mListener.callSessionConferenceStateUpdated(ImsCallSession.this, state); } @@ -1291,17 +1277,15 @@ public class ImsCallSession { * Notifies the incoming USSD message. */ @Override - public void callSessionUssdMessageReceived(IImsCallSession session, - int mode, String ussdMessage) { + public void callSessionUssdMessageReceived(int mode, String ussdMessage) { if (mListener != null) { mListener.callSessionUssdMessageReceived(ImsCallSession.this, mode, ussdMessage); } } /** - * Notifies of a case where a {@link com.android.ims.internal.ImsCallSession} may + * Notifies of a case where a {@link ImsCallSession} may * potentially handover from one radio technology to another. - * @param session * @param srcAccessTech The source radio access technology; one of the access technology * constants defined in {@link android.telephony.ServiceState}. For * example @@ -1312,8 +1296,7 @@ public class ImsCallSession { * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}. */ @Override - public void callSessionMayHandover(IImsCallSession session, - int srcAccessTech, int targetAccessTech) { + public void callSessionMayHandover(int srcAccessTech, int targetAccessTech) { if (mListener != null) { mListener.callSessionMayHandover(ImsCallSession.this, srcAccessTech, targetAccessTech); @@ -1324,9 +1307,8 @@ public class ImsCallSession { * Notifies of handover information for this call */ @Override - public void callSessionHandover(IImsCallSession session, - int srcAccessTech, int targetAccessTech, - ImsReasonInfo reasonInfo) { + public void callSessionHandover(int srcAccessTech, int targetAccessTech, + ImsReasonInfo reasonInfo) { if (mListener != null) { mListener.callSessionHandover(ImsCallSession.this, srcAccessTech, targetAccessTech, reasonInfo); @@ -1337,9 +1319,8 @@ public class ImsCallSession { * Notifies of handover failure info for this call */ @Override - public void callSessionHandoverFailed(IImsCallSession session, - int srcAccessTech, int targetAccessTech, - ImsReasonInfo reasonInfo) { + public void callSessionHandoverFailed(int srcAccessTech, int targetAccessTech, + ImsReasonInfo reasonInfo) { if (mListener != null) { mListener.callSessionHandoverFailed(ImsCallSession.this, srcAccessTech, targetAccessTech, reasonInfo); @@ -1350,8 +1331,7 @@ public class ImsCallSession { * Notifies the TTY mode received from remote party. */ @Override - public void callSessionTtyModeReceived(IImsCallSession session, - int mode) { + public void callSessionTtyModeReceived(int mode) { if (mListener != null) { mListener.callSessionTtyModeReceived(ImsCallSession.this, mode); } @@ -1360,21 +1340,17 @@ public class ImsCallSession { /** * Notifies of a change to the multiparty state for this {@code ImsCallSession}. * - * @param session The call session. * @param isMultiParty {@code true} if the session became multiparty, {@code false} * otherwise. */ - public void callSessionMultipartyStateChanged(IImsCallSession session, - boolean isMultiParty) { - + public void callSessionMultipartyStateChanged(boolean isMultiParty) { if (mListener != null) { mListener.callSessionMultipartyStateChanged(ImsCallSession.this, isMultiParty); } } @Override - public void callSessionSuppServiceReceived(IImsCallSession session, - ImsSuppServiceNotification suppServiceInfo ) { + public void callSessionSuppServiceReceived(ImsSuppServiceNotification suppServiceInfo ) { if (mListener != null) { mListener.callSessionSuppServiceReceived(ImsCallSession.this, suppServiceInfo); } @@ -1384,8 +1360,7 @@ public class ImsCallSession { * Received RTT modify request from remote party */ @Override - public void callSessionRttModifyRequestReceived(IImsCallSession session, - ImsCallProfile callProfile) { + public void callSessionRttModifyRequestReceived(ImsCallProfile callProfile) { if (mListener != null) { mListener.callSessionRttModifyRequestReceived(ImsCallSession.this, callProfile); } diff --git a/telephony/java/android/telephony/ims/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/ImsCallSessionListener.java new file mode 100644 index 000000000000..a7f124a5b791 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsCallSessionListener.java @@ -0,0 +1,603 @@ +/* + * 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.ims; + +import android.annotation.SystemApi; +import android.os.RemoteException; +import android.telephony.ims.aidl.IImsCallSessionListener; +import android.telephony.ims.stub.ImsCallSessionImplBase; + +import com.android.ims.internal.IImsCallSession; + +/** + * Listener interface for notifying the Framework's {@link ImsCallSession} for updates to an ongoing + * IMS call. + * + * @hide + */ +// DO NOT remove or change the existing APIs, only add new ones to this implementation or you +// will break other implementations of ImsCallSessionListener maintained by other ImsServices. +// TODO: APIs in here do not conform to API guidelines yet. This can be changed if +// ImsCallSessionListenerConverter is also changed. +@SystemApi +public class ImsCallSessionListener { + + private final IImsCallSessionListener mListener; + + /** @hide */ + public ImsCallSessionListener(IImsCallSessionListener l) { + mListener = l; + } + + /** + * A request has been sent out to initiate a new IMS call session and a 1xx response has been + * received from the network. + */ + public void callSessionProgressing(ImsStreamMediaProfile profile) { + try { + mListener.callSessionProgressing(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session has been initiated. + * + * @param profile the associated {@link ImsCallProfile}. + */ + public void callSessionInitiated(ImsCallProfile profile) { + try { + mListener.callSessionInitiated(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session establishment has failed. + * + * @param reasonInfo {@link ImsReasonInfo} detailing the reason of the IMS call session + * establishment failure. + */ + public void callSessionInitiatedFailed(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionInitiatedFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session has been terminated. + * + * @param reasonInfo {@link ImsReasonInfo} detailing the reason of the session termination. + */ + public void callSessionTerminated(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionTerminated(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session has started the process of holding the call. If it fails, + * {@link #callSessionHoldFailed(ImsReasonInfo)} should be called. + * + * If the IMS call session is resumed, call {@link #callSessionResumed(ImsCallProfile)}. + * + * @param profile The associated {@link ImsCallProfile} of the call session that has been put + * on hold. + */ + public void callSessionHeld(ImsCallProfile profile) { + try { + mListener.callSessionHeld(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session has failed to be held. + * + * @param reasonInfo {@link ImsReasonInfo} detailing the reason of the session hold failure. + */ + public void callSessionHoldFailed(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionHoldFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * This IMS Call session has been put on hold by the remote party. + * + * @param profile The {@link ImsCallProfile} associated with this IMS call session. + */ + public void callSessionHoldReceived(ImsCallProfile profile) { + try { + mListener.callSessionHoldReceived(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session has started the process of resuming the call. If the process of resuming + * the call fails, call {@link #callSessionResumeFailed(ImsReasonInfo)}. + * + * @param profile The {@link ImsCallProfile} associated with this IMS call session. + */ + public void callSessionResumed(ImsCallProfile profile) { + try { + mListener.callSessionResumed(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session resume has failed. + * + * @param reasonInfo {@link ImsReasonInfo} containing the detailed reason of the session resume + * failure. + */ + public void callSessionResumeFailed(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionResumeFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The remote party has resumed this IMS call session. + * + * @param profile {@link ImsCallProfile} associated with the IMS call session. + */ + public void callSessionResumeReceived(ImsCallProfile profile) { + try { + mListener.callSessionResumeReceived(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session merge has been started. At this point, the {@code newSession} + * represents the IMS call session which represents the new merged conference and has been + * initiated to the IMS conference server. + * + * @param newSession the {@link ImsCallSessionImplBase} that represents the merged active & held + * sessions. + * @param profile The {@link ImsCallProfile} associated with this IMS call session. + */ + public void callSessionMergeStarted(ImsCallSessionImplBase newSession, ImsCallProfile profile) + { + try { + mListener.callSessionMergeStarted(newSession != null ? + newSession.getServiceImpl() : null, profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * Compatibility method for older implementations. + * See {@link #callSessionMergeStarted(ImsCallSessionImplBase, ImsCallProfile)}. + * + * @hide + */ + public void callSessionMergeStarted(IImsCallSession newSession, ImsCallProfile profile) + { + try { + mListener.callSessionMergeStarted(newSession, profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The session merge is successful and the merged {@link ImsCallSession} is active. + * + * @param newSession the new {@link ImsCallSessionImplBase} + * that represents the conference IMS call + * session. + */ + public void callSessionMergeComplete(ImsCallSessionImplBase newSession) { + try { + mListener.callSessionMergeComplete(newSession != null ? + newSession.getServiceImpl() : null); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * Compatibility method for older implementations of ImsService. + * + * See {@link #callSessionMergeComplete(ImsCallSessionImplBase)}}. + * + * @hide + */ + public void callSessionMergeComplete(IImsCallSession newSession) { + try { + mListener.callSessionMergeComplete(newSession); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session merge has failed. + * + * @param reasonInfo {@link ImsReasonInfo} contining the reason for the call merge failure. + */ + public void callSessionMergeFailed(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionMergeFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session profile has been updated. Does not include holding or resuming a call. + * + * @param profile The {@link ImsCallProfile} associated with the updated IMS call session. + */ + public void callSessionUpdated(ImsCallProfile profile) { + try { + mListener.callSessionUpdated(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session profile update has failed. + * + * @param reasonInfo {@link ImsReasonInfo} containing a reason for the session update failure. + */ + public void callSessionUpdateFailed(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionUpdateFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session profile has received an update from the remote user. + * + * @param profile The new {@link ImsCallProfile} associated with the update. + */ + public void callSessionUpdateReceived(ImsCallProfile profile) { + try { + mListener.callSessionUpdateReceived(profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * Called when the session has been extended to a conference session. + * + * If the conference extension fails, call + * {@link #callSessionConferenceExtendFailed(ImsReasonInfo)}. + * + * @param newSession the session object that is extended to the conference from the active + * IMS Call session. + * @param profile The {@link ImsCallProfile} associated with the IMS call session. + */ + public void callSessionConferenceExtended(ImsCallSessionImplBase newSession, + ImsCallProfile profile) { + try { + mListener.callSessionConferenceExtended( + newSession != null ? newSession.getServiceImpl() : null, profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * Compatibility method to interface with older versions of ImsService. + * See {@link #callSessionConferenceExtended(ImsCallSessionImplBase, ImsCallProfile)}. + * + * @hide + */ + public void callSessionConferenceExtended(IImsCallSession newSession, ImsCallProfile profile) { + try { + mListener.callSessionConferenceExtended(newSession, profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The previous conference extension has failed. + * + * @param reasonInfo {@link ImsReasonInfo} containing the detailed reason of the conference + * extension failure. + */ + public void callSessionConferenceExtendFailed(ImsReasonInfo reasonInfo) { + try { + mListener.callSessionConferenceExtendFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * A conference extension has been received received from the remote party. + * + * @param newSession An {@link ImsCallSessionImplBase} + * representing the extended IMS call session. + * @param profile The {@link ImsCallProfile} associated with the new IMS call session. + */ + public void callSessionConferenceExtendReceived(ImsCallSessionImplBase newSession, + ImsCallProfile profile) { + try { + mListener.callSessionConferenceExtendReceived(newSession != null + ? newSession.getServiceImpl() : null, profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * Compatibility method to interface with older versions of ImsService. + * See {@link #callSessionConferenceExtendReceived(ImsCallSessionImplBase, ImsCallProfile)}. + * + * @hide + */ + public void callSessionConferenceExtendReceived(IImsCallSession newSession, + ImsCallProfile profile) { + try { + mListener.callSessionConferenceExtendReceived(newSession, profile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The request to invite participants to the conference has been delivered to the conference + * server. + */ + public void callSessionInviteParticipantsRequestDelivered() { + try { + mListener.callSessionInviteParticipantsRequestDelivered(); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The previous request to invite participants to the conference (see + * {@link #callSessionInviteParticipantsRequestDelivered()}) has failed. + * + * @param reasonInfo {@link ImsReasonInfo} detailing the reason forthe conference invitation + * failure. + */ + public void callSessionInviteParticipantsRequestFailed(ImsReasonInfo reasonInfo) + { + try { + mListener.callSessionInviteParticipantsRequestFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The request to remove participants from the conference has been delivered to the conference + * server. + */ + public void callSessionRemoveParticipantsRequestDelivered() { + try { + mListener.callSessionRemoveParticipantsRequestDelivered(); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The previous request to remove participants from the conference (see + * {@link #callSessionRemoveParticipantsRequestDelivered()}) has failed. + * + * @param reasonInfo {@link ImsReasonInfo} detailing the reason for the conference removal + * failure. + */ + public void callSessionRemoveParticipantsRequestFailed(ImsReasonInfo reasonInfo) + { + try { + mListener.callSessionInviteParticipantsRequestFailed(reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session's conference state has changed. + * + * @param state The new {@link ImsConferenceState} associated with the conference. + */ + public void callSessionConferenceStateUpdated(ImsConferenceState state) { + try { + mListener.callSessionConferenceStateUpdated(state); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session has received a Ussd message. + * + * @param mode The mode of the USSD message, either + * {@link ImsCallSessionImplBase#USSD_MODE_NOTIFY} or + * {@link ImsCallSessionImplBase#USSD_MODE_REQUEST}. + * @param ussdMessage The USSD message. + */ + public void callSessionUssdMessageReceived(int mode, String ussdMessage) + { + try { + mListener.callSessionUssdMessageReceived(mode, ussdMessage); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * An {@link ImsCallSession} may potentially handover from one radio + * technology to another. + * + * @param srcAccessTech The source radio access technology; one of the access technology + * constants defined in {@link android.telephony.ServiceState}. For example + * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}. + * @param targetAccessTech The target radio access technology; one of the access technology + * constants defined in {@link android.telephony.ServiceState}. For example + * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}. + */ + public void callSessionMayHandover(int srcAccessTech, int targetAccessTech) + { + try { + mListener.callSessionMayHandover(srcAccessTech, targetAccessTech); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session's access technology has changed. + * + * @param srcAccessTech original access technology, defined in + * {@link android.telephony.ServiceState}. + * @param targetAccessTech new access technology, defined in + * {@link android.telephony.ServiceState}. + * @param reasonInfo The {@link ImsReasonInfo} associated with this handover. + */ + public void callSessionHandover(int srcAccessTech, int targetAccessTech, + ImsReasonInfo reasonInfo) { + try { + mListener.callSessionHandover(srcAccessTech, targetAccessTech, reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The IMS call session's access technology change has failed.. + * + * @param srcAccessTech original access technology + * @param targetAccessTech new access technology + * @param reasonInfo An {@link ImsReasonInfo} detailing the reason for the failure. + */ + public void callSessionHandoverFailed(int srcAccessTech, int targetAccessTech, + ImsReasonInfo reasonInfo) { + try { + mListener.callSessionHandoverFailed(srcAccessTech, targetAccessTech, reasonInfo); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The TTY mode has been changed by the remote party. + * + * @param mode one of the following: - + * {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} - + * {@link com.android.internal.telephony.Phone#TTY_MODE_FULL} - + * {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} - + * {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} + */ + public void callSessionTtyModeReceived(int mode) { + try { + mListener.callSessionTtyModeReceived(mode); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * The multiparty state has been changed for this {@code ImsCallSession}. + * + * @param isMultiParty {@code true} if the session became multiparty, {@code false} otherwise. + */ + public void callSessionMultipartyStateChanged(boolean isMultiParty) { + try { + mListener.callSessionMultipartyStateChanged(isMultiParty); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * Supplementary service information has been received for the current IMS call session. + * + * @param suppSrvNotification The {@link ImsSuppServiceNotification} containing the change. + */ + public void callSessionSuppServiceReceived(ImsSuppServiceNotification suppSrvNotification) + { + try { + mListener.callSessionSuppServiceReceived(suppSrvNotification); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * An RTT modify request has been received from the remote party. + * + * @param callProfile An {@link ImsCallProfile} with the updated attributes + */ + public void callSessionRttModifyRequestReceived(ImsCallProfile callProfile) + { + try { + mListener.callSessionRttModifyRequestReceived(callProfile); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * An RTT modify response has been received. + * + * @param status the received response for RTT modify request. + */ + public void callSessionRttModifyResponseReceived(int status) { + try { + mListener.callSessionRttModifyResponseReceived(status); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * An RTT message has been received from the remote party. + * + * @param rttMessage The RTT message that has been received. + */ + public void callSessionRttMessageReceived(String rttMessage) { + try { + mListener.callSessionRttMessageReceived(rttMessage); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } +} + diff --git a/telephony/java/com/android/ims/ImsConferenceState.aidl b/telephony/java/android/telephony/ims/ImsConferenceState.aidl index 2fc029f57902..e2b371c1440e 100644 --- a/telephony/java/com/android/ims/ImsConferenceState.aidl +++ b/telephony/java/android/telephony/ims/ImsConferenceState.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package com.android.ims; +package android.telephony.ims; parcelable ImsConferenceState; diff --git a/telephony/java/com/android/ims/ImsConferenceState.java b/telephony/java/android/telephony/ims/ImsConferenceState.java index 0afde88b8918..66d2f8d929d3 100644 --- a/telephony/java/com/android/ims/ImsConferenceState.java +++ b/telephony/java/android/telephony/ims/ImsConferenceState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The Android Open Source Project + * 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. @@ -11,16 +11,17 @@ * 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. + * limitations under the License */ -package com.android.ims; +package android.telephony.ims; import java.util.HashMap; import java.util.Iterator; import java.util.Map.Entry; import java.util.Set; +import android.annotation.SystemApi; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -32,7 +33,8 @@ import android.telecom.Connection; * * @hide */ -public class ImsConferenceState implements Parcelable { +@SystemApi +public final class ImsConferenceState implements Parcelable { /** * conference-info : user */ @@ -87,12 +89,13 @@ public class ImsConferenceState implements Parcelable { */ public static final String SIP_STATUS_CODE = "sipstatuscode"; - public HashMap<String, Bundle> mParticipants = new HashMap<String, Bundle>(); + public final HashMap<String, Bundle> mParticipants = new HashMap<String, Bundle>(); + /** @hide */ public ImsConferenceState() { } - public ImsConferenceState(Parcel in) { + private ImsConferenceState(Parcel in) { readFromParcel(in); } diff --git a/telephony/java/com/android/ims/ImsExternalCallState.aidl b/telephony/java/android/telephony/ims/ImsExternalCallState.aidl index c208702a8c34..99d293566806 100644 --- a/telephony/java/com/android/ims/ImsExternalCallState.aidl +++ b/telephony/java/android/telephony/ims/ImsExternalCallState.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package com.android.ims; +package android.telephony.ims; parcelable ImsExternalCallState; diff --git a/telephony/java/com/android/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java index da2607356d6c..e82c115cb4b3 100644 --- a/telephony/java/com/android/ims/ImsExternalCallState.java +++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 The Android Open Source Project + * 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. @@ -11,11 +11,12 @@ * 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. + * limitations under the License */ -package com.android.ims; +package android.telephony.ims; +import android.annotation.SystemApi; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; @@ -32,7 +33,8 @@ import android.telephony.Rlog; * Parcelable object to handle MultiEndpoint Dialog Information * @hide */ -public class ImsExternalCallState implements Parcelable { +@SystemApi +public final class ImsExternalCallState implements Parcelable { private static final String TAG = "ImsExternalCallState"; @@ -50,9 +52,11 @@ public class ImsExternalCallState implements Parcelable { private int mCallType; private boolean mIsHeld; + /** @hide */ public ImsExternalCallState() { } + /** @hide */ public ImsExternalCallState(int callId, Uri address, boolean isPullable, int callState, int callType, boolean isCallheld) { mCallId = callId; @@ -64,6 +68,7 @@ public class ImsExternalCallState implements Parcelable { Rlog.d(TAG, "ImsExternalCallState = " + this); } + /** @hide */ public ImsExternalCallState(Parcel in) { mCallId = in.readInt(); ClassLoader classLoader = ImsExternalCallState.class.getClassLoader(); diff --git a/telephony/java/com/android/ims/ImsReasonInfo.aidl b/telephony/java/android/telephony/ims/ImsReasonInfo.aidl index 17e6d3a729e9..604b323d1292 100644 --- a/telephony/java/com/android/ims/ImsReasonInfo.aidl +++ b/telephony/java/android/telephony/ims/ImsReasonInfo.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package com.android.ims; +package android.telephony.ims; parcelable ImsReasonInfo; diff --git a/telephony/java/com/android/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java index 83d9bd94013e..7b7749102590 100644 --- a/telephony/java/com/android/ims/ImsReasonInfo.java +++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The Android Open Source Project + * 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. @@ -11,11 +11,12 @@ * 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. + * limitations under the License */ -package com.android.ims; +package android.telephony.ims; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -24,7 +25,8 @@ import android.os.Parcelable; * * @hide */ -public class ImsReasonInfo implements Parcelable { +@SystemApi +public final class ImsReasonInfo implements Parcelable { /** * Specific code of each types @@ -418,27 +420,36 @@ public class ImsReasonInfo implements Parcelable { // For main reason code + /** @hide */ public int mCode; // For the extra code value; it depends on the code value. + /** @hide */ public int mExtraCode; // For the additional message of the reason info. + /** @hide */ public String mExtraMessage; + + /** @hide */ public ImsReasonInfo() { mCode = CODE_UNSPECIFIED; mExtraCode = CODE_UNSPECIFIED; mExtraMessage = null; } - public ImsReasonInfo(Parcel in) { - readFromParcel(in); + private ImsReasonInfo(Parcel in) { + mCode = in.readInt(); + mExtraCode = in.readInt(); + mExtraMessage = in.readString(); } + /** @hide */ public ImsReasonInfo(int code, int extraCode) { mCode = code; mExtraCode = extraCode; mExtraMessage = null; } + /** @hide */ public ImsReasonInfo(int code, int extraCode, String extraMessage) { mCode = code; mExtraCode = extraCode; @@ -487,12 +498,6 @@ public class ImsReasonInfo implements Parcelable { out.writeString(mExtraMessage); } - private void readFromParcel(Parcel in) { - mCode = in.readInt(); - mExtraCode = in.readInt(); - mExtraMessage = in.readString(); - } - public static final Creator<ImsReasonInfo> CREATOR = new Creator<ImsReasonInfo>() { @Override public ImsReasonInfo createFromParcel(Parcel in) { diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java index aaa0f08594d1..2748cb5470bf 100644 --- a/telephony/java/android/telephony/ims/ImsService.java +++ b/telephony/java/android/telephony/ims/ImsService.java @@ -16,25 +16,28 @@ package android.telephony.ims; -import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.telephony.CarrierConfigManager; +import android.telephony.ims.aidl.IImsConfig; +import android.telephony.ims.aidl.IImsMmTelFeature; +import android.telephony.ims.aidl.IImsRcsFeature; +import android.telephony.ims.aidl.IImsRegistration; +import android.telephony.ims.aidl.IImsServiceController; +import android.telephony.ims.aidl.IImsServiceControllerListener; import android.telephony.ims.feature.ImsFeature; -import android.telephony.ims.feature.MMTelFeature; +import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.feature.RcsFeature; +import android.telephony.ims.stub.ImsConfigImplBase; +import android.telephony.ims.stub.ImsFeatureConfiguration; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.util.Log; import android.util.SparseArray; import com.android.ims.internal.IImsFeatureStatusCallback; -import com.android.ims.internal.IImsMMTelFeature; -import com.android.ims.internal.IImsRcsFeature; -import com.android.ims.internal.IImsRegistration; -import com.android.ims.internal.IImsServiceController; import com.android.internal.annotations.VisibleForTesting; import static android.Manifest.permission.MODIFY_PHONE_STATE; @@ -48,9 +51,7 @@ import static android.Manifest.permission.MODIFY_PHONE_STATE; * ... * <service android:name=".EgImsService" * android:permission="android.permission.BIND_IMS_SERVICE" > - * <!-- Apps must declare which features they support as metadata. The different categories are - * defined below. In this example, the RCS_FEATURE feature is supported. --> - * <meta-data android:name="android.telephony.ims.RCS_FEATURE" android:value="true" /> + * ... * <intent-filter> * <action android:name="android.telephony.ims.ImsService" /> * </intent-filter> @@ -64,13 +65,31 @@ import static android.Manifest.permission.MODIFY_PHONE_STATE; * 2) Defined as a Carrier Provided ImsService in the Carrier Configuration using * {@link CarrierConfigManager#KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING}. * + * There are two ways to define to the platform which {@link ImsFeature}s this {@link ImsService} + * supports, dynamic or static definitions. + * + * In the static definition, the {@link ImsFeature}s that are supported are defined in the service + * definition of the AndroidManifest.xml file as metadata: + * <!-- Apps must declare which features they support as metadata. The different categories are + * defined below. In this example, the MMTEL_FEATURE feature is supported. --> + * <meta-data android:name="android.telephony.ims.MMTEL_FEATURE" android:value="true" /> + * * The features that are currently supported in an ImsService are: * - RCS_FEATURE: This ImsService implements the RcsFeature class. - * - MMTEL_FEATURE: This ImsService implements the MMTelFeature class. - * - EMERGENCY_MMTEL_FEATURE: This ImsService implements the MMTelFeature class and will be - * available to place emergency calls at all times. This MUST be implemented by the default - * ImsService provided in the device overlay. - * @hide + * - MMTEL_FEATURE: This ImsService implements the MmTelFeature class. + * - EMERGENCY_MMTEL_FEATURE: This ImsService supports Emergency Calling for MMTEL, must be + * declared along with the MMTEL_FEATURE. If this is not specified, the framework will use + * circuit switch for emergency calling. + * + * In the dynamic definition, the supported features are not specified in the service definition + * of the AndroidManifest. Instead, the framework binds to this service and calls + * {@link #querySupportedImsFeatures()}. The {@link ImsService} then returns an + * {@link ImsFeatureConfiguration}, which the framework uses to initialize the supported + * {@link ImsFeature}s. If at any time, the list of supported {@link ImsFeature}s changes, + * {@link #onUpdateSupportedImsFeatures(ImsFeatureConfiguration)} can be called to tell the + * framework of the changes. + * + * @hide */ @SystemApi public class ImsService extends Service { @@ -89,20 +108,36 @@ public class ImsService extends Service { // call ImsFeature#onFeatureRemoved. private final SparseArray<SparseArray<ImsFeature>> mFeaturesBySlot = new SparseArray<>(); + private IImsServiceControllerListener mListener; + + /** + * Listener that notifies the framework of ImsService changes. * @hide */ - protected final IBinder mImsServiceController = new IImsServiceController.Stub() { + public static class Listener extends IImsServiceControllerListener.Stub { + /** + * The IMS features that this ImsService supports has changed. + * @param c a new {@link ImsFeatureConfiguration} containing {@link ImsFeature.FeatureType}s + * that this ImsService supports. This may trigger the addition/removal of feature + * in this service. + */ + public void onUpdateSupportedImsFeatures(ImsFeatureConfiguration c) { + } + } + /** + * @hide + */ + protected final IBinder mImsServiceController = new IImsServiceController.Stub() { @Override - public IImsMMTelFeature createEmergencyMMTelFeature(int slotId, - IImsFeatureStatusCallback c) { - return createEmergencyMMTelFeatureInternal(slotId, c); + public void setListener(IImsServiceControllerListener l) { + mListener = l; } @Override - public IImsMMTelFeature createMMTelFeature(int slotId, IImsFeatureStatusCallback c) { - return createMMTelFeatureInternal(slotId, c); + public IImsMmTelFeature createMmTelFeature(int slotId, IImsFeatureStatusCallback c) { + return createMmTelFeatureInternal(slotId, c); } @Override @@ -111,16 +146,46 @@ public class ImsService extends Service { } @Override - public void removeImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c) - throws RemoteException { + public void removeImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c) { ImsService.this.removeImsFeature(slotId, featureType, c); } @Override - public IImsRegistration getRegistration(int slotId) throws RemoteException { + public ImsFeatureConfiguration querySupportedImsFeatures() { + return ImsService.this.querySupportedImsFeatures(); + } + + @Override + public void notifyImsServiceReadyForFeatureCreation() { + ImsService.this.readyForFeatureCreation(); + } + + @Override + public void notifyImsFeatureReady(int slotId, int featureType) { + ImsService.this.notifyImsFeatureReady(slotId, featureType); + } + + @Override + public IImsConfig getConfig(int slotId) { + ImsConfigImplBase c = ImsService.this.getConfig(slotId); + return c != null ? c.getIImsConfig() : null; + } + + @Override + public IImsRegistration getRegistration(int slotId) { ImsRegistrationImplBase r = ImsService.this.getRegistration(slotId); return r != null ? r.getBinder() : null; } + + @Override + public void enableIms(int slotId) { + ImsService.this.enableIms(slotId); + } + + @Override + public void disableIms(int slotId) { + ImsService.this.disableIms(slotId); + } }; /** @@ -143,47 +208,35 @@ public class ImsService extends Service { return mFeaturesBySlot.get(slotId); } - private IImsMMTelFeature createEmergencyMMTelFeatureInternal(int slotId, - IImsFeatureStatusCallback c) { - MMTelFeature f = onCreateEmergencyMMTelImsFeature(slotId); - if (f != null) { - setupFeature(f, slotId, ImsFeature.EMERGENCY_MMTEL, c); - return f.getBinder(); - } else { - return null; - } - } - - private IImsMMTelFeature createMMTelFeatureInternal(int slotId, + private IImsMmTelFeature createMmTelFeatureInternal(int slotId, IImsFeatureStatusCallback c) { - MMTelFeature f = onCreateMMTelImsFeature(slotId); + MmTelFeature f = createMmTelFeature(slotId); if (f != null) { - setupFeature(f, slotId, ImsFeature.MMTEL, c); + setupFeature(f, slotId, ImsFeature.FEATURE_MMTEL, c); return f.getBinder(); } else { + Log.e(LOG_TAG, "createMmTelFeatureInternal: null feature returned."); return null; } } private IImsRcsFeature createRcsFeatureInternal(int slotId, IImsFeatureStatusCallback c) { - RcsFeature f = onCreateRcsFeature(slotId); + RcsFeature f = createRcsFeature(slotId); if (f != null) { - setupFeature(f, slotId, ImsFeature.RCS, c); + setupFeature(f, slotId, ImsFeature.FEATURE_RCS, c); return f.getBinder(); } else { + Log.e(LOG_TAG, "createRcsFeatureInternal: null feature returned."); return null; } } private void setupFeature(ImsFeature f, int slotId, int featureType, IImsFeatureStatusCallback c) { - f.setContext(this); - f.setSlotId(slotId); f.addImsFeatureStatusCallback(c); + f.initialize(this, slotId); addImsFeature(slotId, featureType, f); - // TODO: Remove once new onFeatureReady AIDL is merged in. - f.onFeatureReady(); } private void addImsFeature(int slotId, int featureType, ImsFeature f) { @@ -221,38 +274,122 @@ public class ImsService extends Service { } } + private void notifyImsFeatureReady(int slotId, int featureType) { + synchronized (mFeaturesBySlot) { + // get ImsFeature associated with the slot/feature + SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId); + if (features == null) { + Log.w(LOG_TAG, "Can not notify ImsFeature ready. No ImsFeatures exist on " + + "slot " + slotId); + return; + } + ImsFeature f = features.get(featureType); + if (f == null) { + Log.w(LOG_TAG, "Can not notify ImsFeature ready. No feature with type " + + featureType + " exists on slot " + slotId); + return; + } + f.onFeatureReady(); + } + } + /** - * @return An implementation of MMTelFeature that will be used by the system for MMTel - * functionality. Must be able to handle emergency calls at any time as well. - * @hide + * When called, provide the {@link ImsFeatureConfiguration} that this {@link ImsService} + * currently supports. This will trigger the framework to set up the {@link ImsFeature}s that + * correspond to the {@link ImsFeature}s configured here. + * + * Use {@link #onUpdateSupportedImsFeatures(ImsFeatureConfiguration)} to change the supported + * {@link ImsFeature}s. + * + * @return an {@link ImsFeatureConfiguration} containing Features this ImsService supports. */ - public @Nullable MMTelFeature onCreateEmergencyMMTelImsFeature(int slotId) { - return null; + public ImsFeatureConfiguration querySupportedImsFeatures() { + // Return empty for base implementation + return new ImsFeatureConfiguration(); } /** - * @return An implementation of MMTelFeature that will be used by the system for MMTel - * functionality. - * @hide + * Updates the framework with a new {@link ImsFeatureConfiguration} containing the updated + * features, that this {@link ImsService} supports. This may trigger the framework to add/remove + * new ImsFeatures, depending on the configuration. */ - public @Nullable MMTelFeature onCreateMMTelImsFeature(int slotId) { + public final void onUpdateSupportedImsFeatures(ImsFeatureConfiguration c) + throws RemoteException { + if (mListener == null) { + throw new IllegalStateException("Framework is not ready"); + } + mListener.onUpdateSupportedImsFeatures(c); + } + + /** + * The ImsService has been bound and is ready for ImsFeature creation based on the Features that + * the ImsService has registered for with the framework, either in the manifest or via + * {@link #querySupportedImsFeatures()}. + * + * The ImsService should use this signal instead of onCreate/onBind or similar to perform + * feature initialization because the framework may bind to this service multiple times to + * query the ImsService's {@link ImsFeatureConfiguration} via + * {@link #querySupportedImsFeatures()}before creating features. + */ + public void readyForFeatureCreation() { + } + + /** + * The framework has enabled IMS for the slot specified, the ImsService should register for IMS + * and perform all appropriate initialization to bring up all ImsFeatures. + */ + public void enableIms(int slotId) { + } + + /** + * The framework has disabled IMS for the slot specified. The ImsService must deregister for IMS + * and set capability status to false for all ImsFeatures. + */ + public void disableIms(int slotId) { + } + + /** + * When called, the framework is requesting that a new {@link MmTelFeature} is created for the + * specified slot. + * + * @param slotId The slot ID that the MMTEL Feature is being created for. + * @return The newly created {@link MmTelFeature} associated with the slot or null if the + * feature is not supported. + */ + public MmTelFeature createMmTelFeature(int slotId) { return null; } /** - * @return An implementation of RcsFeature that will be used by the system for RCS. - * @hide + * When called, the framework is requesting that a new {@link RcsFeature} is created for the + * specified slot. + * + * @param slotId The slot ID that the RCS Feature is being created for. + * @return The newly created {@link RcsFeature} associated with the slot or null if the feature + * is not supported. */ - public @Nullable RcsFeature onCreateRcsFeature(int slotId) { + public RcsFeature createRcsFeature(int slotId) { return null; } /** + * Return the {@link ImsConfigImplBase} implementation associated with the provided slot. This + * will be used by the platform to get/set specific IMS related configurations. + * + * @param slotId The slot that the IMS configuration is associated with. + * @return ImsConfig implementation that is associated with the specified slot. + */ + public ImsConfigImplBase getConfig(int slotId) { + return new ImsConfigImplBase(); + } + + /** + * Return the {@link ImsRegistrationImplBase} implementation associated with the provided slot. + * * @param slotId The slot that is associated with the IMS Registration. * @return the ImsRegistration implementation associated with the slot. - * @hide */ public ImsRegistrationImplBase getRegistration(int slotId) { return new ImsRegistrationImplBase(); } -} +}
\ No newline at end of file diff --git a/telephony/java/com/android/ims/ImsSsData.aidl b/telephony/java/android/telephony/ims/ImsSsData.aidl index 33f83067a4df..eff3a6b0acc7 100644 --- a/telephony/java/com/android/ims/ImsSsData.aidl +++ b/telephony/java/android/telephony/ims/ImsSsData.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package com.android.ims; +package android.telephony.ims; parcelable ImsSsData; diff --git a/telephony/java/com/android/ims/ImsSsData.java b/telephony/java/android/telephony/ims/ImsSsData.java index 7336c133af96..1ddf1994f26b 100644 --- a/telephony/java/com/android/ims/ImsSsData.java +++ b/telephony/java/android/telephony/ims/ImsSsData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Android Open Source Project + * 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. @@ -11,21 +11,21 @@ * 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. + * limitations under the License */ -package com.android.ims; +package android.telephony.ims; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; -import java.util.ArrayList; - /** * Provided STK Call Control Suplementary Service information * * {@hide} */ -public class ImsSsData implements Parcelable { +@SystemApi +public final class ImsSsData implements Parcelable { //ServiceType public static final int SS_CFU = 0; @@ -68,30 +68,38 @@ public class ImsSsData implements Parcelable { public static final int SS_ALL_TELESERVICES_EXCEPT_SMS = 5; // Refer to ServiceType + /** @hide */ public int serviceType; // Refere to SSRequestType + /** @hide */ public int requestType; // Refer to TeleserviceType + /** @hide */ public int teleserviceType; // Service Class + /** @hide */ public int serviceClass; // Error information + /** @hide */ public int result; + /** @hide */ public int[] ssInfo; /* Valid for all supplementary services. This field will be empty for RequestType SS_INTERROGATION and ServiceType SS_CF_*, SS_INCOMING_BARRING_DN, SS_INCOMING_BARRING_ANONYMOUS.*/ + /** @hide */ public ImsCallForwardInfo[] cfInfo; /* Valid only for supplementary services ServiceType SS_CF_* and RequestType SS_INTERROGATION */ + /** @hide */ public ImsSsInfo[] imsSsInfo; /* Valid only for ServiceType SS_INCOMING_BARRING_DN and ServiceType SS_INCOMING_BARRING_ANONYMOUS */ public ImsSsData() {} - public ImsSsData(Parcel in) { + private ImsSsData(Parcel in) { readFromParcel(in); } @@ -133,20 +141,36 @@ public class ImsSsData implements Parcelable { return 0; } + /** + * Old method, kept for compatibility. See {@link #isTypeCf()} + * @hide + */ public boolean isTypeCF() { return (serviceType == SS_CFU || serviceType == SS_CF_BUSY || serviceType == SS_CF_NO_REPLY || serviceType == SS_CF_NOT_REACHABLE || serviceType == SS_CF_ALL || serviceType == SS_CF_ALL_CONDITIONAL); } + public boolean isTypeCf() { + return isTypeCF(); + } + public boolean isTypeUnConditional() { return (serviceType == SS_CFU || serviceType == SS_CF_ALL); } + /** + * Old method, kept for compatibility. See {@link #isTypeCf()} + * @hide + */ public boolean isTypeCW() { return (serviceType == SS_WAIT); } + public boolean isTypeCw() { + return isTypeCW(); + } + public boolean isTypeClip() { return (serviceType == SS_CLIP); } diff --git a/telephony/java/com/android/ims/ImsSsInfo.aidl b/telephony/java/android/telephony/ims/ImsSsInfo.aidl index 0ac598b70218..66d49507c127 100644 --- a/telephony/java/com/android/ims/ImsSsInfo.aidl +++ b/telephony/java/android/telephony/ims/ImsSsInfo.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package com.android.ims; +package android.telephony.ims; parcelable ImsSsInfo; diff --git a/telephony/java/com/android/ims/ImsSsInfo.java b/telephony/java/android/telephony/ims/ImsSsInfo.java index 7acc3bfd45c9..1d1292fb9f72 100644 --- a/telephony/java/com/android/ims/ImsSsInfo.java +++ b/telephony/java/android/telephony/ims/ImsSsInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The Android Open Source Project + * 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. @@ -11,11 +11,12 @@ * 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. + * limitations under the License */ -package com.android.ims; +package android.telephony.ims; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -24,7 +25,8 @@ import android.os.Parcelable; * * @hide */ -public class ImsSsInfo implements Parcelable { +@SystemApi +public final class ImsSsInfo implements Parcelable { /** * For the status of service registration or activation/deactivation. */ @@ -33,13 +35,15 @@ public class ImsSsInfo implements Parcelable { public static final int ENABLED = 1; // 0: disabled, 1: enabled + /** @hide */ public int mStatus; + /** @hide */ public String mIcbNum; public ImsSsInfo() { } - public ImsSsInfo(Parcel in) { + private ImsSsInfo(Parcel in) { readFromParcel(in); } @@ -76,4 +80,12 @@ public class ImsSsInfo implements Parcelable { return new ImsSsInfo[size]; } }; + + public int getStatus() { + return mStatus; + } + + public String getIcbNum() { + return mIcbNum; + } } diff --git a/telephony/java/com/android/ims/ImsStreamMediaProfile.aidl b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.aidl index d648a3569c11..ee321aec29d8 100644 --- a/telephony/java/com/android/ims/ImsStreamMediaProfile.aidl +++ b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package com.android.ims; +package android.telephony.ims; parcelable ImsStreamMediaProfile; diff --git a/telephony/java/com/android/ims/ImsStreamMediaProfile.java b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java index cfe37b524347..243352bdd180 100644 --- a/telephony/java/com/android/ims/ImsStreamMediaProfile.java +++ b/telephony/java/android/telephony/ims/ImsStreamMediaProfile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 The Android Open Source Project + * 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. @@ -11,11 +11,12 @@ * 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. + * limitations under the License */ -package com.android.ims; +package android.telephony.ims; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -25,7 +26,8 @@ import android.os.Parcelable; * * @hide */ -public class ImsStreamMediaProfile implements Parcelable { +@SystemApi +public final class ImsStreamMediaProfile implements Parcelable { private static final String TAG = "ImsStreamMediaProfile"; /** @@ -79,18 +81,25 @@ public class ImsStreamMediaProfile implements Parcelable { public static final int RTT_MODE_FULL = 1; // Audio related information + /** @hide */ public int mAudioQuality; + /** @hide */ public int mAudioDirection; // Video related information + /** @hide */ public int mVideoQuality; + /** @hide */ public int mVideoDirection; // Rtt related information + /** @hide */ public int mRttMode; + /** @hide */ public ImsStreamMediaProfile(Parcel in) { readFromParcel(in); } + /** @hide */ public ImsStreamMediaProfile() { mAudioQuality = AUDIO_QUALITY_NONE; mAudioDirection = DIRECTION_SEND_RECEIVE; @@ -99,6 +108,7 @@ public class ImsStreamMediaProfile implements Parcelable { mRttMode = RTT_MODE_DISABLED; } + /** @hide */ public ImsStreamMediaProfile(int audioQuality, int audioDirection, int videoQuality, int videoDirection) { mAudioQuality = audioQuality; @@ -107,6 +117,7 @@ public class ImsStreamMediaProfile implements Parcelable { mVideoDirection = videoDirection; } + /** @hide */ public ImsStreamMediaProfile(int rttMode) { mRttMode = rttMode; } @@ -178,4 +189,23 @@ public class ImsStreamMediaProfile implements Parcelable { mRttMode = rttMode; } + public int getAudioQuality() { + return mAudioQuality; + } + + public int getAudioDirection() { + return mAudioDirection; + } + + public int getVideoQuality() { + return mVideoQuality; + } + + public int getVideoDirection() { + return mVideoDirection; + } + + public int getRttMode() { + return mRttMode; + } } diff --git a/telephony/java/com/android/ims/ImsSuppServiceNotification.aidl b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.aidl index 6b4479f467c2..0552780c7dd3 100644 --- a/telephony/java/com/android/ims/ImsSuppServiceNotification.aidl +++ b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.aidl @@ -15,6 +15,6 @@ */ -package com.android.ims; +package android.telephony.ims; parcelable ImsSuppServiceNotification; diff --git a/telephony/java/com/android/ims/ImsSuppServiceNotification.java b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java index faf749972b91..efaade825224 100644 --- a/telephony/java/com/android/ims/ImsSuppServiceNotification.java +++ b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 The Android Open Source Project + * 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. @@ -11,12 +11,13 @@ * 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. + * limitations under the License */ -package com.android.ims; +package android.telephony.ims; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -28,27 +29,42 @@ import java.util.Arrays; * * @hide */ -public class ImsSuppServiceNotification implements Parcelable { +@SystemApi +public final class ImsSuppServiceNotification implements Parcelable { private static final String TAG = "ImsSuppServiceNotification"; /** Type of notification: 0 = MO; 1 = MT */ - public int notificationType; + public final int notificationType; /** TS 27.007 7.17 "code1" or "code2" */ - public int code; + public final int code; /** TS 27.007 7.17 "index" - Not used currently*/ - public int index; + public final int index; /** TS 27.007 7.17 "type" (MT only) - Not used currently */ - public int type; + public final int type; /** TS 27.007 7.17 "number" (MT only) */ - public String number; + public final String number; /** List of forwarded numbers, if any */ - public String[] history; + public final String[] history; - public ImsSuppServiceNotification() { + + public ImsSuppServiceNotification(int notificationType, int code, int index, int type, + String number, String[] history) { + this.notificationType = notificationType; + this.code = code; + this.index = index; + this.type = type; + this.number = number; + this.history = history; } + /** @hide */ public ImsSuppServiceNotification(Parcel in) { - readFromParcel(in); + notificationType = in.readInt(); + code = in.readInt(); + index = in.readInt(); + type = in.readInt(); + number = in.readString(); + history = in.createStringArray(); } @Override @@ -77,15 +93,6 @@ public class ImsSuppServiceNotification implements Parcelable { out.writeStringArray(history); } - private void readFromParcel(Parcel in) { - notificationType = in.readInt(); - code = in.readInt(); - index = in.readInt(); - type = in.readInt(); - number = in.readString(); - history = in.createStringArray(); - } - public static final Creator<ImsSuppServiceNotification> CREATOR = new Creator<ImsSuppServiceNotification>() { @Override diff --git a/telephony/java/android/telephony/ims/ImsUtListener.java b/telephony/java/android/telephony/ims/ImsUtListener.java new file mode 100644 index 000000000000..d50a0f738b25 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsUtListener.java @@ -0,0 +1,108 @@ +/* + * 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.ims; + +import android.annotation.SystemApi; +import android.os.Bundle; +import android.os.RemoteException; +import android.util.Log; + +import com.android.ims.internal.IImsUtListener; + +/** + * Base implementation of the IMS UT listener interface, which implements stubs. + * Override these methods to implement functionality. + * @hide + */ +// DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you +// will break other implementations of ImsUt maintained by other ImsServices. +@SystemApi +public class ImsUtListener { + private IImsUtListener mServiceInterface; + private static final String LOG_TAG = "ImsUtListener"; + + public void onUtConfigurationUpdated(int id) { + try { + mServiceInterface.utConfigurationUpdated(null, id); + } catch (RemoteException e) { + Log.w(LOG_TAG, "utConfigurationUpdated: remote exception"); + } + } + + public void onUtConfigurationUpdateFailed(int id, ImsReasonInfo error) { + try { + mServiceInterface.utConfigurationUpdateFailed(null, id, error); + } catch (RemoteException e) { + Log.w(LOG_TAG, "utConfigurationUpdateFailed: remote exception"); + } + } + + public void onUtConfigurationQueried(int id, Bundle ssInfo) { + try { + mServiceInterface.utConfigurationQueried(null, id, ssInfo); + } catch (RemoteException e) { + Log.w(LOG_TAG, "utConfigurationQueried: remote exception"); + } + } + + public void onUtConfigurationQueryFailed(int id, ImsReasonInfo error) { + try { + mServiceInterface.utConfigurationQueryFailed(null, id, error); + } catch (RemoteException e) { + Log.w(LOG_TAG, "utConfigurationQueryFailed: remote exception"); + } + } + + public void onUtConfigurationCallBarringQueried(int id, ImsSsInfo[] cbInfo) { + try { + mServiceInterface.utConfigurationCallBarringQueried(null, id, cbInfo); + } catch (RemoteException e) { + Log.w(LOG_TAG, "utConfigurationCallBarringQueried: remote exception"); + } + } + + public void onUtConfigurationCallForwardQueried(int id, ImsCallForwardInfo[] cfInfo) { + try { + mServiceInterface.utConfigurationCallForwardQueried(null, id, cfInfo); + } catch (RemoteException e) { + Log.w(LOG_TAG, "utConfigurationCallForwardQueried: remote exception"); + } + } + + public void onUtConfigurationCallWaitingQueried(int id, ImsSsInfo[] cwInfo) { + try { + mServiceInterface.utConfigurationCallWaitingQueried(null, id, cwInfo); + } catch (RemoteException e) { + Log.w(LOG_TAG, "utConfigurationCallWaitingQueried: remote exception"); + } + } + + public void onSupplementaryServiceIndication(ImsSsData ssData) { + try { + mServiceInterface.onSupplementaryServiceIndication(ssData); + } catch (RemoteException e) { + Log.w(LOG_TAG, "onSupplementaryServiceIndication: remote exception"); + } + } + + /** + * @hide + */ + public ImsUtListener(IImsUtListener serviceInterface) { + mServiceInterface = serviceInterface; + } +} diff --git a/telephony/java/com/android/ims/internal/ImsVideoCallProvider.java b/telephony/java/android/telephony/ims/ImsVideoCallProvider.java index 432dc3905737..b4f60b952a00 100644 --- a/telephony/java/com/android/ims/internal/ImsVideoCallProvider.java +++ b/telephony/java/android/telephony/ims/ImsVideoCallProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * 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. @@ -14,8 +14,9 @@ * limitations under the License */ -package com.android.ims.internal; +package android.telephony.ims; +import android.annotation.SystemApi; import android.net.Uri; import android.os.Handler; import android.os.Looper; @@ -26,11 +27,14 @@ import android.telecom.VideoProfile; import android.telecom.VideoProfile.CameraCapabilities; import android.view.Surface; +import com.android.ims.internal.IImsVideoCallCallback; +import com.android.ims.internal.IImsVideoCallProvider; import com.android.internal.os.SomeArgs; /** * @hide */ +@SystemApi public abstract class ImsVideoCallProvider { private static final int MSG_SET_CALLBACK = 1; private static final int MSG_SET_CAMERA = 2; @@ -173,6 +177,7 @@ public abstract class ImsVideoCallProvider { /** * Returns binder object which can be used across IPC methods. + * @hide */ public final IImsVideoCallProvider getInterface() { return mBinder; diff --git a/telephony/java/android/telephony/ims/internal/aidl/IImsCallSessionListener.aidl b/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl index 2fb67442fa34..f25b4b148605 100644 --- a/telephony/java/android/telephony/ims/internal/aidl/IImsCallSessionListener.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl @@ -14,14 +14,14 @@ * limitations under the License. */ -package android.telephony.ims.internal.aidl; +package android.telephony.ims.aidl; -import com.android.ims.ImsStreamMediaProfile; -import com.android.ims.ImsCallProfile; -import com.android.ims.ImsReasonInfo; -import com.android.ims.ImsConferenceState; +import android.telephony.ims.ImsStreamMediaProfile; +import android.telephony.ims.ImsCallProfile; +import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.ImsConferenceState; import com.android.ims.internal.IImsCallSession; -import com.android.ims.ImsSuppServiceNotification; +import android.telephony.ims.ImsSuppServiceNotification; /** * A listener type for receiving notification on IMS call session events. diff --git a/telephony/java/android/telephony/ims/internal/aidl/IImsCapabilityCallback.aidl b/telephony/java/android/telephony/ims/aidl/IImsCapabilityCallback.aidl index fd2eb24610ec..c755703c042a 100644 --- a/telephony/java/android/telephony/ims/internal/aidl/IImsCapabilityCallback.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsCapabilityCallback.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.telephony.ims.internal.aidl; +package android.telephony.ims.aidl; /** * See ImsFeature#CapabilityCallback for more information. diff --git a/telephony/java/android/telephony/ims/internal/aidl/IImsConfig.aidl b/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl index 3d424a33012d..4433c1c03c1f 100644 --- a/telephony/java/android/telephony/ims/internal/aidl/IImsConfig.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl @@ -15,9 +15,9 @@ */ -package android.telephony.ims.internal.aidl; +package android.telephony.ims.aidl; -import android.telephony.ims.internal.aidl.IImsConfigCallback; +import android.telephony.ims.aidl.IImsConfigCallback; import com.android.ims.ImsConfigListener; diff --git a/telephony/java/android/telephony/ims/internal/aidl/IImsConfigCallback.aidl b/telephony/java/android/telephony/ims/aidl/IImsConfigCallback.aidl index 52efd2322c17..2b3f1ca7196a 100644 --- a/telephony/java/android/telephony/ims/internal/aidl/IImsConfigCallback.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsConfigCallback.aidl @@ -15,7 +15,7 @@ */ -package android.telephony.ims.internal.aidl; +package android.telephony.ims.aidl; /** * Provides callback interface for ImsConfig when a value has changed. diff --git a/telephony/java/android/telephony/ims/internal/aidl/IImsMmTelFeature.aidl b/telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl index e226adaac07f..b9a6b3c38a92 100644 --- a/telephony/java/android/telephony/ims/internal/aidl/IImsMmTelFeature.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl @@ -14,15 +14,15 @@ * limitations under the License. */ -package android.telephony.ims.internal.aidl; +package android.telephony.ims.aidl; import android.os.Message; -import android.telephony.ims.internal.aidl.IImsMmTelListener; -import android.telephony.ims.internal.aidl.IImsCapabilityCallback; -import android.telephony.ims.internal.aidl.IImsCallSessionListener; -import android.telephony.ims.internal.feature.CapabilityChangeRequest; +import android.telephony.ims.aidl.IImsMmTelListener; +import android.telephony.ims.aidl.IImsSmsListener; +import android.telephony.ims.aidl.IImsCapabilityCallback; +import android.telephony.ims.feature.CapabilityChangeRequest; -import com.android.ims.ImsCallProfile; +import android.telephony.ims.ImsCallProfile; import com.android.ims.internal.IImsCallSession; import com.android.ims.internal.IImsEcbm; import com.android.ims.internal.IImsMultiEndpoint; @@ -30,14 +30,15 @@ import com.android.ims.internal.IImsRegistrationListener; import com.android.ims.internal.IImsUt; /** - * See SmsImplBase for more information. + * See MmTelFeature for more information. * {@hide} */ interface IImsMmTelFeature { void setListener(IImsMmTelListener l); int getFeatureState(); ImsCallProfile createCallProfile(int callSessionType, int callType); - IImsCallSession createCallSession(in ImsCallProfile profile, IImsCallSessionListener listener); + IImsCallSession createCallSession(in ImsCallProfile profile); + int shouldProcessCall(in String[] uris); IImsUt getUtInterface(); IImsEcbm getEcbmInterface(); void setUiTtyMode(int uiTtyMode, in Message onCompleteMessage); @@ -49,4 +50,12 @@ interface IImsMmTelFeature { IImsCapabilityCallback c); oneway void queryCapabilityConfiguration(int capability, int radioTech, IImsCapabilityCallback c); + // SMS APIs + void setSmsListener(IImsSmsListener l); + oneway void sendSms(in int token, int messageRef, String format, String smsc, boolean retry, + in byte[] pdu); + oneway void acknowledgeSms(int token, int messageRef, int result); + oneway void acknowledgeSmsReport(int token, int messageRef, int result); + String getSmsFormat(); + oneway void onSmsReady(); } diff --git a/telephony/java/android/telephony/ims/internal/aidl/IImsMmTelListener.aidl b/telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl index 43f5098af3ca..904e7cad9c14 100644 --- a/telephony/java/android/telephony/ims/internal/aidl/IImsMmTelListener.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl @@ -14,7 +14,9 @@ * limitations under the License. */ -package android.telephony.ims.internal.aidl; +package android.telephony.ims.aidl; + +import android.os.Bundle; import com.android.ims.internal.IImsCallSession; @@ -23,6 +25,6 @@ import com.android.ims.internal.IImsCallSession; * {@hide} */ oneway interface IImsMmTelListener { - void onIncomingCall(IImsCallSession c); + void onIncomingCall(IImsCallSession c, in Bundle extras); void onVoiceMessageCountUpdate(int count); }
\ No newline at end of file diff --git a/telephony/java/android/telephony/ims/internal/aidl/IImsRcsFeature.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl index f6005b66bd3c..691cfba9a28c 100644 --- a/telephony/java/android/telephony/ims/internal/aidl/IImsRcsFeature.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.telephony.ims.internal.aidl; +package android.telephony.ims.aidl; /** * See RcsFeature for more information. diff --git a/telephony/java/com/android/ims/internal/IImsRegistration.aidl b/telephony/java/android/telephony/ims/aidl/IImsRegistration.aidl index 6de264ec90fb..4ae0a75ad027 100644 --- a/telephony/java/com/android/ims/internal/IImsRegistration.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRegistration.aidl @@ -15,9 +15,9 @@ */ -package com.android.ims.internal; +package android.telephony.ims.aidl; -import com.android.ims.internal.IImsRegistrationCallback; +import android.telephony.ims.aidl.IImsRegistrationCallback; /** * See ImsRegistration for more information. diff --git a/telephony/java/com/android/ims/internal/IImsRegistrationCallback.aidl b/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl index 5f21167422dc..4f37caa33680 100644 --- a/telephony/java/com/android/ims/internal/IImsRegistrationCallback.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl @@ -15,12 +15,12 @@ */ -package com.android.ims.internal; +package android.telephony.ims.aidl; import android.net.Uri; -import android.telephony.ims.internal.stub.ImsFeatureConfiguration; +import android.telephony.ims.stub.ImsFeatureConfiguration; -import com.android.ims.ImsReasonInfo; +import android.telephony.ims.ImsReasonInfo; /** * See ImsRegistrationImplBase.Callback for more information. diff --git a/telephony/java/android/telephony/ims/internal/aidl/IImsServiceController.aidl b/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl index 82a85254bbca..86f8606ac39f 100644 --- a/telephony/java/android/telephony/ims/internal/aidl/IImsServiceController.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl @@ -14,16 +14,16 @@ * limitations under the License. */ -package android.telephony.ims.internal.aidl; +package android.telephony.ims.aidl; -import android.telephony.ims.internal.aidl.IImsMmTelFeature; -import android.telephony.ims.internal.aidl.IImsRcsFeature; -import android.telephony.ims.internal.aidl.IImsConfig; -import android.telephony.ims.internal.aidl.IImsServiceControllerListener; -import android.telephony.ims.internal.stub.ImsFeatureConfiguration; +import android.telephony.ims.aidl.IImsMmTelFeature; +import android.telephony.ims.aidl.IImsRcsFeature; +import android.telephony.ims.aidl.IImsConfig; +import android.telephony.ims.aidl.IImsRegistration; +import android.telephony.ims.aidl.IImsServiceControllerListener; +import android.telephony.ims.stub.ImsFeatureConfiguration; import com.android.ims.internal.IImsFeatureStatusCallback; -import com.android.ims.internal.IImsRegistration; /** * See ImsService and MmTelFeature for more information. @@ -41,4 +41,6 @@ interface IImsServiceController { void removeImsFeature(int slotId, int featureType, in IImsFeatureStatusCallback c); IImsConfig getConfig(int slotId); IImsRegistration getRegistration(int slotId); + oneway void enableIms(int slotId); + oneway void disableIms(int slotId); } diff --git a/telephony/java/android/telephony/ims/internal/aidl/IImsServiceControllerListener.aidl b/telephony/java/android/telephony/ims/aidl/IImsServiceControllerListener.aidl index 01cca2db0978..54f6120aa99c 100644 --- a/telephony/java/android/telephony/ims/internal/aidl/IImsServiceControllerListener.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsServiceControllerListener.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.telephony.ims.internal.aidl; +package android.telephony.ims.aidl; -import android.telephony.ims.internal.stub.ImsFeatureConfiguration; +import android.telephony.ims.stub.ImsFeatureConfiguration; /** * See ImsService#Listener for more information. diff --git a/telephony/java/com/android/ims/internal/IImsSmsListener.aidl b/telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl index 5a4b7e489025..606df15b1782 100644 --- a/telephony/java/com/android/ims/internal/IImsSmsListener.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.android.ims.internal; +package android.telephony.ims.aidl; /** * See SmsImplBase for more information. * {@hide} */ -interface IImsSmsListener { +oneway interface IImsSmsListener { void onSendSmsResult(int token, int messageRef, int status, int reason); void onSmsStatusReportReceived(int token, int messageRef, in String format, in byte[] pdu); diff --git a/telephony/java/android/telephony/ims/compat/ImsService.java b/telephony/java/android/telephony/ims/compat/ImsService.java new file mode 100644 index 000000000000..cf1efb34bd0a --- /dev/null +++ b/telephony/java/android/telephony/ims/compat/ImsService.java @@ -0,0 +1,237 @@ +/* + * 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.ims.compat; + +import android.annotation.Nullable; +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.os.RemoteException; +import android.telephony.CarrierConfigManager; +import android.telephony.ims.compat.feature.ImsFeature; +import android.telephony.ims.compat.feature.MMTelFeature; +import android.telephony.ims.compat.feature.RcsFeature; +import android.util.Log; +import android.util.SparseArray; + +import com.android.ims.internal.IImsFeatureStatusCallback; +import com.android.ims.internal.IImsMMTelFeature; +import com.android.ims.internal.IImsRcsFeature; +import com.android.ims.internal.IImsServiceController; +import com.android.internal.annotations.VisibleForTesting; + +/** + * Main ImsService implementation, which binds via the Telephony ImsResolver. Services that extend + * ImsService must register the service in their AndroidManifest to be detected by the framework. + * First, the application must declare that they use the "android.permission.BIND_IMS_SERVICE" + * permission. Then, the ImsService definition in the manifest must follow the following format: + * + * ... + * <service android:name=".EgImsService" + * android:permission="android.permission.BIND_IMS_SERVICE" > + * <!-- Apps must declare which features they support as metadata. The different categories are + * defined below. In this example, the RCS_FEATURE feature is supported. --> + * <meta-data android:name="android.telephony.ims.RCS_FEATURE" android:value="true" /> + * <intent-filter> + * <action android:name="android.telephony.ims.compat.ImsService" /> + * </intent-filter> + * </service> + * ... + * + * The telephony framework will then bind to the ImsService you have defined in your manifest + * if you are either: + * 1) Defined as the default ImsService for the device in the device overlay using + * "config_ims_package". + * 2) Defined as a Carrier Provided ImsService in the Carrier Configuration using + * {@link CarrierConfigManager#KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING}. + * + * The features that are currently supported in an ImsService are: + * - RCS_FEATURE: This ImsService implements the RcsFeature class. + * - MMTEL_FEATURE: This ImsService implements the MMTelFeature class. + * - EMERGENCY_MMTEL_FEATURE: This ImsService implements the MMTelFeature class and will be + * available to place emergency calls at all times. This MUST be implemented by the default + * ImsService provided in the device overlay. + * @hide + */ +public class ImsService extends Service { + + private static final String LOG_TAG = "ImsService(Compat)"; + + /** + * The intent that must be defined as an intent-filter in the AndroidManifest of the ImsService. + * @hide + */ + public static final String SERVICE_INTERFACE = "android.telephony.ims.compat.ImsService"; + + // A map of slot Id -> map of features (indexed by ImsFeature feature id) corresponding to that + // slot. + // We keep track of this to facilitate cleanup of the IImsFeatureStatusCallback and + // call ImsFeature#onFeatureRemoved. + private final SparseArray<SparseArray<ImsFeature>> mFeaturesBySlot = new SparseArray<>(); + + /** + * @hide + */ + protected final IBinder mImsServiceController = new IImsServiceController.Stub() { + + @Override + public IImsMMTelFeature createEmergencyMMTelFeature(int slotId, + IImsFeatureStatusCallback c) { + return createEmergencyMMTelFeatureInternal(slotId, c); + } + + @Override + public IImsMMTelFeature createMMTelFeature(int slotId, IImsFeatureStatusCallback c) { + return createMMTelFeatureInternal(slotId, c); + } + + @Override + public IImsRcsFeature createRcsFeature(int slotId, IImsFeatureStatusCallback c) { + return createRcsFeatureInternal(slotId, c); + } + + @Override + public void removeImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c) + throws RemoteException { + ImsService.this.removeImsFeature(slotId, featureType, c); + } + }; + + /** + * @hide + */ + @Override + public IBinder onBind(Intent intent) { + if(SERVICE_INTERFACE.equals(intent.getAction())) { + Log.i(LOG_TAG, "ImsService(Compat) Bound."); + return mImsServiceController; + } + return null; + } + + /** + * @hide + */ + @VisibleForTesting + public SparseArray<ImsFeature> getFeatures(int slotId) { + return mFeaturesBySlot.get(slotId); + } + + private IImsMMTelFeature createEmergencyMMTelFeatureInternal(int slotId, + IImsFeatureStatusCallback c) { + MMTelFeature f = onCreateEmergencyMMTelImsFeature(slotId); + if (f != null) { + setupFeature(f, slotId, ImsFeature.EMERGENCY_MMTEL, c); + return f.getBinder(); + } else { + return null; + } + } + + private IImsMMTelFeature createMMTelFeatureInternal(int slotId, + IImsFeatureStatusCallback c) { + MMTelFeature f = onCreateMMTelImsFeature(slotId); + if (f != null) { + setupFeature(f, slotId, ImsFeature.MMTEL, c); + return f.getBinder(); + } else { + return null; + } + } + + private IImsRcsFeature createRcsFeatureInternal(int slotId, + IImsFeatureStatusCallback c) { + RcsFeature f = onCreateRcsFeature(slotId); + if (f != null) { + setupFeature(f, slotId, ImsFeature.RCS, c); + return f.getBinder(); + } else { + return null; + } + } + + private void setupFeature(ImsFeature f, int slotId, int featureType, + IImsFeatureStatusCallback c) { + f.setContext(this); + f.setSlotId(slotId); + f.addImsFeatureStatusCallback(c); + addImsFeature(slotId, featureType, f); + // TODO: Remove once new onFeatureReady AIDL is merged in. + f.onFeatureReady(); + } + + private void addImsFeature(int slotId, int featureType, ImsFeature f) { + synchronized (mFeaturesBySlot) { + // Get SparseArray for Features, by querying slot Id + SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId); + if (features == null) { + // Populate new SparseArray of features if it doesn't exist for this slot yet. + features = new SparseArray<>(); + mFeaturesBySlot.put(slotId, features); + } + features.put(featureType, f); + } + } + + private void removeImsFeature(int slotId, int featureType, + IImsFeatureStatusCallback c) { + synchronized (mFeaturesBySlot) { + // get ImsFeature associated with the slot/feature + SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId); + if (features == null) { + Log.w(LOG_TAG, "Can not remove ImsFeature. No ImsFeatures exist on slot " + + slotId); + return; + } + ImsFeature f = features.get(featureType); + if (f == null) { + Log.w(LOG_TAG, "Can not remove ImsFeature. No feature with type " + + featureType + " exists on slot " + slotId); + return; + } + f.removeImsFeatureStatusCallback(c); + f.onFeatureRemoved(); + features.remove(featureType); + } + } + + /** + * @return An implementation of MMTelFeature that will be used by the system for MMTel + * functionality. Must be able to handle emergency calls at any time as well. + * @hide + */ + public @Nullable MMTelFeature onCreateEmergencyMMTelImsFeature(int slotId) { + return null; + } + + /** + * @return An implementation of MMTelFeature that will be used by the system for MMTel + * functionality. + * @hide + */ + public @Nullable MMTelFeature onCreateMMTelImsFeature(int slotId) { + return null; + } + + /** + * @return An implementation of RcsFeature that will be used by the system for RCS. + * @hide + */ + public @Nullable RcsFeature onCreateRcsFeature(int slotId) { + return null; + } +} diff --git a/telephony/java/android/telephony/ims/compat/feature/ImsFeature.java b/telephony/java/android/telephony/ims/compat/feature/ImsFeature.java new file mode 100644 index 000000000000..0a12cae26af4 --- /dev/null +++ b/telephony/java/android/telephony/ims/compat/feature/ImsFeature.java @@ -0,0 +1,202 @@ +/* + * 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.ims.compat.feature; + +import android.annotation.IntDef; +import android.content.Context; +import android.content.Intent; +import android.os.IInterface; +import android.os.RemoteException; +import android.telephony.SubscriptionManager; +import android.util.Log; + +import com.android.ims.internal.IImsFeatureStatusCallback; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Collections; +import java.util.Iterator; +import java.util.Set; +import java.util.WeakHashMap; + +/** + * Base class for all IMS features that are supported by the framework. + * @hide + */ +public abstract class ImsFeature { + + private static final String LOG_TAG = "ImsFeature"; + + /** + * Action to broadcast when ImsService is up. + * Internal use only. + * Only defined here separately compatibility purposes with the old ImsService. + * @hide + */ + public static final String ACTION_IMS_SERVICE_UP = + "com.android.ims.IMS_SERVICE_UP"; + + /** + * Action to broadcast when ImsService is down. + * Internal use only. + * Only defined here separately for compatibility purposes with the old ImsService. + * @hide + */ + public static final String ACTION_IMS_SERVICE_DOWN = + "com.android.ims.IMS_SERVICE_DOWN"; + + /** + * Part of the ACTION_IMS_SERVICE_UP or _DOWN intents. + * A long value; the phone ID corresponding to the IMS service coming up or down. + * Only defined here separately for compatibility purposes with the old ImsService. + * @hide + */ + public static final String EXTRA_PHONE_ID = "android:phone_id"; + + // Invalid feature value + public static final int INVALID = -1; + // ImsFeatures that are defined in the Manifests. Ensure that these values match the previously + // defined values in ImsServiceClass for compatibility purposes. + public static final int EMERGENCY_MMTEL = 0; + public static final int MMTEL = 1; + public static final int RCS = 2; + // Total number of features defined + public static final int MAX = 3; + + // Integer values defining the state of the ImsFeature at any time. + @IntDef(flag = true, + value = { + STATE_NOT_AVAILABLE, + STATE_INITIALIZING, + STATE_READY, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ImsState {} + public static final int STATE_NOT_AVAILABLE = 0; + public static final int STATE_INITIALIZING = 1; + public static final int STATE_READY = 2; + + private final Set<IImsFeatureStatusCallback> mStatusCallbacks = Collections.newSetFromMap( + new WeakHashMap<IImsFeatureStatusCallback, Boolean>()); + private @ImsState int mState = STATE_NOT_AVAILABLE; + private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX; + protected Context mContext; + + public void setContext(Context context) { + mContext = context; + } + + public void setSlotId(int slotId) { + mSlotId = slotId; + } + + public int getFeatureState() { + return mState; + } + + protected final void setFeatureState(@ImsState int state) { + if (mState != state) { + mState = state; + notifyFeatureState(state); + } + } + + public void addImsFeatureStatusCallback(IImsFeatureStatusCallback c) { + if (c == null) { + return; + } + try { + // If we have just connected, send queued status. + c.notifyImsFeatureStatus(mState); + // Add the callback if the callback completes successfully without a RemoteException. + synchronized (mStatusCallbacks) { + mStatusCallbacks.add(c); + } + } catch (RemoteException e) { + Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage()); + } + } + + public void removeImsFeatureStatusCallback(IImsFeatureStatusCallback c) { + if (c == null) { + return; + } + synchronized (mStatusCallbacks) { + mStatusCallbacks.remove(c); + } + } + + /** + * Internal method called by ImsFeature when setFeatureState has changed. + * @param state + */ + private void notifyFeatureState(@ImsState int state) { + synchronized (mStatusCallbacks) { + for (Iterator<IImsFeatureStatusCallback> iter = mStatusCallbacks.iterator(); + iter.hasNext(); ) { + IImsFeatureStatusCallback callback = iter.next(); + try { + Log.i(LOG_TAG, "notifying ImsFeatureState=" + state); + callback.notifyImsFeatureStatus(state); + } catch (RemoteException e) { + // remove if the callback is no longer alive. + iter.remove(); + Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage()); + } + } + } + sendImsServiceIntent(state); + } + + /** + * Provide backwards compatibility using deprecated service UP/DOWN intents. + */ + private void sendImsServiceIntent(@ImsState int state) { + if(mContext == null || mSlotId == SubscriptionManager.INVALID_SIM_SLOT_INDEX) { + return; + } + Intent intent; + switch (state) { + case ImsFeature.STATE_NOT_AVAILABLE: + case ImsFeature.STATE_INITIALIZING: + intent = new Intent(ACTION_IMS_SERVICE_DOWN); + break; + case ImsFeature.STATE_READY: + intent = new Intent(ACTION_IMS_SERVICE_UP); + break; + default: + intent = new Intent(ACTION_IMS_SERVICE_DOWN); + } + intent.putExtra(EXTRA_PHONE_ID, mSlotId); + mContext.sendBroadcast(intent); + } + + /** + * Called when the feature is ready to use. + */ + public abstract void onFeatureReady(); + + /** + * Called when the feature is being removed and must be cleaned up. + */ + public abstract void onFeatureRemoved(); + + /** + * @return Binder instance + */ + public abstract IInterface getBinder(); +} diff --git a/telephony/java/android/telephony/ims/feature/MMTelFeature.java b/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java index 93c316f3dcb9..d3d17f4fb198 100644 --- a/telephony/java/android/telephony/ims/feature/MMTelFeature.java +++ b/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * 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. @@ -14,14 +14,13 @@ * limitations under the License */ -package android.telephony.ims.feature; +package android.telephony.ims.compat.feature; import android.app.PendingIntent; import android.os.Message; import android.os.RemoteException; -import android.telephony.ims.internal.stub.SmsImplBase; -import com.android.ims.ImsCallProfile; +import android.telephony.ims.ImsCallProfile; import com.android.ims.internal.IImsCallSession; import com.android.ims.internal.IImsCallSessionListener; import com.android.ims.internal.IImsConfig; @@ -29,9 +28,12 @@ import com.android.ims.internal.IImsEcbm; import com.android.ims.internal.IImsMMTelFeature; import com.android.ims.internal.IImsMultiEndpoint; import com.android.ims.internal.IImsRegistrationListener; -import com.android.ims.internal.IImsSmsListener; import com.android.ims.internal.IImsUt; -import com.android.ims.internal.ImsCallSession; +import android.telephony.ims.ImsCallSession; +import android.telephony.ims.compat.stub.ImsCallSessionImplBase; +import android.telephony.ims.stub.ImsEcbmImplBase; +import android.telephony.ims.stub.ImsMultiEndpointImplBase; +import android.telephony.ims.stub.ImsUtImplBase; /** * Base implementation for MMTel. @@ -110,10 +112,10 @@ public class MMTelFeature extends ImsFeature { } @Override - public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile, - IImsCallSessionListener listener) throws RemoteException { + public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile) + throws RemoteException { synchronized (mLock) { - return MMTelFeature.this.createCallSession(sessionId, profile, listener); + return MMTelFeature.this.createCallSession(sessionId, profile, null); } } @@ -128,7 +130,8 @@ public class MMTelFeature extends ImsFeature { @Override public IImsUt getUtInterface() throws RemoteException { synchronized (mLock) { - return MMTelFeature.this.getUtInterface(); + ImsUtImplBase implBase = MMTelFeature.this.getUtInterface(); + return implBase != null ? implBase.getInterface() : null; } } @@ -156,7 +159,8 @@ public class MMTelFeature extends ImsFeature { @Override public IImsEcbm getEcbmInterface() throws RemoteException { synchronized (mLock) { - return MMTelFeature.this.getEcbmInterface(); + ImsEcbmImplBase implBase = MMTelFeature.this.getEcbmInterface(); + return implBase != null ? implBase.getImsEcbm() : null; } } @@ -170,50 +174,8 @@ public class MMTelFeature extends ImsFeature { @Override public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException { synchronized (mLock) { - return MMTelFeature.this.getMultiEndpointInterface(); - } - } - - @Override - public void setSmsListener(IImsSmsListener l) throws RemoteException { - synchronized (mLock) { - MMTelFeature.this.setSmsListener(l); - } - } - - @Override - public void sendSms(int token, int messageRef, String format, String smsc, boolean retry, - byte[] pdu) { - synchronized (mLock) { - MMTelFeature.this.sendSms(token, messageRef, format, smsc, retry, pdu); - } - } - - @Override - public void acknowledgeSms(int token, int messageRef, int result) { - synchronized (mLock) { - MMTelFeature.this.acknowledgeSms(token, messageRef, result); - } - } - - @Override - public void acknowledgeSmsReport(int token, int messageRef, int result) { - synchronized (mLock) { - MMTelFeature.this.acknowledgeSmsReport(token, messageRef, result); - } - } - - @Override - public String getSmsFormat() { - synchronized (mLock) { - return MMTelFeature.this.getSmsFormat(); - } - } - - @Override - public void onSmsReady() { - synchronized (mLock) { - MMTelFeature.this.onSmsReady(); + ImsMultiEndpointImplBase implBase = MMTelFeature.this.getMultiEndpointInterface(); + return implBase != null ? implBase.getIImsMultiEndpoint() : null; } } }; @@ -326,7 +288,6 @@ public class MMTelFeature extends ImsFeature { * * @param sessionId a session id which is obtained from {@link #startSession} * @param profile a call profile to make the call - * @param listener An implementation of IImsCallSessionListener. */ public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile, IImsCallSessionListener listener) { @@ -346,7 +307,7 @@ public class MMTelFeature extends ImsFeature { /** * @return The Ut interface for the supplementary service configuration. */ - public IImsUt getUtInterface() { + public ImsUtImplBase getUtInterface() { return null; } @@ -372,7 +333,7 @@ public class MMTelFeature extends ImsFeature { /** * @return The Emergency call-back mode interface for emergency VoLTE calls that support it. */ - public IImsEcbm getEcbmInterface() { + public ImsEcbmImplBase getEcbmInterface() { return null; } @@ -387,47 +348,10 @@ public class MMTelFeature extends ImsFeature { /** * @return MultiEndpoint interface for DEP notifications */ - public IImsMultiEndpoint getMultiEndpointInterface() { + public ImsMultiEndpointImplBase getMultiEndpointInterface() { return null; } - private void setSmsListener(IImsSmsListener listener) { - getSmsImplementation().registerSmsListener(listener); - } - - private void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry, - byte[] pdu) { - getSmsImplementation().sendSms(token, messageRef, format, smsc, isRetry, pdu); - } - - private void acknowledgeSms(int token, int messageRef, - @SmsImplBase.DeliverStatusResult int result) { - getSmsImplementation().acknowledgeSms(token, messageRef, result); - } - - private void acknowledgeSmsReport(int token, int messageRef, - @SmsImplBase.StatusReportResult int result) { - getSmsImplementation().acknowledgeSmsReport(token, messageRef, result); - } - - private void onSmsReady() { - getSmsImplementation().onReady(); - } - - /** - * Must be overridden by IMS Provider to be able to support SMS over IMS. Otherwise a default - * non-functional implementation is returned. - * - * @return an instance of {@link SmsImplBase} which should be implemented by the IMS Provider. - */ - protected SmsImplBase getSmsImplementation() { - return new SmsImplBase(); - } - - public String getSmsFormat() { - return getSmsImplementation().getSmsFormat(); - } - @Override public void onFeatureReady() { diff --git a/telephony/java/android/telephony/ims/internal/feature/RcsFeature.java b/telephony/java/android/telephony/ims/compat/feature/RcsFeature.java index 8d1bd9d27f7c..228b33045107 100644 --- a/telephony/java/android/telephony/ims/internal/feature/RcsFeature.java +++ b/telephony/java/android/telephony/ims/compat/feature/RcsFeature.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * 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. @@ -14,9 +14,10 @@ * limitations under the License */ -package android.telephony.ims.internal.feature; +package android.telephony.ims.compat.feature; -import android.telephony.ims.internal.aidl.IImsRcsFeature; + +import com.android.ims.internal.IImsRcsFeature; /** * Base implementation of the RcsFeature APIs. Any ImsService wishing to support RCS should extend @@ -36,19 +37,12 @@ public class RcsFeature extends ImsFeature { } @Override - public void changeEnabledCapabilities(CapabilityChangeRequest request, - CapabilityCallbackProxy c) { - // Do nothing for base implementation. - } - - @Override - public void onFeatureRemoved() { + public void onFeatureReady() { } - /**{@inheritDoc}*/ @Override - public void onFeatureReady() { + public void onFeatureRemoved() { } diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java new file mode 100644 index 000000000000..00cb1e25f66d --- /dev/null +++ b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java @@ -0,0 +1,585 @@ +/* + * 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.ims.compat.stub; + +import android.os.Message; +import android.os.RemoteException; + +import android.telephony.ims.ImsCallProfile; +import android.telephony.ims.ImsConferenceState; +import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.ImsStreamMediaProfile; +import android.telephony.ims.ImsSuppServiceNotification; +import android.telephony.ims.aidl.IImsCallSessionListener; +import com.android.ims.internal.IImsCallSession; +import com.android.ims.internal.IImsVideoCallProvider; + +import android.telephony.ims.ImsCallSession; + +/** + * Compat implementation of ImsCallSessionImplBase for older implementations. + * + * DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you + * will break other implementations of ImsCallSession maintained by other ImsServices. + * + * @hide + */ + +public class ImsCallSessionImplBase extends IImsCallSession.Stub { + + @Override + // convert to old implementation of listener + public final void setListener(IImsCallSessionListener listener) + throws RemoteException { + setListener(new ImsCallSessionListenerConverter(listener)); + } + + /** + * Sets the listener to listen to the session events. An {@link ImsCallSession} + * can only hold one listener at a time. Subsequent calls to this method + * override the previous listener. + * + * @param listener to listen to the session events of this object + */ + public void setListener(com.android.ims.internal.IImsCallSessionListener listener) { + + } + + /** + * Closes the object. This {@link ImsCallSessionImplBase} is not usable after being closed. + */ + @Override + public void close() { + + } + + /** + * @return A String containing the unique call ID of this {@link ImsCallSessionImplBase}. + */ + @Override + public String getCallId() { + return null; + } + + /** + * @return The {@link ImsCallProfile} that this {@link ImsCallSessionImplBase} is associated + * with. + */ + @Override + public ImsCallProfile getCallProfile() { + return null; + } + + /** + * @return The local {@link ImsCallProfile} that this {@link ImsCallSessionImplBase} is + * associated with. + */ + @Override + public ImsCallProfile getLocalCallProfile() { + return null; + } + + /** + * @return The remote {@link ImsCallProfile} that this {@link ImsCallSessionImplBase} is + * associated with. + */ + @Override + public ImsCallProfile getRemoteCallProfile() { + return null; + } + + /** + * @param name The String extra key. + * @return The string extra value associated with the specified property. + */ + @Override + public String getProperty(String name) { + return null; + } + + /** + * @return The {@link ImsCallSessionImplBase} state. + */ + @Override + public int getState() { + return -1; + } + + /** + * @return true if the {@link ImsCallSessionImplBase} is in a call, false otherwise. + */ + @Override + public boolean isInCall() { + return false; + } + + /** + * Mutes or unmutes the mic for the active call. + * + * @param muted true if the call should be muted, false otherwise. + */ + @Override + public void setMute(boolean muted) { + } + + /** + * Initiates an IMS call with the specified number and call profile. + * The session listener set in {@link #setListener(IImsCallSessionListener)} is called back upon + * defined session events. + * Only valid to call when the session state is in + * {@link ImsCallSession.State#IDLE}. + * + * @param callee dialed string to make the call to + * @param profile call profile to make the call with the specified service type, + * call type and media information + * @see {@link ImsCallSession.Listener#callSessionStarted}, + * {@link ImsCallSession.Listener#callSessionStartFailed} + */ + @Override + public void start(String callee, ImsCallProfile profile) { + } + + /** + * Initiates an IMS call with the specified participants and call profile. + * The session listener set in {@link #setListener(IImsCallSessionListener)} is called back upon + * defined session events. + * The method is only valid to call when the session state is in + * {@link ImsCallSession.State#IDLE}. + * + * @param participants participant list to initiate an IMS conference call + * @param profile call profile to make the call with the specified service type, + * call type and media information + * @see {@link ImsCallSession.Listener#callSessionStarted}, + * {@link ImsCallSession.Listener#callSessionStartFailed} + */ + @Override + public void startConference(String[] participants, ImsCallProfile profile) { + } + + /** + * Accepts an incoming call or session update. + * + * @param callType call type specified in {@link ImsCallProfile} to be answered + * @param profile stream media profile {@link ImsStreamMediaProfile} to be answered + * @see {@link ImsCallSession.Listener#callSessionStarted} + */ + @Override + public void accept(int callType, ImsStreamMediaProfile profile) { + } + + /** + * Rejects an incoming call or session update. + * + * @param reason reason code to reject an incoming call, defined in {@link ImsReasonInfo}. + * {@link ImsCallSession.Listener#callSessionStartFailed} + */ + @Override + public void reject(int reason) { + } + + /** + * Terminates a call. + * + * @param reason reason code to terminate a call, defined in {@link ImsReasonInfo}. + * + * @see {@link ImsCallSession.Listener#callSessionTerminated} + */ + @Override + public void terminate(int reason) { + } + + /** + * Puts a call on hold. When it succeeds, {@link ImsCallSession.Listener#callSessionHeld} is + * called. + * + * @param profile stream media profile {@link ImsStreamMediaProfile} to hold the call + * @see {@link ImsCallSession.Listener#callSessionHeld}, + * {@link ImsCallSession.Listener#callSessionHoldFailed} + */ + @Override + public void hold(ImsStreamMediaProfile profile) { + } + + /** + * Continues a call that's on hold. When it succeeds, + * {@link ImsCallSession.Listener#callSessionResumed} is called. + * + * @param profile stream media profile with {@link ImsStreamMediaProfile} to resume the call + * @see {@link ImsCallSession.Listener#callSessionResumed}, + * {@link ImsCallSession.Listener#callSessionResumeFailed} + */ + @Override + public void resume(ImsStreamMediaProfile profile) { + } + + /** + * Merges the active and held call. When the merge starts, + * {@link ImsCallSession.Listener#callSessionMergeStarted} is called. + * {@link ImsCallSession.Listener#callSessionMergeComplete} is called if the merge is + * successful, and {@link ImsCallSession.Listener#callSessionMergeFailed} is called if the merge + * fails. + * + * @see {@link ImsCallSession.Listener#callSessionMergeStarted}, + * {@link ImsCallSession.Listener#callSessionMergeComplete}, + * {@link ImsCallSession.Listener#callSessionMergeFailed} + */ + @Override + public void merge() { + } + + /** + * Updates the current call's properties (ex. call mode change: video upgrade / downgrade). + * + * @param callType call type specified in {@link ImsCallProfile} to be updated + * @param profile stream media profile {@link ImsStreamMediaProfile} to be updated + * @see {@link ImsCallSession.Listener#callSessionUpdated}, + * {@link ImsCallSession.Listener#callSessionUpdateFailed} + */ + @Override + public void update(int callType, ImsStreamMediaProfile profile) { + } + + /** + * Extends this call to the conference call with the specified recipients. + * + * @param participants participant list to be invited to the conference call after extending the + * call + * @see {@link ImsCallSession.Listener#callSessionConferenceExtended}, + * {@link ImsCallSession.Listener#callSessionConferenceExtendFailed} + */ + @Override + public void extendToConference(String[] participants) { + } + + /** + * Requests the conference server to invite an additional participants to the conference. + * + * @param participants participant list to be invited to the conference call + * @see {@link ImsCallSession.Listener#callSessionInviteParticipantsRequestDelivered}, + * {@link ImsCallSession.Listener#callSessionInviteParticipantsRequestFailed} + */ + @Override + public void inviteParticipants(String[] participants) { + } + + /** + * Requests the conference server to remove the specified participants from the conference. + * + * @param participants participant list to be removed from the conference call + * @see {@link ImsCallSession.Listener#callSessionRemoveParticipantsRequestDelivered}, + * {@link ImsCallSession.Listener#callSessionRemoveParticipantsRequestFailed} + */ + @Override + public void removeParticipants(String[] participants) { + } + + /** + * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>, + * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15, + * and event flash to 16. Currently, event flash is not supported. + * + * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs. + */ + @Override + public void sendDtmf(char c, Message result) { + } + + /** + * Start a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>, + * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15, + * and event flash to 16. Currently, event flash is not supported. + * + * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs. + */ + @Override + public void startDtmf(char c) { + } + + /** + * Stop a DTMF code. + */ + @Override + public void stopDtmf() { + } + + /** + * Sends an USSD message. + * + * @param ussdMessage USSD message to send + */ + @Override + public void sendUssd(String ussdMessage) { + } + + @Override + public IImsVideoCallProvider getVideoCallProvider() { + return null; + } + + /** + * Determines if the current session is multiparty. + * @return {@code True} if the session is multiparty. + */ + @Override + public boolean isMultiparty() { + return false; + } + + /** + * Device issues RTT modify request + * @param toProfile The profile with requested changes made + */ + @Override + public void sendRttModifyRequest(ImsCallProfile toProfile) { + } + + /** + * Device responds to Remote RTT modify request + * @param status true if the the request was accepted or false of the request is defined. + */ + @Override + public void sendRttModifyResponse(boolean status) { + } + + /** + * Device sends RTT message + * @param rttMessage RTT message to be sent + */ + @Override + public void sendRttMessage(String rttMessage) { + } + + /** + * There are two different ImsCallSessionListeners that need to reconciled here, we need to + * convert the "old" version of the com.android.ims.internal.IImsCallSessionListener to the + * "new" version of the Listener android.telephony.ims.ImsCallSessionListener when calling + * back to the framework. + */ + private class ImsCallSessionListenerConverter + extends com.android.ims.internal.IImsCallSessionListener.Stub { + + private final IImsCallSessionListener mNewListener; + + public ImsCallSessionListenerConverter(IImsCallSessionListener listener) { + mNewListener = listener; + } + + @Override + public void callSessionProgressing(IImsCallSession i, + ImsStreamMediaProfile imsStreamMediaProfile) throws RemoteException { + mNewListener.callSessionProgressing(imsStreamMediaProfile); + } + + @Override + public void callSessionStarted(IImsCallSession i, ImsCallProfile imsCallProfile) + throws RemoteException { + mNewListener.callSessionInitiated(imsCallProfile); + } + + @Override + public void callSessionStartFailed(IImsCallSession i, ImsReasonInfo imsReasonInfo) + throws RemoteException { + mNewListener.callSessionInitiatedFailed(imsReasonInfo); + } + + @Override + public void callSessionTerminated(IImsCallSession i, ImsReasonInfo imsReasonInfo) + throws RemoteException { + mNewListener.callSessionTerminated(imsReasonInfo); + } + + @Override + public void callSessionHeld(IImsCallSession i, ImsCallProfile imsCallProfile) + throws RemoteException { + mNewListener.callSessionHeld(imsCallProfile); + } + + @Override + public void callSessionHoldFailed(IImsCallSession i, ImsReasonInfo imsReasonInfo) + throws RemoteException { + mNewListener.callSessionHoldFailed(imsReasonInfo); + } + + @Override + public void callSessionHoldReceived(IImsCallSession i, ImsCallProfile imsCallProfile) + throws RemoteException { + mNewListener.callSessionHoldReceived(imsCallProfile); + } + + @Override + public void callSessionResumed(IImsCallSession i, ImsCallProfile imsCallProfile) + throws RemoteException { + mNewListener.callSessionResumed(imsCallProfile); + } + + @Override + public void callSessionResumeFailed(IImsCallSession i, ImsReasonInfo imsReasonInfo) + throws RemoteException { + mNewListener.callSessionResumeFailed(imsReasonInfo); + } + + @Override + public void callSessionResumeReceived(IImsCallSession i, ImsCallProfile imsCallProfile) + throws RemoteException { + mNewListener.callSessionResumeReceived(imsCallProfile); + } + + @Override + public void callSessionMergeStarted(IImsCallSession i, IImsCallSession newSession, + ImsCallProfile profile) + throws RemoteException { + mNewListener.callSessionMergeStarted(newSession, profile); + } + + @Override + public void callSessionMergeComplete(IImsCallSession iImsCallSession) + throws RemoteException { + mNewListener.callSessionMergeComplete(iImsCallSession); + } + + @Override + public void callSessionMergeFailed(IImsCallSession i, ImsReasonInfo imsReasonInfo) + throws RemoteException { + mNewListener.callSessionMergeFailed(imsReasonInfo); + } + + @Override + public void callSessionUpdated(IImsCallSession i, ImsCallProfile imsCallProfile) + throws RemoteException { + mNewListener.callSessionUpdated(imsCallProfile); + } + + @Override + public void callSessionUpdateFailed(IImsCallSession i, ImsReasonInfo imsReasonInfo) + throws RemoteException { + mNewListener.callSessionUpdateFailed(imsReasonInfo); + } + + @Override + public void callSessionUpdateReceived(IImsCallSession i, ImsCallProfile imsCallProfile) + throws RemoteException { + mNewListener.callSessionUpdateReceived(imsCallProfile); + } + + @Override + public void callSessionConferenceExtended(IImsCallSession i, IImsCallSession newSession, + ImsCallProfile imsCallProfile) throws RemoteException { + mNewListener.callSessionConferenceExtended(newSession, imsCallProfile); + } + + @Override + public void callSessionConferenceExtendFailed(IImsCallSession i, + ImsReasonInfo imsReasonInfo) throws RemoteException { + mNewListener.callSessionConferenceExtendFailed(imsReasonInfo); + } + + @Override + public void callSessionConferenceExtendReceived(IImsCallSession i, + IImsCallSession newSession, ImsCallProfile imsCallProfile) + throws RemoteException { + mNewListener.callSessionConferenceExtendReceived(newSession, imsCallProfile); + } + + @Override + public void callSessionInviteParticipantsRequestDelivered(IImsCallSession i) + throws RemoteException { + mNewListener.callSessionInviteParticipantsRequestDelivered(); + } + + @Override + public void callSessionInviteParticipantsRequestFailed(IImsCallSession i, + ImsReasonInfo imsReasonInfo) throws RemoteException { + mNewListener.callSessionInviteParticipantsRequestFailed(imsReasonInfo); + } + + @Override + public void callSessionRemoveParticipantsRequestDelivered(IImsCallSession i) + throws RemoteException { + mNewListener.callSessionRemoveParticipantsRequestDelivered(); + } + + @Override + public void callSessionRemoveParticipantsRequestFailed(IImsCallSession i, + ImsReasonInfo imsReasonInfo) throws RemoteException { + mNewListener.callSessionRemoveParticipantsRequestFailed(imsReasonInfo); + } + + @Override + public void callSessionConferenceStateUpdated(IImsCallSession i, + ImsConferenceState imsConferenceState) throws RemoteException { + mNewListener.callSessionConferenceStateUpdated(imsConferenceState); + } + + @Override + public void callSessionUssdMessageReceived(IImsCallSession i, int mode, String message) + throws RemoteException { + mNewListener.callSessionUssdMessageReceived(mode, message); + } + + @Override + public void callSessionHandover(IImsCallSession i, int srcAccessTech, int targetAccessTech, + ImsReasonInfo reasonInfo) throws RemoteException { + mNewListener.callSessionHandover(srcAccessTech, targetAccessTech, reasonInfo); + } + + @Override + public void callSessionHandoverFailed(IImsCallSession i, int srcAccessTech, + int targetAccessTech, ImsReasonInfo reasonInfo) throws RemoteException { + mNewListener.callSessionHandoverFailed(srcAccessTech, targetAccessTech, reasonInfo); + } + + @Override + public void callSessionMayHandover(IImsCallSession i, int srcAccessTech, int targetAccessTech) + throws RemoteException { + mNewListener.callSessionMayHandover(srcAccessTech, targetAccessTech); + } + + @Override + public void callSessionTtyModeReceived(IImsCallSession iImsCallSession, int mode) + throws RemoteException { + mNewListener.callSessionTtyModeReceived(mode); + } + + @Override + public void callSessionMultipartyStateChanged(IImsCallSession i, boolean isMultiparty) + throws RemoteException { + mNewListener.callSessionMultipartyStateChanged(isMultiparty); + } + + @Override + public void callSessionSuppServiceReceived(IImsCallSession i, + ImsSuppServiceNotification imsSuppServiceNotification) throws RemoteException { + mNewListener.callSessionSuppServiceReceived(imsSuppServiceNotification); + } + + @Override + public void callSessionRttModifyRequestReceived(IImsCallSession i, + ImsCallProfile imsCallProfile) throws RemoteException { + mNewListener.callSessionRttModifyRequestReceived(imsCallProfile); + } + + @Override + public void callSessionRttModifyResponseReceived(int status) throws RemoteException { + mNewListener.callSessionRttModifyResponseReceived(status); + } + + @Override + public void callSessionRttMessageReceived(String rttMessage) throws RemoteException { + mNewListener.callSessionRttMessageReceived(rttMessage); + } + } +} diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java new file mode 100644 index 000000000000..2c325ba8e134 --- /dev/null +++ b/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java @@ -0,0 +1,391 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package android.telephony.ims.compat.stub; + +import android.content.Context; +import android.content.Intent; +import android.os.RemoteException; +import android.util.Log; + +import com.android.ims.ImsConfig; +import com.android.ims.ImsConfigListener; +import com.android.ims.internal.IImsConfig; +import com.android.internal.annotations.VisibleForTesting; + +import java.lang.ref.WeakReference; +import java.util.HashMap; + + +/** + * Base implementation of ImsConfig. + * Override the methods that your implementation of ImsConfig supports. + * + * DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you + * will break other implementations of ImsConfig maintained by other ImsServices. + * + * Provides APIs to get/set the IMS service feature/capability/parameters. + * The config items include: + * 1) Items provisioned by the operator. + * 2) Items configured by user. Mainly service feature class. + * + * The inner class {@link ImsConfigStub} implements methods of IImsConfig AIDL interface. + * The IImsConfig AIDL interface is called by ImsConfig, which may exist in many other processes. + * ImsConfigImpl access to the configuration parameters may be arbitrarily slow, especially in + * during initialization, or times when a lot of configuration parameters are being set/get + * (such as during boot up or SIM card change). By providing a cache in ImsConfigStub, we can speed + * up access to these configuration parameters, so a query to the ImsConfigImpl does not have to be + * performed every time. + * @hide + */ + +public class ImsConfigImplBase { + + static final private String TAG = "ImsConfigImplBase"; + + ImsConfigStub mImsConfigStub; + + public ImsConfigImplBase(Context context) { + mImsConfigStub = new ImsConfigStub(this, context); + } + + /** + * Gets the value for ims service/capabilities parameters from the provisioned + * value storage. Synchronous blocking call. + * + * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @return value in Integer format. + */ + public int getProvisionedValue(int item) throws RemoteException { + return -1; + } + + /** + * Gets the value for ims service/capabilities parameters from the provisioned + * value storage. Synchronous blocking call. + * + * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @return value in String format. + */ + public String getProvisionedStringValue(int item) throws RemoteException { + return null; + } + + /** + * Sets the value for IMS service/capabilities parameters by the operator device + * management entity. It sets the config item value in the provisioned storage + * from which the master value is derived. Synchronous blocking call. + * + * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @param value in Integer format. + * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants. + */ + public int setProvisionedValue(int item, int value) throws RemoteException { + return ImsConfig.OperationStatusConstants.FAILED; + } + + /** + * Sets the value for IMS service/capabilities parameters by the operator device + * management entity. It sets the config item value in the provisioned storage + * from which the master value is derived. Synchronous blocking call. + * + * @param item as defined in com.android.ims.ImsConfig#ConfigConstants. + * @param value in String format. + * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants. + */ + public int setProvisionedStringValue(int item, String value) throws RemoteException { + return ImsConfig.OperationStatusConstants.FAILED; + } + + /** + * Gets the value of the specified IMS feature item for specified network type. + * This operation gets the feature config value from the master storage (i.e. final + * value). Asynchronous non-blocking call. + * + * @param feature as defined in com.android.ims.ImsConfig#FeatureConstants. + * @param network as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX. + * @param listener feature value returned asynchronously through listener. + */ + public void getFeatureValue(int feature, int network, ImsConfigListener listener) + throws RemoteException { + } + + /** + * Sets the value for IMS feature item for specified network type. + * This operation stores the user setting in setting db from which master db + * is derived. + * + * @param feature as defined in com.android.ims.ImsConfig#FeatureConstants. + * @param network as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX. + * @param value as defined in com.android.ims.ImsConfig#FeatureValueConstants. + * @param listener, provided if caller needs to be notified for set result. + */ + public void setFeatureValue(int feature, int network, int value, ImsConfigListener listener) + throws RemoteException { + } + + /** + * Gets the value for IMS VoLTE provisioned. + * This should be the same as the operator provisioned value if applies. + */ + public boolean getVolteProvisioned() throws RemoteException { + return false; + } + + /** + * Gets the value for IMS feature item video quality. + * + * @param listener Video quality value returned asynchronously through listener. + */ + public void getVideoQuality(ImsConfigListener listener) throws RemoteException { + } + + /** + * Sets the value for IMS feature item video quality. + * + * @param quality, defines the value of video quality. + * @param listener, provided if caller needs to be notified for set result. + */ + public void setVideoQuality(int quality, ImsConfigListener listener) throws RemoteException { + } + + public IImsConfig getIImsConfig() { return mImsConfigStub; } + + /** + * Updates provisioning value and notifies the framework of the change. + * Doesn't call #setProvisionedValue and assumes the result succeeded. + * This should only be used by modem when they implicitly changed provisioned values. + * + * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @param value in Integer format. + */ + public final void notifyProvisionedValueChanged(int item, int value) { + mImsConfigStub.updateCachedValue(item, value, true); + } + + /** + * Updates provisioning value and notifies the framework of the change. + * Doesn't call #setProvisionedValue and assumes the result succeeded. + * This should only be used by modem when they implicitly changed provisioned values. + * + * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @param value in String format. + */ + public final void notifyProvisionedValueChanged(int item, String value) { + mImsConfigStub.updateCachedValue(item, value, true); + } + + /** + * Implements the IImsConfig AIDL interface, which is called by potentially many processes + * in order to get/set configuration parameters. + * + * It holds an object of ImsConfigImplBase class which is usually extended by ImsConfigImpl + * with actual implementations from vendors. This class caches provisioned values from + * ImsConfigImpl layer because queries through ImsConfigImpl can be slow. When query goes in, + * it first checks cache layer. If missed, it will call the vendor implementation of + * ImsConfigImplBase API. + * and cache the return value if the set succeeds. + * + * Provides APIs to get/set the IMS service feature/capability/parameters. + * The config items include: + * 1) Items provisioned by the operator. + * 2) Items configured by user. Mainly service feature class. + * + * @hide + */ + @VisibleForTesting + static public class ImsConfigStub extends IImsConfig.Stub { + Context mContext; + WeakReference<ImsConfigImplBase> mImsConfigImplBaseWeakReference; + private HashMap<Integer, Integer> mProvisionedIntValue = new HashMap<>(); + private HashMap<Integer, String> mProvisionedStringValue = new HashMap<>(); + + @VisibleForTesting + public ImsConfigStub(ImsConfigImplBase imsConfigImplBase, Context context) { + mContext = context; + mImsConfigImplBaseWeakReference = + new WeakReference<ImsConfigImplBase>(imsConfigImplBase); + } + + /** + * Gets the value for ims service/capabilities parameters. It first checks its local cache, + * if missed, it will call ImsConfigImplBase.getProvisionedValue. + * Synchronous blocking call. + * + * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @return value in Integer format. + */ + @Override + public synchronized int getProvisionedValue(int item) throws RemoteException { + if (mProvisionedIntValue.containsKey(item)) { + return mProvisionedIntValue.get(item); + } else { + int retVal = getImsConfigImpl().getProvisionedValue(item); + if (retVal != ImsConfig.OperationStatusConstants.UNKNOWN) { + updateCachedValue(item, retVal, false); + } + return retVal; + } + } + + /** + * Gets the value for ims service/capabilities parameters. It first checks its local cache, + * if missed, it will call #ImsConfigImplBase.getProvisionedValue. + * Synchronous blocking call. + * + * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @return value in String format. + */ + @Override + public synchronized String getProvisionedStringValue(int item) throws RemoteException { + if (mProvisionedIntValue.containsKey(item)) { + return mProvisionedStringValue.get(item); + } else { + String retVal = getImsConfigImpl().getProvisionedStringValue(item); + if (retVal != null) { + updateCachedValue(item, retVal, false); + } + return retVal; + } + } + + /** + * Sets the value for IMS service/capabilities parameters by the operator device + * management entity. It sets the config item value in the provisioned storage + * from which the master value is derived, and write it into local cache. + * Synchronous blocking call. + * + * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. + * @param value in Integer format. + * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants. + */ + @Override + public synchronized int setProvisionedValue(int item, int value) throws RemoteException { + mProvisionedIntValue.remove(item); + int retVal = getImsConfigImpl().setProvisionedValue(item, value); + if (retVal == ImsConfig.OperationStatusConstants.SUCCESS) { + updateCachedValue(item, value, true); + } else { + Log.d(TAG, "Set provision value of " + item + + " to " + value + " failed with error code " + retVal); + } + + return retVal; + } + + /** + * Sets the value for IMS service/capabilities parameters by the operator device + * management entity. It sets the config item value in the provisioned storage + * from which the master value is derived, and write it into local cache. + * Synchronous blocking call. + * + * @param item as defined in com.android.ims.ImsConfig#ConfigConstants. + * @param value in String format. + * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants. + */ + @Override + public synchronized int setProvisionedStringValue(int item, String value) + throws RemoteException { + mProvisionedStringValue.remove(item); + int retVal = getImsConfigImpl().setProvisionedStringValue(item, value); + if (retVal == ImsConfig.OperationStatusConstants.SUCCESS) { + updateCachedValue(item, value, true); + } + + return retVal; + } + + /** + * Wrapper function to call ImsConfigImplBase.getFeatureValue. + */ + @Override + public void getFeatureValue(int feature, int network, ImsConfigListener listener) + throws RemoteException { + getImsConfigImpl().getFeatureValue(feature, network, listener); + } + + /** + * Wrapper function to call ImsConfigImplBase.setFeatureValue. + */ + @Override + public void setFeatureValue(int feature, int network, int value, ImsConfigListener listener) + throws RemoteException { + getImsConfigImpl().setFeatureValue(feature, network, value, listener); + } + + /** + * Wrapper function to call ImsConfigImplBase.getVolteProvisioned. + */ + @Override + public boolean getVolteProvisioned() throws RemoteException { + return getImsConfigImpl().getVolteProvisioned(); + } + + /** + * Wrapper function to call ImsConfigImplBase.getVideoQuality. + */ + @Override + public void getVideoQuality(ImsConfigListener listener) throws RemoteException { + getImsConfigImpl().getVideoQuality(listener); + } + + /** + * Wrapper function to call ImsConfigImplBase.setVideoQuality. + */ + @Override + public void setVideoQuality(int quality, ImsConfigListener listener) + throws RemoteException { + getImsConfigImpl().setVideoQuality(quality, listener); + } + + private ImsConfigImplBase getImsConfigImpl() throws RemoteException { + ImsConfigImplBase ref = mImsConfigImplBaseWeakReference.get(); + if (ref == null) { + throw new RemoteException("Fail to get ImsConfigImpl"); + } else { + return ref; + } + } + + private void sendImsConfigChangedIntent(int item, int value) { + sendImsConfigChangedIntent(item, Integer.toString(value)); + } + + private void sendImsConfigChangedIntent(int item, String value) { + Intent configChangedIntent = new Intent(ImsConfig.ACTION_IMS_CONFIG_CHANGED); + configChangedIntent.putExtra(ImsConfig.EXTRA_CHANGED_ITEM, item); + configChangedIntent.putExtra(ImsConfig.EXTRA_NEW_VALUE, value); + if (mContext != null) { + mContext.sendBroadcast(configChangedIntent); + } + } + + protected synchronized void updateCachedValue(int item, int value, boolean notifyChange) { + mProvisionedIntValue.put(item, value); + if (notifyChange) { + sendImsConfigChangedIntent(item, value); + } + } + + protected synchronized void updateCachedValue( + int item, String value, boolean notifyChange) { + mProvisionedStringValue.put(item, value); + if (notifyChange) { + sendImsConfigChangedIntent(item, value); + } + } + } +}
\ No newline at end of file diff --git a/telephony/java/android/telephony/ims/stub/ImsUtListenerImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsUtListenerImplBase.java index daa74c8f6f88..b2aa08015d10 100644 --- a/telephony/java/android/telephony/ims/stub/ImsUtListenerImplBase.java +++ b/telephony/java/android/telephony/ims/compat/stub/ImsUtListenerImplBase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * 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. @@ -14,15 +14,15 @@ * limitations under the License */ -package android.telephony.ims.stub; +package android.telephony.ims.compat.stub; import android.os.Bundle; import android.os.RemoteException; -import com.android.ims.ImsCallForwardInfo; -import com.android.ims.ImsReasonInfo; -import com.android.ims.ImsSsData; -import com.android.ims.ImsSsInfo; +import android.telephony.ims.ImsCallForwardInfo; +import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.ImsSsData; +import android.telephony.ims.ImsSsInfo; import com.android.ims.internal.IImsUt; import com.android.ims.internal.IImsUtListener; diff --git a/telephony/java/android/telephony/ims/internal/feature/CapabilityChangeRequest.aidl b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.aidl index f4ec0eb38f34..e789bd5ac940 100644 --- a/telephony/java/android/telephony/ims/internal/feature/CapabilityChangeRequest.aidl +++ b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.aidl @@ -14,6 +14,6 @@ * limitations under the License */ -package android.telephony.ims.internal.feature; +package android.telephony.ims.feature; parcelable CapabilityChangeRequest; diff --git a/telephony/java/android/telephony/ims/internal/feature/CapabilityChangeRequest.java b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java index 5dbf077ee7c5..7c793a5c18ac 100644 --- a/telephony/java/android/telephony/ims/internal/feature/CapabilityChangeRequest.java +++ b/telephony/java/android/telephony/ims/feature/CapabilityChangeRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * 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. @@ -14,8 +14,9 @@ * limitations under the License */ -package android.telephony.ims.internal.feature; +package android.telephony.ims.feature; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; import android.telephony.ims.stub.ImsRegistrationImplBase; @@ -30,17 +31,32 @@ import java.util.Set; * the request. * {@hide} */ -public class CapabilityChangeRequest implements Parcelable { +@SystemApi +public final class CapabilityChangeRequest implements Parcelable { + /** + * Contains a feature capability, defined as + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE}, + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO}, + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT}, or + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS}, + * along with an associated technology, defined as + * {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE} or + * {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN} + */ public static class CapabilityPair { private final int mCapability; private final int radioTech; - public CapabilityPair(int capability, int radioTech) { + public CapabilityPair(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability, + @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) { this.mCapability = capability; this.radioTech = radioTech; } + /** + * @hide + */ @Override public boolean equals(Object o) { if (this == o) return true; @@ -52,6 +68,9 @@ public class CapabilityChangeRequest implements Parcelable { return getRadioTech() == that.getRadioTech(); } + /** + * @hide + */ @Override public int hashCode() { int result = getCapability(); @@ -59,10 +78,22 @@ public class CapabilityChangeRequest implements Parcelable { return result; } + /** + * @return The stored capability, defined as + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE}, + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO}, + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT}, or + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS} + */ public @MmTelFeature.MmTelCapabilities.MmTelCapability int getCapability() { return mCapability; } + /** + * @return the stored radio technology, defined as + * {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE} or + * {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN} + */ public @ImsRegistrationImplBase.ImsRegistrationTech int getRadioTech() { return radioTech; } @@ -73,6 +104,7 @@ public class CapabilityChangeRequest implements Parcelable { // Pair contains <radio tech, mCapability> private final Set<CapabilityPair> mCapabilitiesToDisable; + /** @hide */ public CapabilityChangeRequest() { mCapabilitiesToEnable = new ArraySet<>(); mCapabilitiesToDisable = new ArraySet<>(); @@ -130,6 +162,9 @@ public class CapabilityChangeRequest implements Parcelable { } } + /** + * @hide + */ protected CapabilityChangeRequest(Parcel in) { int enableSize = in.readInt(); mCapabilitiesToEnable = new ArraySet<>(enableSize); @@ -177,17 +212,24 @@ public class CapabilityChangeRequest implements Parcelable { } } + /** + * @hide + */ @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof CapabilityChangeRequest)) return false; - CapabilityChangeRequest that = (CapabilityChangeRequest) o; + CapabilityChangeRequest + that = (CapabilityChangeRequest) o; if (!mCapabilitiesToEnable.equals(that.mCapabilitiesToEnable)) return false; return mCapabilitiesToDisable.equals(that.mCapabilitiesToDisable); } + /** + * @hide + */ @Override public int hashCode() { int result = mCapabilitiesToEnable.hashCode(); diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java index d47cea3097f3..bfdd4533275b 100644 --- a/telephony/java/android/telephony/ims/feature/ImsFeature.java +++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * 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. @@ -17,28 +17,35 @@ package android.telephony.ims.feature; import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.SystemApi; import android.content.Context; import android.content.Intent; import android.os.IInterface; +import android.os.RemoteCallbackList; import android.os.RemoteException; import android.telephony.SubscriptionManager; +import android.telephony.ims.aidl.IImsCapabilityCallback; +import android.telephony.ims.stub.ImsRegistrationImplBase; import android.util.Log; import com.android.ims.internal.IImsFeatureStatusCallback; +import com.android.internal.annotations.VisibleForTesting; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; -import java.util.List; import java.util.Set; import java.util.WeakHashMap; /** - * Base class for all IMS features that are supported by the framework. + * Base class for all IMS features that are supported by the framework. Use a concrete subclass + * of {@link ImsFeature}, such as {@link MmTelFeature} or {@link RcsFeature}. + * * @hide */ +@SystemApi public abstract class ImsFeature { private static final String LOG_TAG = "ImsFeature"; @@ -46,7 +53,8 @@ public abstract class ImsFeature { /** * Action to broadcast when ImsService is up. * Internal use only. - * Only defined here separately compatibility purposes with the old ImsService. + * Only defined here separately for compatibility purposes with the old ImsService. + * * @hide */ public static final String ACTION_IMS_SERVICE_UP = @@ -56,6 +64,7 @@ public abstract class ImsFeature { * Action to broadcast when ImsService is down. * Internal use only. * Only defined here separately for compatibility purposes with the old ImsService. + * * @hide */ public static final String ACTION_IMS_SERVICE_DOWN = @@ -65,67 +74,329 @@ public abstract class ImsFeature { * Part of the ACTION_IMS_SERVICE_UP or _DOWN intents. * A long value; the phone ID corresponding to the IMS service coming up or down. * Only defined here separately for compatibility purposes with the old ImsService. + * * @hide */ public static final String EXTRA_PHONE_ID = "android:phone_id"; - // Invalid feature value - public static final int INVALID = -1; + /** + * Invalid feature value\ + * @hide + */ + public static final int FEATURE_INVALID = -1; // ImsFeatures that are defined in the Manifests. Ensure that these values match the previously // defined values in ImsServiceClass for compatibility purposes. - public static final int EMERGENCY_MMTEL = 0; - public static final int MMTEL = 1; - public static final int RCS = 2; - // Total number of features defined - public static final int MAX = 3; + /** + * This feature supports emergency calling over MMTEL. + */ + public static final int FEATURE_EMERGENCY_MMTEL = 0; + /** + * This feature supports the MMTEL feature. + */ + public static final int FEATURE_MMTEL = 1; + /** + * This feature supports the RCS feature. + */ + public static final int FEATURE_RCS = 2; + /** + * Total number of features defined + * @hide + */ + public static final int FEATURE_MAX = 3; - // Integer values defining the state of the ImsFeature at any time. + /** + * Integer values defining IMS features that are supported in ImsFeature. + * @hide + */ @IntDef(flag = true, value = { - STATE_NOT_AVAILABLE, + FEATURE_EMERGENCY_MMTEL, + FEATURE_MMTEL, + FEATURE_RCS + }) + @Retention(RetentionPolicy.SOURCE) + public @interface FeatureType {} + + /** + * Integer values defining the state of the ImsFeature at any time. + * @hide + */ + @IntDef(flag = true, + value = { + STATE_UNAVAILABLE, STATE_INITIALIZING, STATE_READY, }) @Retention(RetentionPolicy.SOURCE) public @interface ImsState {} - public static final int STATE_NOT_AVAILABLE = 0; + + /** + * This {@link ImsFeature}'s state is unavailable and should not be communicated with. + */ + public static final int STATE_UNAVAILABLE = 0; + /** + * This {@link ImsFeature} state is initializing and should not be communicated with. + */ public static final int STATE_INITIALIZING = 1; + /** + * This {@link ImsFeature} is ready for communication. + */ public static final int STATE_READY = 2; + /** + * Integer values defining the result codes that should be returned from + * {@link #changeEnabledCapabilities} when the framework tries to set a feature's capability. + * @hide + */ + @IntDef(flag = true, + value = { + CAPABILITY_ERROR_GENERIC, + CAPABILITY_SUCCESS + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ImsCapabilityError {} + + /** + * The capability was unable to be changed. + */ + public static final int CAPABILITY_ERROR_GENERIC = -1; + /** + * The capability was able to be changed. + */ + public static final int CAPABILITY_SUCCESS = 0; + + + /** + * The framework implements this callback in order to register for Feature Capability status + * updates, via {@link #onCapabilitiesStatusChanged(Capabilities)}, query Capability + * configurations, via {@link #onQueryCapabilityConfiguration}, as well as to receive error + * callbacks when the ImsService can not change the capability as requested, via + * {@link #onChangeCapabilityConfigurationError}. + * + * @hide + */ + public static class CapabilityCallback extends IImsCapabilityCallback.Stub { + + @Override + public final void onCapabilitiesStatusChanged(int config) throws RemoteException { + onCapabilitiesStatusChanged(new Capabilities(config)); + } + + /** + * Returns the result of a query for the capability configuration of a requested capability. + * + * @param capability The capability that was requested. + * @param radioTech The IMS radio technology associated with the capability. + * @param isEnabled true if the capability is enabled, false otherwise. + */ + @Override + public void onQueryCapabilityConfiguration(int capability, int radioTech, + boolean isEnabled) { + + } + + /** + * Called when a change to the capability configuration has returned an error. + * + * @param capability The capability that was requested to be changed. + * @param radioTech The IMS radio technology associated with the capability. + * @param reason error associated with the failure to change configuration. + */ + @Override + public void onChangeCapabilityConfigurationError(int capability, int radioTech, + @ImsCapabilityError int reason) { + } + + /** + * The status of the feature's capabilities has changed to either available or unavailable. + * If unavailable, the feature is not able to support the unavailable capability at this + * time. + * + * @param config The new availability of the capabilities. + */ + public void onCapabilitiesStatusChanged(Capabilities config) { + } + } + + /** + * Used by the ImsFeature to call back to the CapabilityCallback that the framework has + * provided. + */ + protected static class CapabilityCallbackProxy { + private final IImsCapabilityCallback mCallback; + + /** @hide */ + public CapabilityCallbackProxy(IImsCapabilityCallback c) { + mCallback = c; + } + + /** + * This method notifies the provided framework callback that the request to change the + * indicated capability has failed and has not changed. + * + * @param capability The Capability that will be notified to the framework, defined as + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE}, + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO}, + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT}, or + * {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS}. + * @param radioTech The radio tech that this capability failed for, defined as + * {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE} or + * {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}. + * @param reason The reason this capability was unable to be changed, defined as + * {@link #CAPABILITY_ERROR_GENERIC} or {@link #CAPABILITY_SUCCESS}. + */ + public void onChangeCapabilityConfigurationError(int capability, int radioTech, + @ImsCapabilityError int reason) { + if (mCallback == null) { + return; + } + try { + mCallback.onChangeCapabilityConfigurationError(capability, radioTech, reason); + } catch (RemoteException e) { + Log.e(LOG_TAG, "onChangeCapabilityConfigurationError called on dead binder."); + } + } + } + + /** + * Contains the capabilities defined and supported by an ImsFeature in the form of a bit mask. + * @hide + */ + public static class Capabilities { + protected int mCapabilities = 0; + + public Capabilities() { + } + + protected Capabilities(int capabilities) { + mCapabilities = capabilities; + } + + /** + * @param capabilities Capabilities to be added to the configuration in the form of a + * bit mask. + */ + public void addCapabilities(int capabilities) { + mCapabilities |= capabilities; + } + + /** + * @param capabilities Capabilities to be removed to the configuration in the form of a + * bit mask. + */ + public void removeCapabilities(int capabilities) { + mCapabilities &= ~capabilities; + } + + /** + * @return true if all of the capabilities specified are capable. + */ + public boolean isCapable(int capabilities) { + return (mCapabilities & capabilities) == capabilities; + } + + /** + * @return a deep copy of the Capabilites. + */ + public Capabilities copy() { + return new Capabilities(mCapabilities); + } + + /** + * @return a bitmask containing the capability flags directly. + */ + public int getMask() { + return mCapabilities; + } + + /** + * @hide + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Capabilities)) return false; + + Capabilities that = (Capabilities) o; + + return mCapabilities == that.mCapabilities; + } + + /** + * @hide + */ + @Override + public int hashCode() { + return mCapabilities; + } + + /** + * @hide + */ + @Override + public String toString() { + return "Capabilities: " + Integer.toBinaryString(mCapabilities); + } + } + private final Set<IImsFeatureStatusCallback> mStatusCallbacks = Collections.newSetFromMap( new WeakHashMap<IImsFeatureStatusCallback, Boolean>()); - private @ImsState int mState = STATE_NOT_AVAILABLE; + private @ImsState int mState = STATE_UNAVAILABLE; private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX; + /** + * @hide + */ protected Context mContext; + private final Object mLock = new Object(); + private final RemoteCallbackList<IImsCapabilityCallback> mCapabilityCallbacks + = new RemoteCallbackList<>(); + private Capabilities mCapabilityStatus = new Capabilities(); - public void setContext(Context context) { + /** + * @hide + */ + public final void initialize(Context context, int slotId) { mContext = context; - } - - public void setSlotId(int slotId) { mSlotId = slotId; } + /** + * @return The current state of the feature, defined as {@link #STATE_UNAVAILABLE}, + * {@link #STATE_INITIALIZING}, or {@link #STATE_READY}. + * @hide + */ public int getFeatureState() { - return mState; + synchronized (mLock) { + return mState; + } } - protected final void setFeatureState(@ImsState int state) { - if (mState != state) { - mState = state; - notifyFeatureState(state); + /** + * Set the state of the ImsFeature. The state is used as a signal to the framework to start or + * stop communication, depending on the state sent. + * @param state The ImsFeature's state, defined as {@link #STATE_UNAVAILABLE}, + * {@link #STATE_INITIALIZING}, or {@link #STATE_READY}. + */ + public final void setFeatureState(@ImsState int state) { + synchronized (mLock) { + if (mState != state) { + mState = state; + notifyFeatureState(state); + } } } - public void addImsFeatureStatusCallback(IImsFeatureStatusCallback c) { - if (c == null) { - return; - } + /** + * Not final for testing, but shouldn't be extended! + * @hide + */ + @VisibleForTesting + public void addImsFeatureStatusCallback(@NonNull IImsFeatureStatusCallback c) { try { // If we have just connected, send queued status. - c.notifyImsFeatureStatus(mState); + c.notifyImsFeatureStatus(getFeatureState()); // Add the callback if the callback completes successfully without a RemoteException. - synchronized (mStatusCallbacks) { + synchronized (mLock) { mStatusCallbacks.add(c); } } catch (RemoteException e) { @@ -133,23 +404,24 @@ public abstract class ImsFeature { } } - public void removeImsFeatureStatusCallback(IImsFeatureStatusCallback c) { - if (c == null) { - return; - } - synchronized (mStatusCallbacks) { + /** + * Not final for testing, but shouldn't be extended! + * @hide + */ + @VisibleForTesting + public void removeImsFeatureStatusCallback(@NonNull IImsFeatureStatusCallback c) { + synchronized (mLock) { mStatusCallbacks.remove(c); } } /** * Internal method called by ImsFeature when setFeatureState has changed. - * @param state */ private void notifyFeatureState(@ImsState int state) { - synchronized (mStatusCallbacks) { + synchronized (mLock) { for (Iterator<IImsFeatureStatusCallback> iter = mStatusCallbacks.iterator(); - iter.hasNext(); ) { + iter.hasNext(); ) { IImsFeatureStatusCallback callback = iter.next(); try { Log.i(LOG_TAG, "notifying ImsFeatureState=" + state); @@ -168,12 +440,12 @@ public abstract class ImsFeature { * Provide backwards compatibility using deprecated service UP/DOWN intents. */ private void sendImsServiceIntent(@ImsState int state) { - if(mContext == null || mSlotId == SubscriptionManager.INVALID_SIM_SLOT_INDEX) { + if (mContext == null || mSlotId == SubscriptionManager.INVALID_SIM_SLOT_INDEX) { return; } Intent intent; switch (state) { - case ImsFeature.STATE_NOT_AVAILABLE: + case ImsFeature.STATE_UNAVAILABLE: case ImsFeature.STATE_INITIALIZING: intent = new Intent(ACTION_IMS_SERVICE_DOWN); break; @@ -188,17 +460,104 @@ public abstract class ImsFeature { } /** - * Called when the feature is ready to use. + * @hide */ - public abstract void onFeatureReady(); + public final void addCapabilityCallback(IImsCapabilityCallback c) { + mCapabilityCallbacks.register(c); + } + + /** + * @hide + */ + public final void removeCapabilityCallback(IImsCapabilityCallback c) { + mCapabilityCallbacks.unregister(c); + } + + /** + * @return the cached capabilities status for this feature. + * @hide + */ + @VisibleForTesting + public Capabilities queryCapabilityStatus() { + synchronized (mLock) { + return mCapabilityStatus.copy(); + } + } + + /** + * Called internally to request the change of enabled capabilities. + * @hide + */ + @VisibleForTesting + public final void requestChangeEnabledCapabilities(CapabilityChangeRequest request, + IImsCapabilityCallback c) { + if (request == null) { + throw new IllegalArgumentException( + "ImsFeature#requestChangeEnabledCapabilities called with invalid params."); + } + changeEnabledCapabilities(request, new CapabilityCallbackProxy(c)); + } /** - * Called when the feature is being removed and must be cleaned up. + * Called by the ImsFeature when the capabilities status has changed. + * + * @param c A {@link Capabilities} containing the new Capabilities status. + * + * @hide + */ + protected final void notifyCapabilitiesStatusChanged(Capabilities c) { + synchronized (mLock) { + mCapabilityStatus = c.copy(); + } + int count = mCapabilityCallbacks.beginBroadcast(); + try { + for (int i = 0; i < count; i++) { + try { + mCapabilityCallbacks.getBroadcastItem(i).onCapabilitiesStatusChanged( + c.mCapabilities); + } catch (RemoteException e) { + Log.w(LOG_TAG, e + " " + "notifyCapabilitiesStatusChanged() - Skipping " + + "callback."); + } + } + } finally { + mCapabilityCallbacks.finishBroadcast(); + } + } + + /** + * Features should override this method to receive Capability preference change requests from + * the framework using the provided {@link CapabilityChangeRequest}. If any of the capabilities + * in the {@link CapabilityChangeRequest} are not able to be completed due to an error, + * {@link CapabilityCallbackProxy#onChangeCapabilityConfigurationError} should be called for + * each failed capability. + * + * @param request A {@link CapabilityChangeRequest} containing requested capabilities to + * enable/disable. + * @param c A {@link CapabilityCallbackProxy}, which will be used to call back to the framework + * setting a subset of these capabilities fail, using + * {@link CapabilityCallbackProxy#onChangeCapabilityConfigurationError}. + */ + public abstract void changeEnabledCapabilities(CapabilityChangeRequest request, + CapabilityCallbackProxy c); + + /** + * Called when the framework is removing this feature and it needs to be cleaned up. */ public abstract void onFeatureRemoved(); /** - * @return Binder instance + * Called when the feature has been initialized and communication with the framework is set up. + * Any attempt by this feature to access the framework before this method is called will return + * with an {@link IllegalStateException}. + * The IMS provider should use this method to trigger registration for this feature on the IMS + * network, if needed. + */ + public abstract void onFeatureReady(); + + /** + * @return Binder instance that the framework will use to communicate with this feature. + * @hide */ - public abstract IInterface getBinder(); + protected abstract IInterface getBinder(); } diff --git a/telephony/java/android/telephony/ims/internal/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java index 9b576c72fa96..09267fc2554c 100644 --- a/telephony/java/android/telephony/ims/internal/feature/MmTelFeature.java +++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * 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. @@ -14,29 +14,33 @@ * limitations under the License */ -package android.telephony.ims.internal.feature; +package android.telephony.ims.feature; import android.annotation.IntDef; +import android.annotation.SystemApi; +import android.net.Uri; +import android.os.Bundle; import android.os.Message; import android.os.RemoteException; import android.telecom.TelecomManager; -import android.telephony.ims.internal.ImsCallSessionListener; -import android.telephony.ims.internal.aidl.IImsCallSessionListener; -import android.telephony.ims.internal.aidl.IImsCapabilityCallback; -import android.telephony.ims.internal.aidl.IImsMmTelFeature; -import android.telephony.ims.internal.aidl.IImsMmTelListener; import android.telephony.ims.stub.ImsRegistrationImplBase; +import android.telephony.ims.stub.ImsCallSessionImplBase; +import android.telephony.ims.stub.ImsSmsImplBase; +import android.telephony.ims.aidl.IImsCapabilityCallback; +import android.telephony.ims.aidl.IImsMmTelFeature; +import android.telephony.ims.aidl.IImsMmTelListener; +import android.telephony.ims.aidl.IImsSmsListener; import android.telephony.ims.stub.ImsEcbmImplBase; import android.telephony.ims.stub.ImsMultiEndpointImplBase; import android.telephony.ims.stub.ImsUtImplBase; import android.util.Log; -import com.android.ims.ImsCallProfile; +import android.telephony.ims.ImsCallProfile; import com.android.ims.internal.IImsCallSession; import com.android.ims.internal.IImsEcbm; import com.android.ims.internal.IImsMultiEndpoint; import com.android.ims.internal.IImsUt; -import com.android.ims.internal.ImsCallSession; +import android.telephony.ims.ImsCallSession; import com.android.internal.annotations.VisibleForTesting; import java.lang.annotation.Retention; @@ -49,7 +53,7 @@ import java.lang.annotation.RetentionPolicy; * service supports. * @hide */ - +@SystemApi public class MmTelFeature extends ImsFeature { private static final String LOG_TAG = "MmTelFeature"; @@ -66,7 +70,11 @@ public class MmTelFeature extends ImsFeature { @Override public int getFeatureState() throws RemoteException { synchronized (mLock) { - return MmTelFeature.this.getFeatureState(); + try { + return MmTelFeature.this.getFeatureState(); + } catch (Exception e) { + throw new RemoteException(e.getMessage()); + } } } @@ -75,45 +83,57 @@ public class MmTelFeature extends ImsFeature { public ImsCallProfile createCallProfile(int callSessionType, int callType) throws RemoteException { synchronized (mLock) { - return MmTelFeature.this.createCallProfile(callSessionType, callType); + try { + return MmTelFeature.this.createCallProfile(callSessionType, callType); + } catch (Exception e) { + throw new RemoteException(e.getMessage()); + } + } + } + + @Override + public IImsCallSession createCallSession(ImsCallProfile profile) throws RemoteException { + synchronized (mLock) { + return createCallSessionInterface(profile); } } @Override - public IImsCallSession createCallSession(ImsCallProfile profile, - IImsCallSessionListener listener) throws RemoteException { + public int shouldProcessCall(String[] numbers) { synchronized (mLock) { - ImsCallSession s = MmTelFeature.this.createCallSession(profile, - new ImsCallSessionListener(listener)); - return s != null ? s.getSession() : null; + return MmTelFeature.this.shouldProcessCall(numbers); } } @Override public IImsUt getUtInterface() throws RemoteException { synchronized (mLock) { - return MmTelFeature.this.getUt(); + return MmTelFeature.this.getUtInterface(); } } @Override public IImsEcbm getEcbmInterface() throws RemoteException { synchronized (mLock) { - return MmTelFeature.this.getEcbm(); + return MmTelFeature.this.getEcbmInterface(); } } @Override public void setUiTtyMode(int uiTtyMode, Message onCompleteMessage) throws RemoteException { synchronized (mLock) { - MmTelFeature.this.setUiTtyMode(uiTtyMode, onCompleteMessage); + try { + MmTelFeature.this.setUiTtyMode(uiTtyMode, onCompleteMessage); + } catch (Exception e) { + throw new RemoteException(e.getMessage()); + } } } @Override public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException { synchronized (mLock) { - return MmTelFeature.this.getMultiEndpoint(); + return MmTelFeature.this.getMultiEndpointInterface(); } } @@ -143,11 +163,56 @@ public class MmTelFeature extends ImsFeature { IImsCapabilityCallback c) { queryCapabilityConfigurationInternal(capability, radioTech, c); } + + @Override + public void setSmsListener(IImsSmsListener l) throws RemoteException { + MmTelFeature.this.setSmsListener(l); + } + + @Override + public void sendSms(int token, int messageRef, String format, String smsc, boolean retry, + byte[] pdu) { + synchronized (mLock) { + MmTelFeature.this.sendSms(token, messageRef, format, smsc, retry, pdu); + } + } + + @Override + public void acknowledgeSms(int token, int messageRef, int result) { + synchronized (mLock) { + MmTelFeature.this.acknowledgeSms(token, messageRef, result); + } + } + + @Override + public void acknowledgeSmsReport(int token, int messageRef, int result) { + synchronized (mLock) { + MmTelFeature.this.acknowledgeSmsReport(token, messageRef, result); + } + } + + @Override + public String getSmsFormat() { + synchronized (mLock) { + return MmTelFeature.this.getSmsFormat(); + } + } + + @Override + public void onSmsReady() { + synchronized (mLock) { + MmTelFeature.this.onSmsReady(); + } + } }; /** * Contains the capabilities defined and supported by a MmTelFeature in the form of a Bitmask. - * The capabilities that are used in MmTelFeature are defined by {@link MmTelCapability}. + * The capabilities that are used in MmTelFeature are defined as + * {@link MmTelCapabilities#CAPABILITY_TYPE_VOICE}, + * {@link MmTelCapabilities#CAPABILITY_TYPE_VIDEO}, + * {@link MmTelCapabilities#CAPABILITY_TYPE_UT}, and + * {@link MmTelCapabilities#CAPABILITY_TYPE_SMS}. * * The capabilities of this MmTelFeature will be set by the framework and can be queried with * {@link #queryCapabilityStatus()}. @@ -158,6 +223,9 @@ public class MmTelFeature extends ImsFeature { */ public static class MmTelCapabilities extends Capabilities { + /** + * @hide + */ @VisibleForTesting public MmTelCapabilities() { super(); @@ -167,6 +235,10 @@ public class MmTelFeature extends ImsFeature { mCapabilities = c.mCapabilities; } + public MmTelCapabilities(int capabilities) { + mCapabilities = capabilities; + } + @IntDef(flag = true, value = { CAPABILITY_TYPE_VOICE, @@ -211,16 +283,36 @@ public class MmTelFeature extends ImsFeature { public final boolean isCapable(@MmTelCapability int capabilities) { return super.isCapable(capabilities); } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder("MmTel Capabilities - ["); + builder.append("Voice: "); + builder.append(isCapable(CAPABILITY_TYPE_VOICE)); + builder.append(" Video: "); + builder.append(isCapable(CAPABILITY_TYPE_VIDEO)); + builder.append(" UT: "); + builder.append(isCapable(CAPABILITY_TYPE_UT)); + builder.append(" SMS: "); + builder.append(isCapable(CAPABILITY_TYPE_SMS)); + builder.append("]"); + return builder.toString(); + } } /** * Listener that the framework implements for communication from the MmTelFeature. + * @hide */ public static class Listener extends IImsMmTelListener.Stub { + /** + * Called when the IMS provider receives an incoming call. + * @param c The {@link ImsCallSession} associated with the new call. + */ @Override - public final void onIncomingCall(IImsCallSession c) { - onIncomingCall(new ImsCallSession(c)); + public void onIncomingCall(IImsCallSession c, Bundle extras) { + } /** @@ -231,15 +323,34 @@ public class MmTelFeature extends ImsFeature { public void onVoiceMessageCountUpdate(int count) { } - - /** - * Called when the IMS provider receives an incoming call. - * @param c The {@link ImsCallSession} associated with the new call. - */ - public void onIncomingCall(ImsCallSession c) { - } } + /** + * To be returned by {@link #shouldProcessCall(String[])} when the ImsService should process the + * outgoing call as IMS. + */ + public static final int PROCESS_CALL_IMS = 0; + /** + * To be returned by {@link #shouldProcessCall(String[])} when the telephony framework should + * not process the outgoing NON_EMERGENCY call as IMS and should instead use circuit switch. + */ + public static final int PROCESS_CALL_CSFB = 1; + /** + * To be returned by {@link #shouldProcessCall(String[])} when the telephony framework should + * not process the outgoing EMERGENCY call as IMS and should instead use circuit switch. + */ + public static final int PROCESS_CALL_EMERGENCY_CSFB = 2; + + @IntDef(flag = true, + value = { + PROCESS_CALL_IMS, + PROCESS_CALL_CSFB, + PROCESS_CALL_EMERGENCY_CSFB + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ProcessCallResult {} + + // Lock for feature synchronization private final Object mLock = new Object(); private IImsMmTelListener mListener; @@ -252,6 +363,9 @@ public class MmTelFeature extends ImsFeature { synchronized (mLock) { mListener = listener; } + if (mListener != null) { + onFeatureReady(); + } } private void queryCapabilityConfigurationInternal(int capability, int radioTech, @@ -289,23 +403,58 @@ public class MmTelFeature extends ImsFeature { * support the capability that is enabled. A capability that is disabled by the framework (via * {@link #changeEnabledCapabilities}) should also show the status as disabled. */ - protected final void notifyCapabilitiesStatusChanged(MmTelCapabilities c) { + public final void notifyCapabilitiesStatusChanged(MmTelCapabilities c) { super.notifyCapabilitiesStatusChanged(c); } /** * Notify the framework of an incoming call. - * @param c The {@link ImsCallSession} of the new incoming call. + * @param c The {@link ImsCallSessionImplBase} of the new incoming call. + */ + public final void notifyIncomingCall(ImsCallSessionImplBase c, Bundle extras) { + synchronized (mLock) { + if (mListener == null) { + throw new IllegalStateException("Session is not available."); + } + try { + mListener.onIncomingCall(c.getServiceImpl(), extras); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + } + + /** * - * @throws RemoteException if the connection to the framework is not available. If this happens, - * the call should be no longer considered active and should be cleaned up. - * */ - protected final void notifyIncomingCall(ImsCallSession c) throws RemoteException { + * @hide + */ + public final void notifyIncomingCallSession(IImsCallSession c, Bundle extras) { + synchronized (mLock) { + if (mListener == null) { + throw new IllegalStateException("Session is not available."); + } + try { + mListener.onIncomingCall(c, extras); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + } + + /** + * Notify the framework of a change in the Voice Message count. + * @link count the new Voice Message count. + */ + public final void notifyVoiceMessageCountUpdate(int count) { synchronized (mLock) { if (mListener == null) { throw new IllegalStateException("Session is not available."); } - mListener.onIncomingCall(c.getSession()); + try { + mListener.onVoiceMessageCountUpdate(count); + } catch (RemoteException e) { + throw new RuntimeException(e); + } } } @@ -365,21 +514,67 @@ public class MmTelFeature extends ImsFeature { } /** + * @hide + */ + public IImsCallSession createCallSessionInterface(ImsCallProfile profile) + throws RemoteException { + ImsCallSessionImplBase s = MmTelFeature.this.createCallSession(profile); + return s != null ? s.getServiceImpl() : null; + } + + /** * Creates an {@link ImsCallSession} with the specified call profile. * Use other methods, if applicable, instead of interacting with * {@link ImsCallSession} directly. * * @param profile a call profile to make the call - * @param listener An implementation of IImsCallSessionListener. */ - public ImsCallSession createCallSession(ImsCallProfile profile, - ImsCallSessionListener listener) { + public ImsCallSessionImplBase createCallSession(ImsCallProfile profile) { // Base Implementation - Should be overridden return null; } /** - * @return The Ut interface for the supplementary service configuration. + * Called by the framework to determine if the outgoing call, designated by the outgoing + * {@link Uri}s, should be processed as an IMS call or CSFB call. + * @param numbers An array of {@link String}s that will be used for placing the call. There can + * be multiple {@link String}s listed in the case when we want to place an outgoing + * call as a conference. + * @return a {@link ProcessCallResult} to the framework, which will be used to determine if the + * call wil lbe placed over IMS or via CSFB. + */ + public @ProcessCallResult int shouldProcessCall(String[] numbers) { + return PROCESS_CALL_IMS; + } + + /** + * + * @hide + */ + protected IImsUt getUtInterface() throws RemoteException { + ImsUtImplBase utImpl = getUt(); + return utImpl != null ? utImpl.getInterface() : null; + } + + /** + * @hide + */ + protected IImsEcbm getEcbmInterface() throws RemoteException { + ImsEcbmImplBase ecbmImpl = getEcbm(); + return ecbmImpl != null ? ecbmImpl.getImsEcbm() : null; + } + + /** + * @hide + */ + public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException { + ImsMultiEndpointImplBase multiendpointImpl = getMultiEndpoint(); + return multiendpointImpl != null ? multiendpointImpl.getIImsMultiEndpoint() : null; + } + + /** + * @return The {@link ImsUtImplBase} Ut interface implementation for the supplementary service + * configuration. */ public ImsUtImplBase getUt() { // Base Implementation - Should be overridden @@ -387,7 +582,8 @@ public class MmTelFeature extends ImsFeature { } /** - * @return The Emergency call-back mode interface for emergency VoLTE calls that support it. + * @return The {@link ImsEcbmImplBase} Emergency call-back mode interface for emergency VoLTE + * calls that support it. */ public ImsEcbmImplBase getEcbm() { // Base Implementation - Should be overridden @@ -395,7 +591,8 @@ public class MmTelFeature extends ImsFeature { } /** - * @return The Emergency call-back mode interface for emergency VoLTE calls that support it. + * @return The {@link ImsMultiEndpointImplBase} implementation for implementing Dialog event + * package processing for multi-endpoint. */ public ImsMultiEndpointImplBase getMultiEndpoint() { // Base Implementation - Should be overridden @@ -411,10 +608,48 @@ public class MmTelFeature extends ImsFeature { * {@link TelecomManager#TTY_MODE_VCO} * @param onCompleteMessage A {@link Message} to be used when the mode has been set. */ - void setUiTtyMode(int mode, Message onCompleteMessage) { + public void setUiTtyMode(int mode, Message onCompleteMessage) { // Base Implementation - Should be overridden } + private void setSmsListener(IImsSmsListener listener) { + getSmsImplementation().registerSmsListener(listener); + } + + private void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry, + byte[] pdu) { + getSmsImplementation().sendSms(token, messageRef, format, smsc, isRetry, pdu); + } + + private void acknowledgeSms(int token, int messageRef, + @ImsSmsImplBase.DeliverStatusResult int result) { + getSmsImplementation().acknowledgeSms(token, messageRef, result); + } + + private void acknowledgeSmsReport(int token, int messageRef, + @ImsSmsImplBase.StatusReportResult int result) { + getSmsImplementation().acknowledgeSmsReport(token, messageRef, result); + } + + private void onSmsReady() { + getSmsImplementation().onReady(); + } + + /** + * Must be overridden by IMS Provider to be able to support SMS over IMS. Otherwise a default + * non-functional implementation is returned. + * + * @return an instance of {@link ImsSmsImplBase} which should be implemented by the IMS + * Provider. + */ + public ImsSmsImplBase getSmsImplementation() { + return new ImsSmsImplBase(); + } + + private String getSmsFormat() { + return getSmsImplementation().getSmsFormat(); + } + /**{@inheritDoc}*/ @Override public void onFeatureRemoved() { diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java index 40c5181d6bca..a637e16d0a48 100644 --- a/telephony/java/android/telephony/ims/feature/RcsFeature.java +++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * 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. @@ -16,16 +16,18 @@ package android.telephony.ims.feature; -import com.android.ims.internal.IImsRcsFeature; +import android.annotation.SystemApi; +import android.telephony.ims.aidl.IImsRcsFeature; /** * Base implementation of the RcsFeature APIs. Any ImsService wishing to support RCS should extend * this class and provide implementations of the RcsFeature methods that they support. * @hide */ - +@SystemApi public class RcsFeature extends ImsFeature { + /**{@inheritDoc}*/ private final IImsRcsFeature mImsRcsBinder = new IImsRcsFeature.Stub() { // Empty Default Implementation. }; @@ -35,16 +37,30 @@ public class RcsFeature extends ImsFeature { super(); } + /** + * {@inheritDoc} + */ @Override - public void onFeatureReady() { - + public void changeEnabledCapabilities(CapabilityChangeRequest request, + CapabilityCallbackProxy c) { + // Do nothing for base implementation. } + /**{@inheritDoc}*/ @Override public void onFeatureRemoved() { } + /**{@inheritDoc}*/ + @Override + public void onFeatureReady() { + + } + + /** + * @hide + */ @Override public final IImsRcsFeature getBinder() { return mImsRcsBinder; diff --git a/telephony/java/android/telephony/ims/internal/ImsCallSessionListener.java b/telephony/java/android/telephony/ims/internal/ImsCallSessionListener.java deleted file mode 100644 index 5d16dd5b30ee..000000000000 --- a/telephony/java/android/telephony/ims/internal/ImsCallSessionListener.java +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package android.telephony.ims.internal; - -import android.os.RemoteException; -import android.telephony.ims.internal.aidl.IImsCallSessionListener; - -import com.android.ims.ImsCallProfile; -import com.android.ims.ImsConferenceState; -import com.android.ims.ImsReasonInfo; -import com.android.ims.ImsStreamMediaProfile; -import com.android.ims.ImsSuppServiceNotification; -import com.android.ims.internal.ImsCallSession; - -/** - * Proxy class for interfacing with the framework's Call session for an ongoing IMS call. - * - * DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you - * will break other implementations of ImsCallSessionListener maintained by other ImsServices. - * - * @hide - */ -public class ImsCallSessionListener { - - private final IImsCallSessionListener mListener; - - public ImsCallSessionListener(IImsCallSessionListener l) { - mListener = l; - } - - /** - * Called when a request is sent out to initiate a new session - * and 1xx response is received from the network. - */ - public void callSessionProgressing(ImsStreamMediaProfile profile) - throws RemoteException { - mListener.callSessionProgressing(profile); - } - - /** - * Called when the session is initiated. - * - * @param profile the associated {@link ImsCallSession}. - */ - public void callSessionInitiated(ImsCallProfile profile) throws RemoteException { - mListener.callSessionInitiated(profile); - } - - /** - * Called when the session establishment has failed. - * - * @param reasonInfo detailed reason of the session establishment failure - */ - public void callSessionInitiatedFailed(ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionInitiatedFailed(reasonInfo); - } - - /** - * Called when the session is terminated. - * - * @param reasonInfo detailed reason of the session termination - */ - public void callSessionTerminated(ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionTerminated(reasonInfo); - } - - /** - * Called when the session is on hold. - */ - public void callSessionHeld(ImsCallProfile profile) throws RemoteException { - mListener.callSessionHeld(profile); - } - - /** - * Called when the session hold has failed. - * - * @param reasonInfo detailed reason of the session hold failure - */ - public void callSessionHoldFailed(ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionHoldFailed(reasonInfo); - } - - /** - * Called when the session hold is received from the remote user. - */ - public void callSessionHoldReceived(ImsCallProfile profile) throws RemoteException { - mListener.callSessionHoldReceived(profile); - } - - /** - * Called when the session resume is done. - */ - public void callSessionResumed(ImsCallProfile profile) throws RemoteException { - mListener.callSessionResumed(profile); - } - - /** - * Called when the session resume has failed. - * - * @param reasonInfo detailed reason of the session resume failure - */ - public void callSessionResumeFailed(ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionResumeFailed(reasonInfo); - } - - /** - * Called when the session resume is received from the remote user. - */ - public void callSessionResumeReceived(ImsCallProfile profile) throws RemoteException { - mListener.callSessionResumeReceived(profile); - } - - /** - * Called when the session merge has been started. At this point, the {@code newSession} - * represents the session which has been initiated to the IMS conference server for the - * new merged conference. - * - * @param newSession the session object that is merged with an active & hold session - */ - public void callSessionMergeStarted(ImsCallSession newSession, ImsCallProfile profile) - throws RemoteException { - mListener.callSessionMergeStarted(newSession != null ? newSession.getSession() : null, - profile); - } - - /** - * Called when the session merge is successful and the merged session is active. - * - * @param newSession the new session object that is used for the conference - */ - public void callSessionMergeComplete(ImsCallSession newSession) throws RemoteException { - mListener.callSessionMergeComplete(newSession != null ? newSession.getSession() : null); - } - - /** - * Called when the session merge has failed. - * - * @param reasonInfo detailed reason of the call merge failure - */ - public void callSessionMergeFailed(ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionMergeFailed(reasonInfo); - } - - /** - * Called when the session is updated (except for hold/unhold). - */ - public void callSessionUpdated(ImsCallProfile profile) throws RemoteException { - mListener.callSessionUpdated(profile); - } - - /** - * Called when the session update has failed. - * - * @param reasonInfo detailed reason of the session update failure - */ - public void callSessionUpdateFailed(ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionUpdateFailed(reasonInfo); - } - - /** - * Called when the session update is received from the remote user. - */ - public void callSessionUpdateReceived(ImsCallProfile profile) throws RemoteException { - mListener.callSessionUpdateReceived(profile); - } - - /** - * Called when the session has been extended to a conference session. - * - * @param newSession the session object that is extended to the conference - * from the active session - */ - public void callSessionConferenceExtended(ImsCallSession newSession, ImsCallProfile profile) - throws RemoteException { - mListener.callSessionConferenceExtended(newSession != null ? newSession.getSession() : null, - profile); - } - - /** - * Called when the conference extension has failed. - * - * @param reasonInfo detailed reason of the conference extension failure - */ - public void callSessionConferenceExtendFailed(ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionConferenceExtendFailed(reasonInfo); - } - - /** - * Called when the conference extension is received from the remote user. - */ - public void callSessionConferenceExtendReceived(ImsCallSession newSession, - ImsCallProfile profile) throws RemoteException { - mListener.callSessionConferenceExtendReceived(newSession != null - ? newSession.getSession() : null, profile); - } - - /** - * Called when the invitation request of the participants is delivered to the conference - * server. - */ - public void callSessionInviteParticipantsRequestDelivered() throws RemoteException { - mListener.callSessionInviteParticipantsRequestDelivered(); - } - - /** - * Called when the invitation request of the participants has failed. - * - * @param reasonInfo detailed reason of the conference invitation failure - */ - public void callSessionInviteParticipantsRequestFailed(ImsReasonInfo reasonInfo) - throws RemoteException { - mListener.callSessionInviteParticipantsRequestFailed(reasonInfo); - } - - /** - * Called when the removal request of the participants is delivered to the conference - * server. - */ - public void callSessionRemoveParticipantsRequestDelivered() throws RemoteException { - mListener.callSessionRemoveParticipantsRequestDelivered(); - } - - /** - * Called when the removal request of the participants has failed. - * - * @param reasonInfo detailed reason of the conference removal failure - */ - public void callSessionRemoveParticipantsRequestFailed(ImsReasonInfo reasonInfo) - throws RemoteException { - mListener.callSessionInviteParticipantsRequestFailed(reasonInfo); - } - - /** - * Notifies the framework of the updated Call session conference state. - * - * @param state the new {@link ImsConferenceState} associated with the conference. - */ - public void callSessionConferenceStateUpdated(ImsConferenceState state) throws RemoteException { - mListener.callSessionConferenceStateUpdated(state); - } - - /** - * Notifies the incoming USSD message. - */ - public void callSessionUssdMessageReceived(int mode, String ussdMessage) - throws RemoteException { - mListener.callSessionUssdMessageReceived(mode, ussdMessage); - } - - /** - * Notifies of a case where a {@link com.android.ims.internal.ImsCallSession} may potentially - * handover from one radio technology to another. - * - * @param srcAccessTech The source radio access technology; one of the access technology - * constants defined in {@link android.telephony.ServiceState}. For - * example - * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}. - * @param targetAccessTech The target radio access technology; one of the access technology - * constants defined in {@link android.telephony.ServiceState}. For - * example - * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}. - */ - public void callSessionMayHandover(int srcAccessTech, int targetAccessTech) - throws RemoteException { - mListener.callSessionMayHandover(srcAccessTech, targetAccessTech); - } - - /** - * Called when session access technology changes. - * - * @param srcAccessTech original access technology - * @param targetAccessTech new access technology - * @param reasonInfo - */ - public void callSessionHandover(int srcAccessTech, int targetAccessTech, - ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionHandover(srcAccessTech, targetAccessTech, reasonInfo); - } - - /** - * Called when session access technology change fails. - * - * @param srcAccessTech original access technology - * @param targetAccessTech new access technology - * @param reasonInfo handover failure reason - */ - public void callSessionHandoverFailed(int srcAccessTech, int targetAccessTech, - ImsReasonInfo reasonInfo) throws RemoteException { - mListener.callSessionHandoverFailed(srcAccessTech, targetAccessTech, reasonInfo); - } - - /** - * Called when the TTY mode is changed by the remote party. - * - * @param mode one of the following: - - * {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} - - * {@link com.android.internal.telephony.Phone#TTY_MODE_FULL} - - * {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} - - * {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} - */ - public void callSessionTtyModeReceived(int mode) throws RemoteException { - mListener.callSessionTtyModeReceived(mode); - } - - /** - * Called when the multiparty state is changed for this {@code ImsCallSession}. - * - * @param isMultiParty {@code true} if the session became multiparty, - * {@code false} otherwise. - */ - - public void callSessionMultipartyStateChanged(boolean isMultiParty) throws RemoteException { - mListener.callSessionMultipartyStateChanged(isMultiParty); - } - - /** - * Called when the supplementary service information is received for the current session. - */ - public void callSessionSuppServiceReceived(ImsSuppServiceNotification suppSrvNotification) - throws RemoteException { - mListener.callSessionSuppServiceReceived(suppSrvNotification); - } - - /** - * Received RTT modify request from the remote party. - * - * @param callProfile ImsCallProfile with updated attributes - */ - public void callSessionRttModifyRequestReceived(ImsCallProfile callProfile) - throws RemoteException { - mListener.callSessionRttModifyRequestReceived(callProfile); - } - - /** - * @param status the received response for RTT modify request. - */ - public void callSessionRttModifyResponseReceived(int status) throws RemoteException { - mListener.callSessionRttModifyResponseReceived(status); - } - - /** - * Device received RTT message from Remote UE. - * - * @param rttMessage RTT message received - */ - public void callSessionRttMessageReceived(String rttMessage) throws RemoteException { - mListener.callSessionRttMessageReceived(rttMessage); - } -} - diff --git a/telephony/java/android/telephony/ims/internal/ImsService.java b/telephony/java/android/telephony/ims/internal/ImsService.java deleted file mode 100644 index afaf33294d8a..000000000000 --- a/telephony/java/android/telephony/ims/internal/ImsService.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package android.telephony.ims.internal; - -import android.app.Service; -import android.content.Intent; -import android.os.IBinder; -import android.os.RemoteException; -import android.telephony.CarrierConfigManager; -import android.telephony.ims.internal.aidl.IImsConfig; -import android.telephony.ims.internal.aidl.IImsMmTelFeature; -import android.telephony.ims.internal.aidl.IImsRcsFeature; -import android.telephony.ims.internal.aidl.IImsServiceController; -import android.telephony.ims.internal.aidl.IImsServiceControllerListener; -import android.telephony.ims.internal.feature.ImsFeature; -import android.telephony.ims.internal.feature.MmTelFeature; -import android.telephony.ims.internal.feature.RcsFeature; -import android.telephony.ims.internal.stub.ImsConfigImplBase; -import android.telephony.ims.internal.stub.ImsFeatureConfiguration; -import android.telephony.ims.stub.ImsRegistrationImplBase; -import android.util.Log; -import android.util.SparseArray; - -import com.android.ims.internal.IImsFeatureStatusCallback; -import com.android.ims.internal.IImsRegistration; -import com.android.internal.annotations.VisibleForTesting; - -/** - * Main ImsService implementation, which binds via the Telephony ImsResolver. Services that extend - * ImsService must register the service in their AndroidManifest to be detected by the framework. - * First, the application must declare that they use the "android.permission.BIND_IMS_SERVICE" - * permission. Then, the ImsService definition in the manifest must follow the following format: - * - * ... - * <service android:name=".EgImsService" - * android:permission="android.permission.BIND_IMS_SERVICE" > - * <!-- Apps must declare which features they support as metadata. The different categories are - * defined below. In this example, the RCS_FEATURE feature is supported. --> - * <meta-data android:name="android.telephony.ims.RCS_FEATURE" android:value="true" /> - * <intent-filter> - * <action android:name="android.telephony.ims.ImsService" /> - * </intent-filter> - * </service> - * ... - * - * The telephony framework will then bind to the ImsService you have defined in your manifest - * if you are either: - * 1) Defined as the default ImsService for the device in the device overlay using - * "config_ims_package". - * 2) Defined as a Carrier Provided ImsService in the Carrier Configuration using - * {@link CarrierConfigManager#KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING}. - * - * The features that are currently supported in an ImsService are: - * - RCS_FEATURE: This ImsService implements the RcsFeature class. - * - MMTEL_FEATURE: This ImsService implements the MmTelFeature class. - * @hide - */ -public class ImsService extends Service { - - private static final String LOG_TAG = "ImsService"; - - /** - * The intent that must be defined as an intent-filter in the AndroidManifest of the ImsService. - * @hide - */ - public static final String SERVICE_INTERFACE = "android.telephony.ims.ImsService"; - - // A map of slot Id -> map of features (indexed by ImsFeature feature id) corresponding to that - // slot. - // We keep track of this to facilitate cleanup of the IImsFeatureStatusCallback and - // call ImsFeature#onFeatureRemoved. - private final SparseArray<SparseArray<ImsFeature>> mFeaturesBySlot = new SparseArray<>(); - - private IImsServiceControllerListener mListener; - - - /** - * Listener that notifies the framework of ImsService changes. - */ - public static class Listener extends IImsServiceControllerListener.Stub { - /** - * The IMS features that this ImsService supports has changed. - * @param c a new {@link ImsFeatureConfiguration} containing {@link ImsFeature.FeatureType}s - * that this ImsService supports. This may trigger the addition/removal of feature - * in this service. - */ - public void onUpdateSupportedImsFeatures(ImsFeatureConfiguration c) { - } - } - - /** - * @hide - */ - protected final IBinder mImsServiceController = new IImsServiceController.Stub() { - @Override - public void setListener(IImsServiceControllerListener l) { - mListener = l; - } - - @Override - public IImsMmTelFeature createMmTelFeature(int slotId, IImsFeatureStatusCallback c) { - return createMmTelFeatureInternal(slotId, c); - } - - @Override - public IImsRcsFeature createRcsFeature(int slotId, IImsFeatureStatusCallback c) { - return createRcsFeatureInternal(slotId, c); - } - - @Override - public void removeImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c) - throws RemoteException { - ImsService.this.removeImsFeature(slotId, featureType, c); - } - - @Override - public ImsFeatureConfiguration querySupportedImsFeatures() { - return ImsService.this.querySupportedImsFeatures(); - } - - @Override - public void notifyImsServiceReadyForFeatureCreation() { - ImsService.this.readyForFeatureCreation(); - } - - @Override - public void notifyImsFeatureReady(int slotId, int featureType) - throws RemoteException { - ImsService.this.notifyImsFeatureReady(slotId, featureType); - } - - @Override - public IImsConfig getConfig(int slotId) throws RemoteException { - ImsConfigImplBase c = ImsService.this.getConfig(slotId); - return c != null ? c.getBinder() : null; - } - - @Override - public IImsRegistration getRegistration(int slotId) throws RemoteException { - ImsRegistrationImplBase r = ImsService.this.getRegistration(slotId); - return r != null ? r.getBinder() : null; - } - }; - - /** - * @hide - */ - @Override - public IBinder onBind(Intent intent) { - if(SERVICE_INTERFACE.equals(intent.getAction())) { - Log.i(LOG_TAG, "ImsService Bound."); - return mImsServiceController; - } - return null; - } - - /** - * @hide - */ - @VisibleForTesting - public SparseArray<ImsFeature> getFeatures(int slotId) { - return mFeaturesBySlot.get(slotId); - } - - private IImsMmTelFeature createMmTelFeatureInternal(int slotId, - IImsFeatureStatusCallback c) { - MmTelFeature f = createMmTelFeature(slotId); - if (f != null) { - setupFeature(f, slotId, ImsFeature.FEATURE_MMTEL, c); - return f.getBinder(); - } else { - Log.e(LOG_TAG, "createMmTelFeatureInternal: null feature returned."); - return null; - } - } - - private IImsRcsFeature createRcsFeatureInternal(int slotId, - IImsFeatureStatusCallback c) { - RcsFeature f = createRcsFeature(slotId); - if (f != null) { - setupFeature(f, slotId, ImsFeature.FEATURE_RCS, c); - return f.getBinder(); - } else { - Log.e(LOG_TAG, "createRcsFeatureInternal: null feature returned."); - return null; - } - } - - private void setupFeature(ImsFeature f, int slotId, int featureType, - IImsFeatureStatusCallback c) { - f.addImsFeatureStatusCallback(c); - f.initialize(this, slotId); - addImsFeature(slotId, featureType, f); - } - - private void addImsFeature(int slotId, int featureType, ImsFeature f) { - synchronized (mFeaturesBySlot) { - // Get SparseArray for Features, by querying slot Id - SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId); - if (features == null) { - // Populate new SparseArray of features if it doesn't exist for this slot yet. - features = new SparseArray<>(); - mFeaturesBySlot.put(slotId, features); - } - features.put(featureType, f); - } - } - - private void removeImsFeature(int slotId, int featureType, - IImsFeatureStatusCallback c) { - synchronized (mFeaturesBySlot) { - // get ImsFeature associated with the slot/feature - SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId); - if (features == null) { - Log.w(LOG_TAG, "Can not remove ImsFeature. No ImsFeatures exist on slot " - + slotId); - return; - } - ImsFeature f = features.get(featureType); - if (f == null) { - Log.w(LOG_TAG, "Can not remove ImsFeature. No feature with type " - + featureType + " exists on slot " + slotId); - return; - } - f.removeImsFeatureStatusCallback(c); - f.onFeatureRemoved(); - features.remove(featureType); - } - } - - private void notifyImsFeatureReady(int slotId, int featureType) { - synchronized (mFeaturesBySlot) { - // get ImsFeature associated with the slot/feature - SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId); - if (features == null) { - Log.w(LOG_TAG, "Can not notify ImsFeature ready. No ImsFeatures exist on " + - "slot " + slotId); - return; - } - ImsFeature f = features.get(featureType); - if (f == null) { - Log.w(LOG_TAG, "Can not notify ImsFeature ready. No feature with type " - + featureType + " exists on slot " + slotId); - return; - } - f.onFeatureReady(); - } - } - - /** - * When called, provide the {@link ImsFeatureConfiguration} that this ImsService currently - * supports. This will trigger the framework to set up the {@link ImsFeature}s that correspond - * to the {@link ImsFeature.FeatureType}s configured here. - * @return an {@link ImsFeatureConfiguration} containing Features this ImsService supports, - * defined in {@link ImsFeature.FeatureType}. - */ - public ImsFeatureConfiguration querySupportedImsFeatures() { - // Return empty for base implementation - return new ImsFeatureConfiguration(); - } - - /** - * Updates the framework with a new {@link ImsFeatureConfiguration} containing the updated - * features, defined in {@link ImsFeature.FeatureType} that this ImsService supports. This may - * trigger the framework to add/remove new ImsFeatures, depending on the configuration. - */ - public final void onUpdateSupportedImsFeatures(ImsFeatureConfiguration c) - throws RemoteException { - if (mListener == null) { - throw new IllegalStateException("Framework is not ready"); - } - mListener.onUpdateSupportedImsFeatures(c); - } - - /** - * The ImsService has been bound and is ready for ImsFeature creation based on the Features that - * the ImsService has registered for with the framework, either in the manifest or via - * The ImsService should use this signal instead of onCreate/onBind or similar to perform - * feature initialization because the framework may bind to this service multiple times to - * query the ImsService's {@link ImsFeatureConfiguration} via - * {@link #querySupportedImsFeatures()}before creating features. - */ - public void readyForFeatureCreation() { - } - - /** - * When called, the framework is requesting that a new MmTelFeature is created for the specified - * slot. - * - * @param slotId The slot ID that the MMTel Feature is being created for. - * @return The newly created MmTelFeature associated with the slot or null if the feature is not - * supported. - */ - public MmTelFeature createMmTelFeature(int slotId) { - return null; - } - - /** - * When called, the framework is requesting that a new RcsFeature is created for the specified - * slot - * - * @param slotId The slot ID that the RCS Feature is being created for. - * @return The newly created RcsFeature associated with the slot or null if the feature is not - * supported. - */ - public RcsFeature createRcsFeature(int slotId) { - return null; - } - - /** - * @param slotId The slot that the IMS configuration is associated with. - * @return ImsConfig implementation that is associated with the specified slot. - */ - public ImsConfigImplBase getConfig(int slotId) { - return new ImsConfigImplBase(); - } - - /** - * @param slotId The slot that is associated with the IMS Registration. - * @return the ImsRegistration implementation associated with the slot. - */ - public ImsRegistrationImplBase getRegistration(int slotId) { - return new ImsRegistrationImplBase(); - } -} diff --git a/telephony/java/android/telephony/ims/internal/feature/ImsFeature.java b/telephony/java/android/telephony/ims/internal/feature/ImsFeature.java deleted file mode 100644 index 9f82ad241eaf..000000000000 --- a/telephony/java/android/telephony/ims/internal/feature/ImsFeature.java +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package android.telephony.ims.internal.feature; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.content.Context; -import android.content.Intent; -import android.os.IInterface; -import android.os.RemoteCallbackList; -import android.os.RemoteException; -import android.telephony.SubscriptionManager; -import android.telephony.ims.internal.aidl.IImsCapabilityCallback; -import android.util.Log; - -import com.android.ims.internal.IImsFeatureStatusCallback; -import com.android.internal.annotations.VisibleForTesting; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Collections; -import java.util.Iterator; -import java.util.Set; -import java.util.WeakHashMap; - -/** - * Base class for all IMS features that are supported by the framework. - * - * @hide - */ -public abstract class ImsFeature { - - private static final String LOG_TAG = "ImsFeature"; - - /** - * Action to broadcast when ImsService is up. - * Internal use only. - * Only defined here separately for compatibility purposes with the old ImsService. - * - * @hide - */ - public static final String ACTION_IMS_SERVICE_UP = - "com.android.ims.IMS_SERVICE_UP"; - - /** - * Action to broadcast when ImsService is down. - * Internal use only. - * Only defined here separately for compatibility purposes with the old ImsService. - * - * @hide - */ - public static final String ACTION_IMS_SERVICE_DOWN = - "com.android.ims.IMS_SERVICE_DOWN"; - - /** - * Part of the ACTION_IMS_SERVICE_UP or _DOWN intents. - * A long value; the phone ID corresponding to the IMS service coming up or down. - * Only defined here separately for compatibility purposes with the old ImsService. - * - * @hide - */ - public static final String EXTRA_PHONE_ID = "android:phone_id"; - - // Invalid feature value - public static final int FEATURE_INVALID = -1; - // ImsFeatures that are defined in the Manifests. Ensure that these values match the previously - // defined values in ImsServiceClass for compatibility purposes. - public static final int FEATURE_EMERGENCY_MMTEL = 0; - public static final int FEATURE_MMTEL = 1; - public static final int FEATURE_RCS = 2; - // Total number of features defined - public static final int FEATURE_MAX = 3; - - // Integer values defining IMS features that are supported in ImsFeature. - @IntDef(flag = true, - value = { - FEATURE_EMERGENCY_MMTEL, - FEATURE_MMTEL, - FEATURE_RCS - }) - @Retention(RetentionPolicy.SOURCE) - public @interface FeatureType {} - - // Integer values defining the state of the ImsFeature at any time. - @IntDef(flag = true, - value = { - STATE_UNAVAILABLE, - STATE_INITIALIZING, - STATE_READY, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface ImsState {} - - public static final int STATE_UNAVAILABLE = 0; - public static final int STATE_INITIALIZING = 1; - public static final int STATE_READY = 2; - - // Integer values defining the result codes that should be returned from - // {@link changeEnabledCapabilities} when the framework tries to set a feature's capability. - @IntDef(flag = true, - value = { - CAPABILITY_ERROR_GENERIC, - CAPABILITY_SUCCESS - }) - @Retention(RetentionPolicy.SOURCE) - public @interface ImsCapabilityError {} - - public static final int CAPABILITY_ERROR_GENERIC = -1; - public static final int CAPABILITY_SUCCESS = 0; - - - /** - * The framework implements this callback in order to register for Feature Capability status - * updates, via {@link #onCapabilitiesStatusChanged(Capabilities)}, query Capability - * configurations, via {@link #onQueryCapabilityConfiguration}, as well as to receive error - * callbacks when the ImsService can not change the capability as requested, via - * {@link #onChangeCapabilityConfigurationError}. - */ - public static class CapabilityCallback extends IImsCapabilityCallback.Stub { - - @Override - public final void onCapabilitiesStatusChanged(int config) throws RemoteException { - onCapabilitiesStatusChanged(new Capabilities(config)); - } - - /** - * Returns the result of a query for the capability configuration of a requested capability. - * - * @param capability The capability that was requested. - * @param radioTech The IMS radio technology associated with the capability. - * @param isEnabled true if the capability is enabled, false otherwise. - */ - @Override - public void onQueryCapabilityConfiguration(int capability, int radioTech, - boolean isEnabled) { - - } - - /** - * Called when a change to the capability configuration has returned an error. - * - * @param capability The capability that was requested to be changed. - * @param radioTech The IMS radio technology associated with the capability. - * @param reason error associated with the failure to change configuration. - */ - @Override - public void onChangeCapabilityConfigurationError(int capability, int radioTech, - int reason) { - } - - /** - * The status of the feature's capabilities has changed to either available or unavailable. - * If unavailable, the feature is not able to support the unavailable capability at this - * time. - * - * @param config The new availability of the capabilities. - */ - public void onCapabilitiesStatusChanged(Capabilities config) { - } - } - - /** - * Used by the ImsFeature to call back to the CapabilityCallback that the framework has - * provided. - */ - protected static class CapabilityCallbackProxy { - private final IImsCapabilityCallback mCallback; - - public CapabilityCallbackProxy(IImsCapabilityCallback c) { - mCallback = c; - } - - /** - * This method notifies the provided framework callback that the request to change the - * indicated capability has failed and has not changed. - * - * @param capability The Capability that will be notified to the framework. - * @param radioTech The radio tech that this capability failed for. - * @param reason The reason this capability was unable to be changed. - */ - public void onChangeCapabilityConfigurationError(int capability, int radioTech, - @ImsCapabilityError int reason) { - try { - mCallback.onChangeCapabilityConfigurationError(capability, radioTech, reason); - } catch (RemoteException e) { - Log.e(LOG_TAG, "onChangeCapabilityConfigurationError called on dead binder."); - } - } - - public void onQueryCapabilityConfiguration(int capability, int radioTech, - boolean isEnabled) { - try { - mCallback.onQueryCapabilityConfiguration(capability, radioTech, isEnabled); - } catch (RemoteException e) { - Log.e(LOG_TAG, "onQueryCapabilityConfiguration called on dead binder."); - } - } - } - - /** - * Contains the capabilities defined and supported by an ImsFeature in the form of a bit mask. - */ - public static class Capabilities { - protected int mCapabilities = 0; - - public Capabilities() { - } - - protected Capabilities(int capabilities) { - mCapabilities = capabilities; - } - - /** - * @param capabilities Capabilities to be added to the configuration in the form of a - * bit mask. - */ - public void addCapabilities(int capabilities) { - mCapabilities |= capabilities; - } - - /** - * @param capabilities Capabilities to be removed to the configuration in the form of a - * bit mask. - */ - public void removeCapabilities(int capabilities) { - mCapabilities &= ~capabilities; - } - - /** - * @return true if all of the capabilities specified are capable. - */ - public boolean isCapable(int capabilities) { - return (mCapabilities & capabilities) == capabilities; - } - - public Capabilities copy() { - return new Capabilities(mCapabilities); - } - - /** - * @return a bitmask containing the capability flags directly. - */ - public int getMask() { - return mCapabilities; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Capabilities)) return false; - - Capabilities that = (Capabilities) o; - - return mCapabilities == that.mCapabilities; - } - - @Override - public int hashCode() { - return mCapabilities; - } - } - - private final Set<IImsFeatureStatusCallback> mStatusCallbacks = Collections.newSetFromMap( - new WeakHashMap<IImsFeatureStatusCallback, Boolean>()); - private @ImsState int mState = STATE_UNAVAILABLE; - private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX; - private Context mContext; - private final Object mLock = new Object(); - private final RemoteCallbackList<IImsCapabilityCallback> mCapabilityCallbacks - = new RemoteCallbackList<>(); - private Capabilities mCapabilityStatus = new Capabilities(); - - public final void initialize(Context context, int slotId) { - mContext = context; - mSlotId = slotId; - } - - public final int getFeatureState() { - synchronized (mLock) { - return mState; - } - } - - protected final void setFeatureState(@ImsState int state) { - synchronized (mLock) { - if (mState != state) { - mState = state; - notifyFeatureState(state); - } - } - } - - // Not final for testing, but shouldn't be extended! - @VisibleForTesting - public void addImsFeatureStatusCallback(@NonNull IImsFeatureStatusCallback c) { - try { - // If we have just connected, send queued status. - c.notifyImsFeatureStatus(getFeatureState()); - // Add the callback if the callback completes successfully without a RemoteException. - synchronized (mLock) { - mStatusCallbacks.add(c); - } - } catch (RemoteException e) { - Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage()); - } - } - - @VisibleForTesting - // Not final for testing, but should not be extended! - public void removeImsFeatureStatusCallback(@NonNull IImsFeatureStatusCallback c) { - synchronized (mLock) { - mStatusCallbacks.remove(c); - } - } - - /** - * Internal method called by ImsFeature when setFeatureState has changed. - */ - private void notifyFeatureState(@ImsState int state) { - synchronized (mLock) { - for (Iterator<IImsFeatureStatusCallback> iter = mStatusCallbacks.iterator(); - iter.hasNext(); ) { - IImsFeatureStatusCallback callback = iter.next(); - try { - Log.i(LOG_TAG, "notifying ImsFeatureState=" + state); - callback.notifyImsFeatureStatus(state); - } catch (RemoteException e) { - // remove if the callback is no longer alive. - iter.remove(); - Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage()); - } - } - } - sendImsServiceIntent(state); - } - - /** - * Provide backwards compatibility using deprecated service UP/DOWN intents. - */ - private void sendImsServiceIntent(@ImsState int state) { - if (mContext == null || mSlotId == SubscriptionManager.INVALID_SIM_SLOT_INDEX) { - return; - } - Intent intent; - switch (state) { - case ImsFeature.STATE_UNAVAILABLE: - case ImsFeature.STATE_INITIALIZING: - intent = new Intent(ACTION_IMS_SERVICE_DOWN); - break; - case ImsFeature.STATE_READY: - intent = new Intent(ACTION_IMS_SERVICE_UP); - break; - default: - intent = new Intent(ACTION_IMS_SERVICE_DOWN); - } - intent.putExtra(EXTRA_PHONE_ID, mSlotId); - mContext.sendBroadcast(intent); - } - - public final void addCapabilityCallback(IImsCapabilityCallback c) { - mCapabilityCallbacks.register(c); - } - - public final void removeCapabilityCallback(IImsCapabilityCallback c) { - mCapabilityCallbacks.unregister(c); - } - - /** - * @return the cached capabilities status for this feature. - */ - @VisibleForTesting - public Capabilities queryCapabilityStatus() { - synchronized (mLock) { - return mCapabilityStatus.copy(); - } - } - - // Called internally to request the change of enabled capabilities. - @VisibleForTesting - public final void requestChangeEnabledCapabilities(CapabilityChangeRequest request, - IImsCapabilityCallback c) throws RemoteException { - if (request == null) { - throw new IllegalArgumentException( - "ImsFeature#requestChangeEnabledCapabilities called with invalid params."); - } - changeEnabledCapabilities(request, new CapabilityCallbackProxy(c)); - } - - /** - * Called by the ImsFeature when the capabilities status has changed. - * - * @param c A {@link Capabilities} containing the new Capabilities status. - */ - protected final void notifyCapabilitiesStatusChanged(Capabilities c) { - synchronized (mLock) { - mCapabilityStatus = c.copy(); - } - int count = mCapabilityCallbacks.beginBroadcast(); - try { - for (int i = 0; i < count; i++) { - try { - mCapabilityCallbacks.getBroadcastItem(i).onCapabilitiesStatusChanged( - c.mCapabilities); - } catch (RemoteException e) { - Log.w(LOG_TAG, e + " " + "notifyCapabilitiesStatusChanged() - Skipping " + - "callback."); - } - } - } finally { - mCapabilityCallbacks.finishBroadcast(); - } - } - - /** - * Features should override this method to receive Capability preference change requests from - * the framework using the provided {@link CapabilityChangeRequest}. If any of the capabilities - * in the {@link CapabilityChangeRequest} are not able to be completed due to an error, - * {@link CapabilityCallbackProxy#onChangeCapabilityConfigurationError} should be called for - * each failed capability. - * - * @param request A {@link CapabilityChangeRequest} containing requested capabilities to - * enable/disable. - * @param c A {@link CapabilityCallbackProxy}, which will be used to call back to the framework - * setting a subset of these capabilities fail, using - * {@link CapabilityCallbackProxy#onChangeCapabilityConfigurationError}. - */ - public abstract void changeEnabledCapabilities(CapabilityChangeRequest request, - CapabilityCallbackProxy c); - - /** - * Called when the framework is removing this feature and it needs to be cleaned up. - */ - public abstract void onFeatureRemoved(); - - /** - * Called when the feature has been initialized and communication with the framework is set up. - * Any attempt by this feature to access the framework before this method is called will return - * with an {@link IllegalStateException}. - * The IMS provider should use this method to trigger registration for this feature on the IMS - * network, if needed. - */ - public abstract void onFeatureReady(); - - /** - * @return Binder instance that the framework will use to communicate with this feature. - */ - protected abstract IInterface getBinder(); -} diff --git a/telephony/java/android/telephony/ims/internal/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/internal/stub/ImsConfigImplBase.java deleted file mode 100644 index 33aec5dfb8af..000000000000 --- a/telephony/java/android/telephony/ims/internal/stub/ImsConfigImplBase.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package android.telephony.ims.internal.stub; - -import android.os.RemoteCallbackList; -import android.os.RemoteException; -import android.telephony.ims.internal.aidl.IImsConfig; -import android.telephony.ims.internal.aidl.IImsConfigCallback; - -import com.android.ims.ImsConfig; - -/** - * Controls the modification of IMS specific configurations. For more information on the supported - * IMS configuration constants, see {@link ImsConfig}. - * - * @hide - */ - -public class ImsConfigImplBase { - - //TODO: Implement the Binder logic to call base APIs. Need to finish other ImsService Config - // work first. - private final IImsConfig mBinder = new IImsConfig.Stub() { - - @Override - public void addImsConfigCallback(IImsConfigCallback c) throws RemoteException { - ImsConfigImplBase.this.addImsConfigCallback(c); - } - - @Override - public void removeImsConfigCallback(IImsConfigCallback c) throws RemoteException { - ImsConfigImplBase.this.removeImsConfigCallback(c); - } - - @Override - public int getConfigInt(int item) throws RemoteException { - return Integer.MIN_VALUE; - } - - @Override - public String getConfigString(int item) throws RemoteException { - return null; - } - - @Override - public int setConfigInt(int item, int value) throws RemoteException { - return Integer.MIN_VALUE; - } - - @Override - public int setConfigString(int item, String value) throws RemoteException { - return Integer.MIN_VALUE; - } - }; - - public class Callback extends IImsConfigCallback.Stub { - - @Override - public final void onIntConfigChanged(int item, int value) throws RemoteException { - onConfigChanged(item, value); - } - - @Override - public final void onStringConfigChanged(int item, String value) throws RemoteException { - onConfigChanged(item, value); - } - - /** - * Called when the IMS configuration has changed. - * @param item the IMS configuration key constant, as defined in ImsConfig. - * @param value the new integer value of the IMS configuration constant. - */ - public void onConfigChanged(int item, int value) { - // Base Implementation - } - - /** - * Called when the IMS configuration has changed. - * @param item the IMS configuration key constant, as defined in ImsConfig. - * @param value the new String value of the IMS configuration constant. - */ - public void onConfigChanged(int item, String value) { - // Base Implementation - } - } - - private final RemoteCallbackList<IImsConfigCallback> mCallbacks = new RemoteCallbackList<>(); - - /** - * Adds a {@link Callback} to the list of callbacks notified when a value in the configuration - * changes. - * @param c callback to add. - */ - private void addImsConfigCallback(IImsConfigCallback c) { - mCallbacks.register(c); - } - /** - * Removes a {@link Callback} to the list of callbacks notified when a value in the - * configuration changes. - * - * @param c callback to remove. - */ - private void removeImsConfigCallback(IImsConfigCallback c) { - mCallbacks.unregister(c); - } - - public final IImsConfig getBinder() { - return mBinder; - } - - /** - * Sets the value for IMS service/capabilities parameters by the operator device - * management entity. It sets the config item value in the provisioned storage - * from which the master value is derived. - * - * @param item as defined in com.android.ims.ImsConfig#ConfigConstants. - * @param value in Integer format. - * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants. - */ - public int setConfig(int item, int value) { - // Base Implementation - To be overridden. - return ImsConfig.OperationStatusConstants.FAILED; - } - - /** - * Sets the value for IMS service/capabilities parameters by the operator device - * management entity. It sets the config item value in the provisioned storage - * from which the master value is derived. - * - * @param item as defined in com.android.ims.ImsConfig#ConfigConstants. - * @param value in String format. - * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants. - */ - public int setConfig(int item, String value) { - return ImsConfig.OperationStatusConstants.FAILED; - } - - /** - * Gets the value for ims service/capabilities parameters from the provisioned - * value storage. - * - * @param item as defined in com.android.ims.ImsConfig#ConfigConstants. - * @return value in Integer format. - */ - public int getConfigInt(int item) { - return ImsConfig.OperationStatusConstants.FAILED; - } - - /** - * Gets the value for ims service/capabilities parameters from the provisioned - * value storage. - * - * @param item as defined in com.android.ims.ImsConfig#ConfigConstants. - * @return value in String format. - */ - public String getConfigString(int item) { - return null; - } -} diff --git a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java index 80b2f789e340..c6ca6fdb0fd8 100644 --- a/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsCallSessionImplBase.java @@ -16,131 +16,347 @@ package android.telephony.ims.stub; +import android.annotation.SystemApi; import android.os.Message; import android.os.RemoteException; +import android.telephony.ims.ImsCallSessionListener; +import android.telephony.ims.aidl.IImsCallSessionListener; -import com.android.ims.ImsCallProfile; -import com.android.ims.ImsStreamMediaProfile; -import com.android.ims.internal.ImsCallSession; +import android.telephony.ims.ImsCallProfile; +import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.ImsStreamMediaProfile; +import android.telephony.ims.ImsCallSession; import com.android.ims.internal.IImsCallSession; -import com.android.ims.internal.IImsCallSessionListener; import com.android.ims.internal.IImsVideoCallProvider; +import android.telephony.ims.ImsVideoCallProvider; + +import dalvik.system.CloseGuard; /** - * Base implementation of IImsCallSession, which implements stub versions of the methods in the - * IImsCallSession AIDL. Override the methods that your implementation of ImsCallSession supports. + * Base implementation of IImsCallSession, which implements stub versions of the methods available. * - * DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you - * will break other implementations of ImsCallSession maintained by other ImsServices. + * Override the methods that your implementation of ImsCallSession supports. * * @hide */ - -public class ImsCallSessionImplBase extends IImsCallSession.Stub { +@SystemApi +// DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you +// will break other implementations of ImsCallSession maintained by other ImsServices. +public class ImsCallSessionImplBase implements AutoCloseable { + /** + * Notify USSD Mode. + */ + public static final int USSD_MODE_NOTIFY = 0; + /** + * Request USSD Mode + */ + public static final int USSD_MODE_REQUEST = 1; /** - * Closes the object. This object is not usable after being closed. + * Defines IMS call session state. */ - @Override - public void close() throws RemoteException { + public static class State { + public static final int IDLE = 0; + public static final int INITIATED = 1; + public static final int NEGOTIATING = 2; + public static final int ESTABLISHING = 3; + public static final int ESTABLISHED = 4; + + public static final int RENEGOTIATING = 5; + public static final int REESTABLISHING = 6; + + public static final int TERMINATING = 7; + public static final int TERMINATED = 8; + + public static final int INVALID = (-1); + + /** + * Converts the state to string. + */ + public static String toString(int state) { + switch (state) { + case IDLE: + return "IDLE"; + case INITIATED: + return "INITIATED"; + case NEGOTIATING: + return "NEGOTIATING"; + case ESTABLISHING: + return "ESTABLISHING"; + case ESTABLISHED: + return "ESTABLISHED"; + case RENEGOTIATING: + return "RENEGOTIATING"; + case REESTABLISHING: + return "REESTABLISHING"; + case TERMINATING: + return "TERMINATING"; + case TERMINATED: + return "TERMINATED"; + default: + return "UNKNOWN"; + } + } + + /** + * @hide + */ + private State() { + } + } + + // Non-final for injection by tests + private IImsCallSession mServiceImpl = new IImsCallSession.Stub() { + @Override + public void close() { + ImsCallSessionImplBase.this.close(); + } + + @Override + public String getCallId() { + return ImsCallSessionImplBase.this.getCallId(); + } + + @Override + public ImsCallProfile getCallProfile() { + return ImsCallSessionImplBase.this.getCallProfile(); + } + + @Override + public ImsCallProfile getLocalCallProfile() { + return ImsCallSessionImplBase.this.getLocalCallProfile(); + } + + @Override + public ImsCallProfile getRemoteCallProfile() { + return ImsCallSessionImplBase.this.getRemoteCallProfile(); + } + + @Override + public String getProperty(String name) { + return ImsCallSessionImplBase.this.getProperty(name); + } + + @Override + public int getState() { + return ImsCallSessionImplBase.this.getState(); + } + + @Override + public boolean isInCall() { + return ImsCallSessionImplBase.this.isInCall(); + } + + @Override + public void setListener(IImsCallSessionListener listener) { + ImsCallSessionImplBase.this.setListener(new ImsCallSessionListener(listener)); + } + + @Override + public void setMute(boolean muted) { + ImsCallSessionImplBase.this.setMute(muted); + } + + @Override + public void start(String callee, ImsCallProfile profile) { + ImsCallSessionImplBase.this.start(callee, profile); + } + + @Override + public void startConference(String[] participants, ImsCallProfile profile) throws + RemoteException { + ImsCallSessionImplBase.this.startConference(participants, profile); + } + + @Override + public void accept(int callType, ImsStreamMediaProfile profile) { + ImsCallSessionImplBase.this.accept(callType, profile); + } + + @Override + public void reject(int reason) { + ImsCallSessionImplBase.this.reject(reason); + } + + @Override + public void terminate(int reason) { + ImsCallSessionImplBase.this.terminate(reason); + } + + @Override + public void hold(ImsStreamMediaProfile profile) { + ImsCallSessionImplBase.this.hold(profile); + } + + @Override + public void resume(ImsStreamMediaProfile profile) { + ImsCallSessionImplBase.this.resume(profile); + } + + @Override + public void merge() { + ImsCallSessionImplBase.this.merge(); + } + + @Override + public void update(int callType, ImsStreamMediaProfile profile) { + ImsCallSessionImplBase.this.update(callType, profile); + } + + @Override + public void extendToConference(String[] participants) { + ImsCallSessionImplBase.this.extendToConference(participants); + } + + @Override + public void inviteParticipants(String[] participants) { + ImsCallSessionImplBase.this.inviteParticipants(participants); + } + + @Override + public void removeParticipants(String[] participants) { + ImsCallSessionImplBase.this.removeParticipants(participants); + } + + @Override + public void sendDtmf(char c, Message result) { + ImsCallSessionImplBase.this.sendDtmf(c, result); + } + + @Override + public void startDtmf(char c) { + ImsCallSessionImplBase.this.startDtmf(c); + } + + @Override + public void stopDtmf() { + ImsCallSessionImplBase.this.stopDtmf(); + } + + @Override + public void sendUssd(String ussdMessage) { + ImsCallSessionImplBase.this.sendUssd(ussdMessage); + } + + @Override + public IImsVideoCallProvider getVideoCallProvider() { + return ImsCallSessionImplBase.this.getVideoCallProvider(); + } + + @Override + public boolean isMultiparty() { + return ImsCallSessionImplBase.this.isMultiparty(); + } + + @Override + public void sendRttModifyRequest(ImsCallProfile toProfile) { + ImsCallSessionImplBase.this.sendRttModifyRequest(toProfile); + } + + @Override + public void sendRttModifyResponse(boolean status) { + ImsCallSessionImplBase.this.sendRttModifyResponse(status); + } + + @Override + public void sendRttMessage(String rttMessage) { + ImsCallSessionImplBase.this.sendRttMessage(rttMessage); + } + }; + /** + * @hide + */ + public final void setListener(IImsCallSessionListener listener) throws RemoteException { + setListener(new ImsCallSessionListener(listener)); } /** - * Gets the call ID of the session. + * Sets the listener to listen to the session events. An {@link ImsCallSession} + * can only hold one listener at a time. Subsequent calls to this method + * override the previous listener. * - * @return the call ID + * @param listener {@link ImsCallSessionListener} used to notify the framework of updates + * to the ImsCallSession */ - @Override - public String getCallId() throws RemoteException { - return null; + public void setListener(ImsCallSessionListener listener) { } /** - * Gets the call profile that this session is associated with - * - * @return the {@link ImsCallProfile} that this session is associated with + * Closes the object. This {@link ImsCallSessionImplBase} is not usable after being closed. */ @Override - public ImsCallProfile getCallProfile() throws RemoteException { + public void close() { + + } + + /** + * @return A String containing the unique call ID of this {@link ImsCallSessionImplBase}. + */ + public String getCallId() { return null; } /** - * Gets the local call profile that this session is associated with - * - * @return the local {@link ImsCallProfile} that this session is associated with + * @return The {@link ImsCallProfile} that this {@link ImsCallSessionImplBase} is associated + * with. */ - @Override - public ImsCallProfile getLocalCallProfile() throws RemoteException { + public ImsCallProfile getCallProfile() { return null; } /** - * Gets the remote call profile that this session is associated with - * - * @return the remote {@link ImsCallProfile} that this session is associated with + * @return The local {@link ImsCallProfile} that this {@link ImsCallSessionImplBase} is + * associated with. */ - @Override - public ImsCallProfile getRemoteCallProfile() throws RemoteException { + public ImsCallProfile getLocalCallProfile() { return null; } /** - * Gets the value associated with the specified property of this session. - * - * @return the string value associated with the specified property + * @return The remote {@link ImsCallProfile} that this {@link ImsCallSessionImplBase} is + * associated with. */ - @Override - public String getProperty(String name) throws RemoteException { + public ImsCallProfile getRemoteCallProfile() { return null; } /** - * Gets the session state. - * The value returned must be one of the states in {@link ImsCallSession.State}. - * - * @return the session state + * @param name The String extra key. + * @return The string extra value associated with the specified property. */ - @Override - public int getState() throws RemoteException { - return ImsCallSession.State.INVALID; + public String getProperty(String name) { + return null; } /** - * Checks if the session is in call. - * - * @return true if the session is in call, false otherwise + * @return The {@link ImsCallSessionImplBase} state, defined in + * {@link ImsCallSessionImplBase.State}. */ - @Override - public boolean isInCall() throws RemoteException { - return false; + public int getState() { + return ImsCallSessionImplBase.State.INVALID; } /** - * Sets the listener to listen to the session events. An {@link ImsCallSession} - * can only hold one listener at a time. Subsequent calls to this method - * override the previous listener. - * - * @param listener to listen to the session events of this object + * @return true if the {@link ImsCallSessionImplBase} is in a call, false otherwise. */ - @Override - public void setListener(IImsCallSessionListener listener) throws RemoteException { + public boolean isInCall() { + return false; } /** * Mutes or unmutes the mic for the active call. * - * @param muted true if the call is muted, false otherwise + * @param muted true if the call should be muted, false otherwise. */ - @Override - public void setMute(boolean muted) throws RemoteException { + public void setMute(boolean muted) { } /** - * Initiates an IMS call with the specified target and call profile. - * The session listener set in {@link #setListener} is called back upon defined session events. - * The method is only valid to call when the session state is in + * Initiates an IMS call with the specified number and call profile. + * The session listener set in {@link #setListener(ImsCallSessionListener)} is called back upon + * defined session events. + * Only valid to call when the session state is in * {@link ImsCallSession.State#IDLE}. * * @param callee dialed string to make the call to @@ -149,13 +365,13 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionStarted}, * {@link ImsCallSession.Listener#callSessionStartFailed} */ - @Override - public void start(String callee, ImsCallProfile profile) throws RemoteException { + public void start(String callee, ImsCallProfile profile) { } /** * Initiates an IMS call with the specified participants and call profile. - * The session listener set in {@link #setListener} is called back upon defined session events. + * The session listener set in {@link #setListener(ImsCallSessionListener)} is called back upon + * defined session events. * The method is only valid to call when the session state is in * {@link ImsCallSession.State#IDLE}. * @@ -165,9 +381,7 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionStarted}, * {@link ImsCallSession.Listener#callSessionStartFailed} */ - @Override - public void startConference(String[] participants, ImsCallProfile profile) - throws RemoteException { + public void startConference(String[] participants, ImsCallProfile profile) { } /** @@ -177,31 +391,26 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @param profile stream media profile {@link ImsStreamMediaProfile} to be answered * @see {@link ImsCallSession.Listener#callSessionStarted} */ - @Override - public void accept(int callType, ImsStreamMediaProfile profile) throws RemoteException { + public void accept(int callType, ImsStreamMediaProfile profile) { } /** * Rejects an incoming call or session update. * - * @param reason reason code to reject an incoming call, defined in - * com.android.ims.ImsReasonInfo + * @param reason reason code to reject an incoming call, defined in {@link ImsReasonInfo}. * {@link ImsCallSession.Listener#callSessionStartFailed} */ - @Override - public void reject(int reason) throws RemoteException { + public void reject(int reason) { } /** * Terminates a call. * - * @param reason reason code to terminate a call, defined in - * com.android.ims.ImsReasonInfo + * @param reason reason code to terminate a call, defined in {@link ImsReasonInfo}. * * @see {@link ImsCallSession.Listener#callSessionTerminated} */ - @Override - public void terminate(int reason) throws RemoteException { + public void terminate(int reason) { } /** @@ -212,8 +421,7 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionHeld}, * {@link ImsCallSession.Listener#callSessionHoldFailed} */ - @Override - public void hold(ImsStreamMediaProfile profile) throws RemoteException { + public void hold(ImsStreamMediaProfile profile) { } /** @@ -224,12 +432,11 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionResumed}, * {@link ImsCallSession.Listener#callSessionResumeFailed} */ - @Override - public void resume(ImsStreamMediaProfile profile) throws RemoteException { + public void resume(ImsStreamMediaProfile profile) { } /** - * Merges the active & hold call. When the merge starts, + * Merges the active and held call. When the merge starts, * {@link ImsCallSession.Listener#callSessionMergeStarted} is called. * {@link ImsCallSession.Listener#callSessionMergeComplete} is called if the merge is * successful, and {@link ImsCallSession.Listener#callSessionMergeFailed} is called if the merge @@ -239,8 +446,7 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * {@link ImsCallSession.Listener#callSessionMergeComplete}, * {@link ImsCallSession.Listener#callSessionMergeFailed} */ - @Override - public void merge() throws RemoteException { + public void merge() { } /** @@ -251,8 +457,7 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionUpdated}, * {@link ImsCallSession.Listener#callSessionUpdateFailed} */ - @Override - public void update(int callType, ImsStreamMediaProfile profile) throws RemoteException { + public void update(int callType, ImsStreamMediaProfile profile) { } /** @@ -263,8 +468,7 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionConferenceExtended}, * {@link ImsCallSession.Listener#callSessionConferenceExtendFailed} */ - @Override - public void extendToConference(String[] participants) throws RemoteException { + public void extendToConference(String[] participants) { } /** @@ -274,8 +478,7 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionInviteParticipantsRequestDelivered}, * {@link ImsCallSession.Listener#callSessionInviteParticipantsRequestFailed} */ - @Override - public void inviteParticipants(String[] participants) throws RemoteException { + public void inviteParticipants(String[] participants) { } /** @@ -285,8 +488,7 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * @see {@link ImsCallSession.Listener#callSessionRemoveParticipantsRequestDelivered}, * {@link ImsCallSession.Listener#callSessionRemoveParticipantsRequestFailed} */ - @Override - public void removeParticipants(String[] participants) throws RemoteException { + public void removeParticipants(String[] participants) { } /** @@ -296,8 +498,7 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs. */ - @Override - public void sendDtmf(char c, Message result) throws RemoteException { + public void sendDtmf(char c, Message result) { } /** @@ -307,15 +508,13 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs. */ - @Override - public void startDtmf(char c) throws RemoteException { + public void startDtmf(char c) { } /** * Stop a DTMF code. */ - @Override - public void stopDtmf() throws RemoteException { + public void stopDtmf() { } /** @@ -323,17 +522,23 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * * @param ussdMessage USSD message to send */ - @Override - public void sendUssd(String ussdMessage) throws RemoteException { + public void sendUssd(String ussdMessage) { } /** - * Returns a binder for the video call provider implementation contained within the IMS service - * process. This binder is used by the VideoCallProvider subclass in Telephony which - * intermediates between the propriety implementation and Telecomm/InCall. + * See {@link #getImsVideoCallProvider()}, used directly in older ImsService implementations. + * @hide */ - @Override - public IImsVideoCallProvider getVideoCallProvider() throws RemoteException { + public IImsVideoCallProvider getVideoCallProvider() { + ImsVideoCallProvider provider = getImsVideoCallProvider(); + return provider != null ? provider.getInterface() : null; + } + + /** + * @return The {@link ImsVideoCallProvider} implementation contained within the IMS service + * process. + */ + public ImsVideoCallProvider getImsVideoCallProvider() { return null; } @@ -341,8 +546,7 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * Determines if the current session is multiparty. * @return {@code True} if the session is multiparty. */ - @Override - public boolean isMultiparty() throws RemoteException { + public boolean isMultiparty() { return false; } @@ -350,16 +554,13 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * Device issues RTT modify request * @param toProfile The profile with requested changes made */ - @Override public void sendRttModifyRequest(ImsCallProfile toProfile) { } /** * Device responds to Remote RTT modify request - * @param status true Accepted the request - * false Declined the request + * @param status true if the the request was accepted or false of the request is defined. */ - @Override public void sendRttModifyResponse(boolean status) { } @@ -367,7 +568,16 @@ public class ImsCallSessionImplBase extends IImsCallSession.Stub { * Device sends RTT message * @param rttMessage RTT message to be sent */ - @Override public void sendRttMessage(String rttMessage) { } + + /** @hide */ + public IImsCallSession getServiceImpl() { + return mServiceImpl; + } + + /** @hide */ + public void setServiceImpl(IImsCallSession serviceImpl) { + mServiceImpl = serviceImpl; + } } diff --git a/telephony/java/android/telephony/ims/stub/ImsCallSessionListenerImplBase.java b/telephony/java/android/telephony/ims/stub/ImsCallSessionListenerImplBase.java deleted file mode 100644 index 6c18935d16ef..000000000000 --- a/telephony/java/android/telephony/ims/stub/ImsCallSessionListenerImplBase.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package android.telephony.ims.stub; - -import com.android.ims.ImsCallProfile; -import com.android.ims.ImsConferenceState; -import com.android.ims.ImsReasonInfo; -import com.android.ims.ImsStreamMediaProfile; -import com.android.ims.ImsSuppServiceNotification; -import com.android.ims.internal.IImsCallSession; -import com.android.ims.internal.IImsCallSessionListener; - -/** - * Base implementation of ImsCallSessionListenerBase, which implements stub versions of the methods - * in the IImsCallSessionListener AIDL. Override the methods that your implementation of - * ImsCallSessionListener supports. - * - * DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you - * will break other implementations of ImsCallSessionListener maintained by other ImsServices. - * - * @hide - */ -public class ImsCallSessionListenerImplBase extends IImsCallSessionListener.Stub { - /** - * Notifies the result of the basic session operation (setup / terminate). - */ - @Override - public void callSessionProgressing(IImsCallSession session, ImsStreamMediaProfile profile) { - // no-op - } - - @Override - public void callSessionStarted(IImsCallSession session, ImsCallProfile profile) { - // no-op - } - - @Override - public void callSessionStartFailed(IImsCallSession session, ImsReasonInfo reasonInfo) { - // no-op - } - - @Override - public void callSessionTerminated(IImsCallSession session, ImsReasonInfo reasonInfo) { - // no-op - } - - /** - * Notifies the result of the call hold/resume operation. - */ - @Override - public void callSessionHeld(IImsCallSession session, ImsCallProfile profile) { - // no-op - } - - @Override - public void callSessionHoldFailed(IImsCallSession session, ImsReasonInfo reasonInfo) { - // no-op - } - - @Override - public void callSessionHoldReceived(IImsCallSession session, ImsCallProfile profile) { - // no-op - } - - @Override - public void callSessionResumed(IImsCallSession session, ImsCallProfile profile) { - // no-op - } - - @Override - public void callSessionResumeFailed(IImsCallSession session, ImsReasonInfo reasonInfo) { - // no-op - } - - @Override - public void callSessionResumeReceived(IImsCallSession session, ImsCallProfile profile) { - // no-op - } - - /** - * Notifies the result of call merge operation. - */ - @Override - public void callSessionMergeStarted(IImsCallSession session, IImsCallSession newSession, - ImsCallProfile profile) { - // no-op - } - - @Override - public void callSessionMergeComplete(IImsCallSession session) { - // no-op - } - - @Override - public void callSessionMergeFailed(IImsCallSession session, ImsReasonInfo reasonInfo) { - // no-op - } - - /** - * Notifies the result of call upgrade / downgrade or any other call - * updates. - */ - @Override - public void callSessionUpdated(IImsCallSession session, ImsCallProfile profile) { - // no-op - } - - @Override - public void callSessionUpdateFailed(IImsCallSession session, ImsReasonInfo reasonInfo) { - // no-op - } - - @Override - public void callSessionUpdateReceived(IImsCallSession session, ImsCallProfile profile) { - // no-op - } - - /** - * Notifies the result of conference extension. - */ - @Override - public void callSessionConferenceExtended(IImsCallSession session, IImsCallSession newSession, - ImsCallProfile profile) { - // no-op - } - - @Override - public void callSessionConferenceExtendFailed(IImsCallSession session, - ImsReasonInfo reasonInfo) { - // no-op - } - - @Override - public void callSessionConferenceExtendReceived(IImsCallSession session, - IImsCallSession newSession, - ImsCallProfile profile) { - // no-op - } - - /** - * Notifies the result of the participant invitation / removal to/from the - * conference session. - */ - @Override - public void callSessionInviteParticipantsRequestDelivered(IImsCallSession session) { - // no-op - } - - @Override - public void callSessionInviteParticipantsRequestFailed(IImsCallSession session, - ImsReasonInfo reasonInfo) { - // no-op - } - - @Override - public void callSessionRemoveParticipantsRequestDelivered(IImsCallSession session) { - // no-op - } - - @Override - public void callSessionRemoveParticipantsRequestFailed(IImsCallSession session, - ImsReasonInfo reasonInfo) { - // no-op - } - - /** - * Notifies the changes of the conference info. the conference session. - */ - @Override - public void callSessionConferenceStateUpdated(IImsCallSession session, - ImsConferenceState state) { - // no-op - } - - /** - * Notifies the incoming USSD message. - */ - @Override - public void callSessionUssdMessageReceived(IImsCallSession session, int mode, - String ussdMessage) { - // no-op - } - - /** - * Notifies of a case where a {@link com.android.ims.internal.ImsCallSession} may potentially - * handover from one radio technology to another. - * @param session - * @param srcAccessTech The source radio access technology; one of the access technology - * constants defined in {@link android.telephony.ServiceState}. For - * example {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}. - * @param targetAccessTech The target radio access technology; one of the access technology - * constants defined in {@link android.telephony.ServiceState}. For - * example {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE}. - */ - @Override - public void callSessionMayHandover(IImsCallSession session, int srcAccessTech, - int targetAccessTech) { - // no-op - } - - /** - * Notifies of handover information for this call - */ - @Override - public void callSessionHandover(IImsCallSession session, int srcAccessTech, - int targetAccessTech, - ImsReasonInfo reasonInfo) { - // no-op - } - - @Override - public void callSessionHandoverFailed(IImsCallSession session, int srcAccessTech, - int targetAccessTech, - ImsReasonInfo reasonInfo) { - // no-op - } - - /** - * Notifies the TTY mode change by remote party. - * - * @param mode one of the following: - - * {@link com.android.internal.telephony.Phone#TTY_MODE_OFF} - - * {@link com.android.internal.telephony.Phone#TTY_MODE_FULL} - - * {@link com.android.internal.telephony.Phone#TTY_MODE_HCO} - - * {@link com.android.internal.telephony.Phone#TTY_MODE_VCO} - */ - @Override - public void callSessionTtyModeReceived(IImsCallSession session, int mode) { - // no-op - } - - /** - * Notifies of a change to the multiparty state for this - * {@code ImsCallSession}. - * - * @param session The call session. - * @param isMultiParty {@code true} if the session became multiparty, - * {@code false} otherwise. - */ - @Override - public void callSessionMultipartyStateChanged(IImsCallSession session, boolean isMultiParty) { - // no-op - } - - /** - * Notifies the supplementary service information for the current session. - */ - @Override - public void callSessionSuppServiceReceived(IImsCallSession session, - ImsSuppServiceNotification suppSrvNotification) { - // no-op - } - - /** - * Received RTT modify request from Remote Party - * @param session The call session. - * @param callProfile ImsCallProfile with updated attribute - */ - @Override - public void callSessionRttModifyRequestReceived(IImsCallSession session, - ImsCallProfile callProfile) { - // no-op - } - - /** - * Received response for RTT modify request - * @param status true : Accepted the request - * false : Declined the request - */ - @Override - public void callSessionRttModifyResponseReceived(int status) { - // no -op - } - - /** - * Device received RTT message from Remote UE - * @param rttMessage RTT message received - */ - @Override - public void callSessionRttMessageReceived(String rttMessage) { - // no-op - } -} - diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java index 5a4db99ee0d0..c6e5ddb52489 100644 --- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * 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. @@ -16,135 +16,400 @@ package android.telephony.ims.stub; +import android.annotation.SystemApi; +import android.content.Context; +import android.os.RemoteCallbackList; import android.os.RemoteException; +import android.telephony.ims.aidl.IImsConfig; +import android.telephony.ims.aidl.IImsConfigCallback; +import android.util.Log; import com.android.ims.ImsConfig; -import com.android.ims.ImsConfigListener; -import com.android.ims.internal.IImsConfig; +import com.android.internal.annotations.VisibleForTesting; + +import java.lang.ref.WeakReference; +import java.util.HashMap; /** - * Base implementation of ImsConfig, which implements stub versions of the methods - * in the IImsConfig AIDL. Override the methods that your implementation of ImsConfig supports. - * - * DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you - * will break other implementations of ImsConfig maintained by other ImsServices. - * - * Provides APIs to get/set the IMS service feature/capability/parameters. - * The config items include: - * 1) Items provisioned by the operator. - * 2) Items configured by user. Mainly service feature class. + * Controls the modification of IMS specific configurations. For more information on the supported + * IMS configuration constants, see {@link ImsConfig}. * + * The inner class {@link ImsConfigStub} implements methods of IImsConfig AIDL interface. + * The IImsConfig AIDL interface is called by ImsConfig, which may exist in many other processes. + * ImsConfigImpl access to the configuration parameters may be arbitrarily slow, especially in + * during initialization, or times when a lot of configuration parameters are being set/get + * (such as during boot up or SIM card change). By providing a cache in ImsConfigStub, we can speed + * up access to these configuration parameters, so a query to the ImsConfigImpl does not have to be + * performed every time. * @hide */ +@SystemApi +public class ImsConfigImplBase { -public class ImsConfigImplBase extends IImsConfig.Stub { + private static final String TAG = "ImsConfigImplBase"; /** - * Gets the value for ims service/capabilities parameters from the provisioned - * value storage. Synchronous blocking call. + * Implements the IImsConfig AIDL interface, which is called by potentially many processes + * in order to get/set configuration parameters. + * + * It holds an object of ImsConfigImplBase class which is usually extended by ImsConfigImpl + * with actual implementations from vendors. This class caches provisioned values from + * ImsConfigImpl layer because queries through ImsConfigImpl can be slow. When query goes in, + * it first checks cache layer. If missed, it will call the vendor implementation of + * ImsConfigImplBase API. + * and cache the return value if the set succeeds. * - * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. - * @return value in Integer format. + * Provides APIs to get/set the IMS service feature/capability/parameters. + * The config items include: + * 1) Items provisioned by the operator. + * 2) Items configured by user. Mainly service feature class. + * + * @hide */ - @Override - public int getProvisionedValue(int item) throws RemoteException { - return -1; + @VisibleForTesting + static public class ImsConfigStub extends IImsConfig.Stub { + WeakReference<ImsConfigImplBase> mImsConfigImplBaseWeakReference; + private HashMap<Integer, Integer> mProvisionedIntValue = new HashMap<>(); + private HashMap<Integer, String> mProvisionedStringValue = new HashMap<>(); + + @VisibleForTesting + public ImsConfigStub(ImsConfigImplBase imsConfigImplBase) { + mImsConfigImplBaseWeakReference = + new WeakReference<ImsConfigImplBase>(imsConfigImplBase); + } + + @Override + public void addImsConfigCallback(IImsConfigCallback c) throws RemoteException { + getImsConfigImpl().addImsConfigCallback(c); + } + + @Override + public void removeImsConfigCallback(IImsConfigCallback c) throws RemoteException { + getImsConfigImpl().removeImsConfigCallback(c); + } + + /** + * Gets the value for ims service/capabilities parameters. It first checks its local cache, + * if missed, it will call ImsConfigImplBase.getConfigInt. + * Synchronous blocking call. + * + * @param item integer key + * @return value in Integer format or {@link #CONFIG_RESULT_UNKNOWN} if + * unavailable. + */ + @Override + public synchronized int getConfigInt(int item) throws RemoteException { + if (mProvisionedIntValue.containsKey(item)) { + return mProvisionedIntValue.get(item); + } else { + int retVal = getImsConfigImpl().getConfigInt(item); + if (retVal != ImsConfig.OperationStatusConstants.UNKNOWN) { + updateCachedValue(item, retVal, false); + } + return retVal; + } + } + + /** + * Gets the value for ims service/capabilities parameters. It first checks its local cache, + * if missed, it will call #ImsConfigImplBase.getConfigString. + * Synchronous blocking call. + * + * @param item integer key + * @return value in String format. + */ + @Override + public synchronized String getConfigString(int item) throws RemoteException { + if (mProvisionedIntValue.containsKey(item)) { + return mProvisionedStringValue.get(item); + } else { + String retVal = getImsConfigImpl().getConfigString(item); + if (retVal != null) { + updateCachedValue(item, retVal, false); + } + return retVal; + } + } + + /** + * Sets the value for IMS service/capabilities parameters by the operator device + * management entity. It sets the config item value in the provisioned storage + * from which the master value is derived, and write it into local cache. + * Synchronous blocking call. + * + * @param item integer key + * @param value in Integer format. + * @return the result of setting the configuration value, defined as either + * {@link #CONFIG_RESULT_FAILED} or {@link #CONFIG_RESULT_SUCCESS}. + */ + @Override + public synchronized int setConfigInt(int item, int value) throws RemoteException { + mProvisionedIntValue.remove(item); + int retVal = getImsConfigImpl().setConfig(item, value); + if (retVal == ImsConfig.OperationStatusConstants.SUCCESS) { + updateCachedValue(item, value, true); + } else { + Log.d(TAG, "Set provision value of " + item + + " to " + value + " failed with error code " + retVal); + } + + return retVal; + } + + /** + * Sets the value for IMS service/capabilities parameters by the operator device + * management entity. It sets the config item value in the provisioned storage + * from which the master value is derived, and write it into local cache. + * Synchronous blocking call. + * + * @param item as defined in com.android.ims.ImsConfig#ConfigConstants. + * @param value in String format. + * @return the result of setting the configuration value, defined as either + * {@link #CONFIG_RESULT_FAILED} or {@link #CONFIG_RESULT_SUCCESS}. + */ + @Override + public synchronized int setConfigString(int item, String value) + throws RemoteException { + mProvisionedStringValue.remove(item); + int retVal = getImsConfigImpl().setConfig(item, value); + if (retVal == ImsConfig.OperationStatusConstants.SUCCESS) { + updateCachedValue(item, value, true); + } + + return retVal; + } + + private ImsConfigImplBase getImsConfigImpl() throws RemoteException { + ImsConfigImplBase ref = mImsConfigImplBaseWeakReference.get(); + if (ref == null) { + throw new RemoteException("Fail to get ImsConfigImpl"); + } else { + return ref; + } + } + + private void notifyImsConfigChanged(int item, int value) throws RemoteException { + getImsConfigImpl().notifyConfigChanged(item, value); + } + + private void notifyImsConfigChanged(int item, String value) throws RemoteException { + getImsConfigImpl().notifyConfigChanged(item, value); + } + + protected synchronized void updateCachedValue(int item, int value, boolean notifyChange) + throws RemoteException { + mProvisionedIntValue.put(item, value); + if (notifyChange) { + notifyImsConfigChanged(item, value); + } + } + + protected synchronized void updateCachedValue(int item, String value, + boolean notifyChange) throws RemoteException { + mProvisionedStringValue.put(item, value); + if (notifyChange) { + notifyImsConfigChanged(item, value); + } + } } /** - * Gets the value for ims service/capabilities parameters from the provisioned - * value storage. Synchronous blocking call. - * - * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. - * @return value in String format. + * Callback that the framework uses for receiving Configuration change updates. + * {@hide} */ - @Override - public String getProvisionedStringValue(int item) throws RemoteException { - return null; + public static class Callback extends IImsConfigCallback.Stub { + + @Override + public final void onIntConfigChanged(int item, int value) throws RemoteException { + onConfigChanged(item, value); + } + + @Override + public final void onStringConfigChanged(int item, String value) throws RemoteException { + onConfigChanged(item, value); + } + + /** + * Called when the IMS configuration has changed. + * @param item the IMS configuration key constant, as defined in ImsConfig. + * @param value the new integer value of the IMS configuration constant. + */ + public void onConfigChanged(int item, int value) { + // Base Implementation + } + + /** + * Called when the IMS configuration has changed. + * @param item the IMS configuration key constant, as defined in ImsConfig. + * @param value the new String value of the IMS configuration constant. + */ + public void onConfigChanged(int item, String value) { + // Base Implementation + } + } + + /** + * The configuration requested resulted in an unknown result. This may happen if the + * IMS configurations are unavailable. + */ + public static final int CONFIG_RESULT_UNKNOWN = -1; + /** + * Setting the configuration value completed. + */ + public static final int CONFIG_RESULT_SUCCESS = 0; + /** + * Setting the configuration value failed. + */ + public static final int CONFIG_RESULT_FAILED = 1; + + private final RemoteCallbackList<IImsConfigCallback> mCallbacks = new RemoteCallbackList<>(); + ImsConfigStub mImsConfigStub; + + /** + * Used for compatibility between older versions of the ImsService. + * @hide + */ + public ImsConfigImplBase(Context context) { + mImsConfigStub = new ImsConfigStub(this); + } + + public ImsConfigImplBase() { + mImsConfigStub = new ImsConfigStub(this); } /** - * Sets the value for IMS service/capabilities parameters by the operator device - * management entity. It sets the config item value in the provisioned storage - * from which the master value is derived. Synchronous blocking call. + * Adds a {@link Callback} to the list of callbacks notified when a value in the configuration + * changes. + * @param c callback to add. + */ + private void addImsConfigCallback(IImsConfigCallback c) { + mCallbacks.register(c); + } + /** + * Removes a {@link Callback} to the list of callbacks notified when a value in the + * configuration changes. * - * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. - * @param value in Integer format. - * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants. + * @param c callback to remove. */ - @Override - public int setProvisionedValue(int item, int value) throws RemoteException { - return ImsConfig.OperationStatusConstants.FAILED; + private void removeImsConfigCallback(IImsConfigCallback c) { + mCallbacks.unregister(c); } /** - * Sets the value for IMS service/capabilities parameters by the operator device - * management entity. It sets the config item value in the provisioned storage - * from which the master value is derived. Synchronous blocking call. + * @param item + * @param value + */ + private final void notifyConfigChanged(int item, int value) { + // can be null in testing + if (mCallbacks == null) { + return; + } + mCallbacks.broadcast(c -> { + try { + c.onIntConfigChanged(item, value); + } catch (RemoteException e) { + Log.w(TAG, "notifyConfigChanged(int): dead binder in notify, skipping."); + } + }); + } + + private void notifyConfigChanged(int item, String value) { + // can be null in testing + if (mCallbacks == null) { + return; + } + mCallbacks.broadcast(c -> { + try { + c.onStringConfigChanged(item, value); + } catch (RemoteException e) { + Log.w(TAG, "notifyConfigChanged(string): dead binder in notify, skipping."); + } + }); + } + + /** + * @hide + */ + public IImsConfig getIImsConfig() { return mImsConfigStub; } + + /** + * Updates provisioning value and notifies the framework of the change. + * Doesn't call {@link #setConfig(int,int)} and assumes the result succeeded. + * This should only be used when the IMS implementer implicitly changed provisioned values. * - * @param item as defined in com.android.ims.ImsConfig#ConfigConstants. - * @param value in String format. - * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants. + * @param item an integer key. + * @param value in Integer format. */ - @Override - public int setProvisionedStringValue(int item, String value) throws RemoteException { - return ImsConfig.OperationStatusConstants.FAILED; + public final void notifyProvisionedValueChanged(int item, int value) { + try { + mImsConfigStub.updateCachedValue(item, value, true); + } catch (RemoteException e) { + Log.w(TAG, "notifyProvisionedValueChanged(int): Framework connection is dead."); + } } /** - * Gets the value of the specified IMS feature item for specified network type. - * This operation gets the feature config value from the master storage (i.e. final - * value). Asynchronous non-blocking call. + * Updates provisioning value and notifies the framework of the change. + * Doesn't call {@link #setConfig(int,String)} and assumes the result succeeded. + * This should only be used when the IMS implementer implicitly changed provisioned values. * - * @param feature as defined in com.android.ims.ImsConfig#FeatureConstants. - * @param network as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX. - * @param listener feature value returned asynchronously through listener. + * @param item an integer key. + * @param value in String format. */ - @Override - public void getFeatureValue(int feature, int network, ImsConfigListener listener) - throws RemoteException { + public final void notifyProvisionedValueChanged(int item, String value) { + try { + mImsConfigStub.updateCachedValue(item, value, true); + } catch (RemoteException e) { + Log.w(TAG, "notifyProvisionedValueChanged(string): Framework connection is dead."); + } } /** - * Sets the value for IMS feature item for specified network type. - * This operation stores the user setting in setting db from which master db - * is derived. + * Sets the configuration value for this ImsService. * - * @param feature as defined in com.android.ims.ImsConfig#FeatureConstants. - * @param network as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX. - * @param value as defined in com.android.ims.ImsConfig#FeatureValueConstants. - * @param listener, provided if caller needs to be notified for set result. - */ - @Override - public void setFeatureValue(int feature, int network, int value, ImsConfigListener listener) - throws RemoteException { + * @param item an integer key. + * @param value an integer containing the configuration value. + * @return the result of setting the configuration value, defined as either + * {@link #CONFIG_RESULT_FAILED} or {@link #CONFIG_RESULT_SUCCESS}. + */ + public int setConfig(int item, int value) { + // Base Implementation - To be overridden. + return CONFIG_RESULT_FAILED; } /** - * Gets the value for IMS VoLTE provisioned. - * This should be the same as the operator provisioned value if applies. + * Sets the configuration value for this ImsService. + * + * @param item an integer key. + * @param value a String containing the new configuration value. + * @return Result of setting the configuration value, defined as either + * {@link #CONFIG_RESULT_FAILED} or {@link #CONFIG_RESULT_SUCCESS}. */ - @Override - public boolean getVolteProvisioned() throws RemoteException { - return false; + public int setConfig(int item, String value) { + // Base Implementation - To be overridden. + return CONFIG_RESULT_FAILED; } /** - * Gets the value for IMS feature item video quality. + * Gets the currently stored value configuration value from the ImsService for {@code item}. * - * @param listener Video quality value returned asynchronously through listener. + * @param item an integer key. + * @return configuration value, stored in integer format or {@link #CONFIG_RESULT_UNKNOWN} if + * unavailable. */ - @Override - public void getVideoQuality(ImsConfigListener listener) throws RemoteException { + public int getConfigInt(int item) { + // Base Implementation - To be overridden. + return CONFIG_RESULT_UNKNOWN; } /** - * Sets the value for IMS feature item video quality. + * Gets the currently stored value configuration value from the ImsService for {@code item}. * - * @param quality, defines the value of video quality. - * @param listener, provided if caller needs to be notified for set result. + * @param item an integer key. + * @return configuration value, stored in String format or {@code null} if unavailable. */ - @Override - public void setVideoQuality(int quality, ImsConfigListener listener) throws RemoteException { + public String getConfigString(int item) { + // Base Implementation - To be overridden. + return null; } -} +}
\ No newline at end of file diff --git a/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java b/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java index 89f95ff0142d..06c35eaec6dd 100644 --- a/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsEcbmImplBase.java @@ -16,7 +16,9 @@ package android.telephony.ims.stub; +import android.annotation.SystemApi; import android.os.RemoteException; +import android.util.Log; import com.android.ims.internal.IImsEcbm; import com.android.ims.internal.IImsEcbmListener; @@ -30,22 +32,65 @@ import com.android.ims.internal.IImsEcbmListener; * * @hide */ +@SystemApi +public class ImsEcbmImplBase { + private static final String TAG = "ImsEcbmImplBase"; -public class ImsEcbmImplBase extends IImsEcbm.Stub { + private IImsEcbmListener mListener; + private IImsEcbm mImsEcbm = new IImsEcbm.Stub() { + @Override + public void setListener(IImsEcbmListener listener) { + mListener = listener; + } + + @Override + public void exitEmergencyCallbackMode() { + ImsEcbmImplBase.this.exitEmergencyCallbackMode(); + } + }; + + /** @hide */ + public IImsEcbm getImsEcbm() { + return mImsEcbm; + } /** - * Sets the listener. + * This method should be implemented by the IMS provider. Framework will trigger this method to + * request to come out of ECBM mode */ - @Override - public void setListener(IImsEcbmListener listener) throws RemoteException { - + public void exitEmergencyCallbackMode() { + Log.d(TAG, "exitEmergencyCallbackMode() not implemented"); } /** - * Requests Modem to come out of ECBM mode + * Notifies the framework when the device enters Emergency Callback Mode. + * + * @throws RuntimeException if the connection to the framework is not available. */ - @Override - public void exitEmergencyCallbackMode() throws RemoteException { + public final void enteredEcbm() { + Log.d(TAG, "Entered ECBM."); + if (mListener != null) { + try { + mListener.enteredECBM(); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + } + /** + * Notifies the framework when the device exits Emergency Callback Mode. + * + * @throws RuntimeException if the connection to the framework is not available. + */ + public final void exitedEcbm() { + Log.d(TAG, "Exited ECBM."); + if (mListener != null) { + try { + mListener.exitedECBM(); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } } } diff --git a/telephony/java/android/telephony/ims/internal/stub/ImsFeatureConfiguration.aidl b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.aidl index e890cf8756f3..e2ae0e8f6775 100644 --- a/telephony/java/android/telephony/ims/internal/stub/ImsFeatureConfiguration.aidl +++ b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.aidl @@ -14,6 +14,6 @@ * limitations under the License */ -package android.telephony.ims.internal.stub; +package android.telephony.ims.stub; parcelable ImsFeatureConfiguration; diff --git a/telephony/java/android/telephony/ims/internal/stub/ImsFeatureConfiguration.java b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java index 244c9578f6b4..98b67c3d3727 100644 --- a/telephony/java/android/telephony/ims/internal/stub/ImsFeatureConfiguration.java +++ b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * 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. @@ -14,29 +14,34 @@ * limitations under the License */ -package android.telephony.ims.internal.stub; +package android.telephony.ims.stub; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.ims.internal.feature.ImsFeature; +import android.telephony.ims.feature.ImsFeature; import android.util.ArraySet; -import java.util.Arrays; import java.util.Set; /** * Container class for IMS Feature configuration. This class contains the features that the - * ImsService supports, which are defined in {@link ImsFeature.FeatureType}. + * ImsService supports, which are defined in {@link ImsFeature} as + * {@link ImsFeature#FEATURE_EMERGENCY_MMTEL}, {@link ImsFeature#FEATURE_MMTEL}, and + * {@link ImsFeature#FEATURE_RCS}. + * * @hide */ -public class ImsFeatureConfiguration implements Parcelable { +@SystemApi +public final class ImsFeatureConfiguration implements Parcelable { /** * Features that this ImsService supports. */ private final Set<Integer> mFeatures; /** - * Creates an ImsFeatureConfiguration with the features + * Builder for {@link ImsFeatureConfiguration} that makes adding supported {@link ImsFeature}s + * easier. */ public static class Builder { ImsFeatureConfiguration mConfig; @@ -72,7 +77,10 @@ public class ImsFeatureConfiguration implements Parcelable { * Configuration of the ImsService, which describes which features the ImsService supports * (for registration). * @param features an array of feature integers defined in {@link ImsFeature} that describe - * which features this ImsService supports. + * which features this ImsService supports. Supported values are + * {@link ImsFeature#FEATURE_EMERGENCY_MMTEL}, {@link ImsFeature#FEATURE_MMTEL}, and + * {@link ImsFeature#FEATURE_RCS}. + * @hide */ public ImsFeatureConfiguration(int[] features) { mFeatures = new ArraySet<>(); @@ -85,7 +93,9 @@ public class ImsFeatureConfiguration implements Parcelable { } /** - * @return an int[] containing the features that this ImsService supports. + * @return an int[] containing the features that this ImsService supports. Supported values are + * {@link ImsFeature#FEATURE_EMERGENCY_MMTEL}, {@link ImsFeature#FEATURE_MMTEL}, and + * {@link ImsFeature#FEATURE_RCS}. */ public int[] getServiceFeatures() { return mFeatures.stream().mapToInt(i->i).toArray(); @@ -95,6 +105,7 @@ public class ImsFeatureConfiguration implements Parcelable { mFeatures.add(feature); } + /** @hide */ protected ImsFeatureConfiguration(Parcel in) { int[] features = in.createIntArray(); if (features != null) { @@ -130,16 +141,23 @@ public class ImsFeatureConfiguration implements Parcelable { dest.writeIntArray(mFeatures.stream().mapToInt(i->i).toArray()); } + /** + * @hide + */ @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof ImsFeatureConfiguration)) return false; - ImsFeatureConfiguration that = (ImsFeatureConfiguration) o; + ImsFeatureConfiguration + that = (ImsFeatureConfiguration) o; return mFeatures.equals(that.mFeatures); } + /** + * @hide + */ @Override public int hashCode() { return mFeatures.hashCode(); diff --git a/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java b/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java index 05da9da485a9..ce2d89a8d809 100644 --- a/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsMultiEndpointImplBase.java @@ -16,11 +16,16 @@ package android.telephony.ims.stub; +import android.annotation.SystemApi; import android.os.RemoteException; +import android.util.Log; +import android.telephony.ims.ImsExternalCallState; import com.android.ims.internal.IImsExternalCallStateListener; import com.android.ims.internal.IImsMultiEndpoint; +import java.util.List; + /** * Base implementation of ImsMultiEndpoint, which implements stub versions of the methods * in the IImsMultiEndpoint AIDL. Override the methods that your implementation of @@ -31,23 +36,49 @@ import com.android.ims.internal.IImsMultiEndpoint; * * @hide */ +@SystemApi +public class ImsMultiEndpointImplBase { + private static final String TAG = "MultiEndpointImplBase"; -public class ImsMultiEndpointImplBase extends IImsMultiEndpoint.Stub { + private IImsExternalCallStateListener mListener; + private IImsMultiEndpoint mImsMultiEndpoint = new IImsMultiEndpoint.Stub() { + @Override + public void setListener(IImsExternalCallStateListener listener) throws RemoteException { + mListener = listener; + } - /** - * Sets the listener. - */ - @Override - public void setListener(IImsExternalCallStateListener listener) throws RemoteException { + @Override + public void requestImsExternalCallStateInfo() throws RemoteException { + ImsMultiEndpointImplBase.this.requestImsExternalCallStateInfo(); + } + }; + /** @hide */ + public IImsMultiEndpoint getIImsMultiEndpoint() { + return mImsMultiEndpoint; } /** - * Query API to get the latest Dialog Event Package information - * Should be invoked only after setListener is done + * Notifies framework when Dialog Event Package update is received + * + * @throws RuntimeException if the connection to the framework is not available. */ - @Override - public void requestImsExternalCallStateInfo() throws RemoteException { + public final void onImsExternalCallStateUpdate(List<ImsExternalCallState> externalCallDialogs) { + Log.d(TAG, "ims external call state update triggered."); + if (mListener != null) { + try { + mListener.onImsExternalCallStateUpdate(externalCallDialogs); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + } + /** + * This method should be implemented by the IMS provider. Framework will trigger this to get the + * latest Dialog Event Package information. Should + */ + public void requestImsExternalCallStateInfo() { + Log.d(TAG, "requestImsExternalCallStateInfo() not implemented"); } } diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java index 42af08365f61..4334d3aadab3 100644 --- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java @@ -17,15 +17,16 @@ package android.telephony.ims.stub; import android.annotation.IntDef; +import android.annotation.SystemApi; import android.net.Uri; -import android.os.IBinder; import android.os.RemoteCallbackList; import android.os.RemoteException; +import android.telephony.ims.aidl.IImsRegistration; +import android.telephony.ims.aidl.IImsRegistrationCallback; import android.util.Log; -import com.android.ims.ImsReasonInfo; -import com.android.ims.internal.IImsRegistration; -import com.android.ims.internal.IImsRegistrationCallback; +import android.telephony.ims.ImsReasonInfo; + import com.android.internal.annotations.VisibleForTesting; import java.lang.annotation.Retention; @@ -36,11 +37,14 @@ import java.lang.annotation.RetentionPolicy; * registration for this ImsService has changed status. * @hide */ - +@SystemApi public class ImsRegistrationImplBase { private static final String LOG_TAG = "ImsRegistrationImplBase"; + /** + * @hide + */ // Defines the underlying radio technology type that we have registered for IMS over. @IntDef(flag = true, value = { @@ -155,6 +159,9 @@ public class ImsRegistrationImplBase { // Locked on mLock, create unspecified disconnect cause. private ImsReasonInfo mLastDisconnectCause = new ImsReasonInfo(); + /** + * @hide + */ public final IImsRegistration getBinder() { return mBinder; } @@ -171,8 +178,8 @@ public class ImsRegistrationImplBase { /** * Notify the framework that the device is connected to the IMS network. * - * @param imsRadioTech the radio access technology. Valid values are defined in - * {@link ImsRegistrationTech}. + * @param imsRadioTech the radio access technology. Valid values are defined as + * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}. */ public final void onRegistered(@ImsRegistrationTech int imsRadioTech) { updateToState(imsRadioTech, REGISTRATION_STATE_REGISTERED); @@ -189,8 +196,8 @@ public class ImsRegistrationImplBase { /** * Notify the framework that the device is trying to connect the IMS network. * - * @param imsRadioTech the radio access technology. Valid values are defined in - * {@link ImsRegistrationTech}. + * @param imsRadioTech the radio access technology. Valid values are defined as + * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}. */ public final void onRegistering(@ImsRegistrationTech int imsRadioTech) { updateToState(imsRadioTech, REGISTRATION_STATE_REGISTERING); @@ -221,6 +228,13 @@ public class ImsRegistrationImplBase { }); } + /** + * Notify the framework that the handover from the current radio technology to the technology + * defined in {@code imsRadioTech} has failed. + * @param imsRadioTech The technology that has failed to be changed. Valid values are + * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}. + * @param info The {@link ImsReasonInfo} for the failure to change technology. + */ public final void onTechnologyChangeFailed(@ImsRegistrationTech int imsRadioTech, ImsReasonInfo info) { mCallbacks.broadcast((c) -> { @@ -233,6 +247,11 @@ public class ImsRegistrationImplBase { }); } + /** + * The this device's subscriber associated {@link Uri}s have changed, which are used to filter + * out this device's {@link Uri}s during conference calling. + * @param uris + */ public final void onSubscriberAssociatedUriChanged(Uri[] uris) { mCallbacks.broadcast((c) -> { try { @@ -264,6 +283,11 @@ public class ImsRegistrationImplBase { } } + /** + * @return the current registration connection type. Valid values are + * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN} + * @hide + */ @VisibleForTesting public final @ImsRegistrationTech int getConnectionType() { synchronized (mLock) { diff --git a/telephony/java/android/telephony/ims/internal/stub/SmsImplBase.java b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java index 57df526b4a4e..bf8953386e49 100644 --- a/telephony/java/android/telephony/ims/internal/stub/SmsImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java @@ -14,17 +14,16 @@ * limitations under the License */ -package android.telephony.ims.internal.stub; +package android.telephony.ims.stub; import android.annotation.IntDef; import android.annotation.SystemApi; import android.os.RemoteException; import android.telephony.SmsManager; import android.telephony.SmsMessage; +import android.telephony.ims.aidl.IImsSmsListener; import android.util.Log; -import com.android.ims.internal.IImsSmsListener; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -37,7 +36,7 @@ import java.lang.annotation.RetentionPolicy; * @hide */ @SystemApi -public class SmsImplBase { +public class ImsSmsImplBase { private static final String LOG_TAG = "SmsImplBase"; /** @hide */ @@ -158,7 +157,7 @@ public class SmsImplBase { * @param token token provided in {@link #onSmsReceived(int, String, byte[])} * @param result result of delivering the message. Valid values are: * {@link #DELIVER_STATUS_OK}, - * {@link #DELIVER_STATUS_OK} + * {@link #DELIVER_STATUS_ERROR} * @param messageRef the message reference */ public void acknowledgeSms(int token, @DeliverStatusResult int messageRef, int result) { @@ -303,9 +302,9 @@ public class SmsImplBase { } /** - * Called when SmsImpl has been initialized and communication with the framework is set up. + * Called when ImsSmsImpl has been initialized and communication with the framework is set up. * Any attempt by this class to access the framework before this method is called will return - * with an {@link RuntimeException}. + * with a {@link RuntimeException}. */ public void onReady() { // Base Implementation - Should be overridden diff --git a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java index 054a8b22d0f2..fcd7faf73bb8 100644 --- a/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsUtImplBase.java @@ -16,177 +16,332 @@ package android.telephony.ims.stub; +import android.annotation.SystemApi; import android.os.Bundle; import android.os.RemoteException; +import android.telephony.ims.ImsUtListener; import com.android.ims.internal.IImsUt; import com.android.ims.internal.IImsUtListener; /** - * Base implementation of ImsUt, which implements stub versions of the methods - * in the IImsUt AIDL. Override the methods that your implementation of ImsUt supports. - * - * DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you - * will break other implementations of ImsUt maintained by other ImsServices. - * - * Provides the Ut interface interworking to get/set the supplementary service configuration. + * Base implementation of IMS UT interface, which implements stubs. Override these methods to + * implement functionality. * * @hide */ +// DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you +// will break other implementations of ImsUt maintained by other ImsServices. +@SystemApi +public class ImsUtImplBase { + + private IImsUt.Stub mServiceImpl = new IImsUt.Stub() { + @Override + public void close() throws RemoteException { + ImsUtImplBase.this.close(); + } + + @Override + public int queryCallBarring(int cbType) throws RemoteException { + return ImsUtImplBase.this.queryCallBarring(cbType); + } + + @Override + public int queryCallForward(int condition, String number) throws RemoteException { + return ImsUtImplBase.this.queryCallForward(condition, number); + } + + @Override + public int queryCallWaiting() throws RemoteException { + return ImsUtImplBase.this.queryCallWaiting(); + } + + @Override + public int queryCLIR() throws RemoteException { + return ImsUtImplBase.this.queryCLIR(); + } + + @Override + public int queryCLIP() throws RemoteException { + return ImsUtImplBase.this.queryCLIP(); + } + + @Override + public int queryCOLR() throws RemoteException { + return ImsUtImplBase.this.queryCOLR(); + } + + @Override + public int queryCOLP() throws RemoteException { + return ImsUtImplBase.this.queryCOLP(); + } + + @Override + public int transact(Bundle ssInfo) throws RemoteException { + return ImsUtImplBase.this.transact(ssInfo); + } + + @Override + public int updateCallBarring(int cbType, int action, String[] barrList) throws + RemoteException { + return ImsUtImplBase.this.updateCallBarring(cbType, action, barrList); + } + + @Override + public int updateCallForward(int action, int condition, String number, int serviceClass, + int timeSeconds) throws RemoteException { + return ImsUtImplBase.this.updateCallForward(action, condition, number, serviceClass, + timeSeconds); + } + + @Override + public int updateCallWaiting(boolean enable, int serviceClass) throws RemoteException { + return ImsUtImplBase.this.updateCallWaiting(enable, serviceClass); + } + + @Override + public int updateCLIR(int clirMode) throws RemoteException { + return ImsUtImplBase.this.updateCLIR(clirMode); + } + + @Override + public int updateCLIP(boolean enable) throws RemoteException { + return ImsUtImplBase.this.updateCLIP(enable); + } -public class ImsUtImplBase extends IImsUt.Stub { + @Override + public int updateCOLR(int presentation) throws RemoteException { + return ImsUtImplBase.this.updateCOLR(presentation); + } + + @Override + public int updateCOLP(boolean enable) throws RemoteException { + return ImsUtImplBase.this.updateCOLP(enable); + } + + @Override + public void setListener(IImsUtListener listener) throws RemoteException { + ImsUtImplBase.this.setListener(new ImsUtListener(listener)); + } + + @Override + public int queryCallBarringForServiceClass(int cbType, int serviceClass) + throws RemoteException { + return ImsUtImplBase.this.queryCallBarringForServiceClass(cbType, serviceClass); + } + + @Override + public int updateCallBarringForServiceClass(int cbType, int action, + String[] barrList, int serviceClass) throws RemoteException { + return ImsUtImplBase.this.updateCallBarringForServiceClass( + cbType, action, barrList, serviceClass); + } + }; /** - * Closes the object. This object is not usable after being closed. + * Called when the framework no longer needs to interact with the IMS UT implementation any + * longer. */ - @Override - public void close() throws RemoteException { + public void close() { } /** - * Retrieves the configuration of the call barring. + * Retrieves the call barring configuration. + * @param cbType */ - @Override - public int queryCallBarring(int cbType) throws RemoteException { + public int queryCallBarring(int cbType) { return -1; } /** * Retrieves the configuration of the call barring for specified service class. */ - @Override - public int queryCallBarringForServiceClass(int cbType, int serviceClass) - throws RemoteException { + public int queryCallBarringForServiceClass(int cbType, int serviceClass) { return -1; } /** * Retrieves the configuration of the call forward. */ - @Override - public int queryCallForward(int condition, String number) throws RemoteException { + public int queryCallForward(int condition, String number) { return -1; } /** * Retrieves the configuration of the call waiting. */ - @Override - public int queryCallWaiting() throws RemoteException { + public int queryCallWaiting() { return -1; } /** * Retrieves the default CLIR setting. + * @hide + */ + public int queryCLIR() { + return queryClir(); + } + + /** + * Retrieves the CLIP call setting. + * @hide + */ + public int queryCLIP() { + return queryClip(); + } + + /** + * Retrieves the COLR call setting. + * @hide + */ + public int queryCOLR() { + return queryColr(); + } + + /** + * Retrieves the COLP call setting. + * @hide + */ + public int queryCOLP() { + return queryColp(); + } + + /** + * Retrieves the default CLIR setting. */ - @Override - public int queryCLIR() throws RemoteException { + public int queryClir() { return -1; } /** * Retrieves the CLIP call setting. */ - @Override - public int queryCLIP() throws RemoteException { + public int queryClip() { return -1; } /** * Retrieves the COLR call setting. */ - @Override - public int queryCOLR() throws RemoteException { + public int queryColr() { return -1; } /** * Retrieves the COLP call setting. */ - @Override - public int queryCOLP() throws RemoteException { + public int queryColp() { return -1; } /** * Updates or retrieves the supplementary service configuration. */ - @Override - public int transact(Bundle ssInfo) throws RemoteException { + public int transact(Bundle ssInfo) { return -1; } /** * Updates the configuration of the call barring. */ - @Override - public int updateCallBarring(int cbType, int action, String[] barrList) throws RemoteException { + public int updateCallBarring(int cbType, int action, String[] barrList) { return -1; } /** * Updates the configuration of the call barring for specified service class. */ - @Override public int updateCallBarringForServiceClass(int cbType, int action, String[] barrList, - int serviceClass) throws RemoteException { + int serviceClass) { return -1; } /** * Updates the configuration of the call forward. */ - @Override public int updateCallForward(int action, int condition, String number, int serviceClass, - int timeSeconds) throws RemoteException { + int timeSeconds) { return 0; } /** * Updates the configuration of the call waiting. */ - @Override - public int updateCallWaiting(boolean enable, int serviceClass) throws RemoteException { + public int updateCallWaiting(boolean enable, int serviceClass) { return -1; } /** * Updates the configuration of the CLIR supplementary service. + * @hide + */ + public int updateCLIR(int clirMode) { + return updateClir(clirMode); + } + + /** + * Updates the configuration of the CLIP supplementary service. + * @hide + */ + public int updateCLIP(boolean enable) { + return updateClip(enable); + } + + /** + * Updates the configuration of the COLR supplementary service. + * @hide + */ + public int updateCOLR(int presentation) { + return updateColr(presentation); + } + + /** + * Updates the configuration of the COLP supplementary service. + * @hide + */ + public int updateCOLP(boolean enable) { + return updateColp(enable); + } + + /** + * Updates the configuration of the CLIR supplementary service. */ - @Override - public int updateCLIR(int clirMode) throws RemoteException { + public int updateClir(int clirMode) { return -1; } /** * Updates the configuration of the CLIP supplementary service. */ - @Override - public int updateCLIP(boolean enable) throws RemoteException { + public int updateClip(boolean enable) { return -1; } /** * Updates the configuration of the COLR supplementary service. */ - @Override - public int updateCOLR(int presentation) throws RemoteException { + public int updateColr(int presentation) { return -1; } /** * Updates the configuration of the COLP supplementary service. */ - @Override - public int updateCOLP(boolean enable) throws RemoteException { + public int updateColp(boolean enable) { return -1; } /** * Sets the listener. */ - @Override - public void setListener(IImsUtListener listener) throws RemoteException { + public void setListener(ImsUtListener listener) { + } + + /** + * @hide + */ + public IImsUt getInterface() { + return mServiceImpl; } } diff --git a/telephony/java/com/android/ims/ImsConfig.java b/telephony/java/com/android/ims/ImsConfig.java index cf4c47bf541f..421b0151b9c6 100644 --- a/telephony/java/com/android/ims/ImsConfig.java +++ b/telephony/java/com/android/ims/ImsConfig.java @@ -19,8 +19,9 @@ package com.android.ims; import android.content.Context; import android.os.RemoteException; import android.telephony.Rlog; - -import com.android.ims.internal.IImsConfig; +import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.aidl.IImsConfig; +import android.telephony.ims.stub.ImsConfigImplBase; /** * Provides APIs to get/set the IMS service feature/capability/parameters. @@ -46,7 +47,7 @@ public class ImsConfig { /** * Broadcast action: the configuration was changed - * + * @deprecated Use {@link ImsConfig#addConfigCallback(ImsConfigImplBase.Callback)} instead. * @hide */ public static final String ACTION_IMS_CONFIG_CHANGED = @@ -70,6 +71,8 @@ public class ImsConfig { /** * Defines IMS service/capability feature constants. + * @deprecated Use + * {@link android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability} instead. */ public static class FeatureConstants { public static final int FEATURE_TYPE_UNKNOWN = -1; @@ -539,162 +542,164 @@ public class ImsConfig { } public ImsConfig(IImsConfig iconfig, Context context) { - if (DBG) Rlog.d(TAG, "ImsConfig creates"); + if (DBG) Rlog.d(TAG, "ImsConfig created"); miConfig = iconfig; mContext = context; } /** - * Gets the provisioned value for IMS service/capabilities parameters used by IMS stack. - * This function should not be called from the mainthread as it could block the - * mainthread. + * @deprecated see {@link #getInt(int)} instead. + */ + public int getProvisionedValue(int item) throws ImsException { + return getConfigInt(item); + } + + /** + * Gets the configuration value for IMS service/capabilities parameters used by IMS stack. * * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. * @return the value in Integer format. - * - * @throws ImsException if calling the IMS service results in an error. + * @throws ImsException if the ImsService is unavailable. */ - public int getProvisionedValue(int item) throws ImsException { + public int getConfigInt(int item) throws ImsException { int ret = 0; try { - ret = miConfig.getProvisionedValue(item); + ret = miConfig.getConfigInt(item); } catch (RemoteException e) { - throw new ImsException("getValue()", e, + throw new ImsException("getInt()", e, ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE); } - if (DBG) Rlog.d(TAG, "getProvisionedValue(): item = " + item + ", ret =" + ret); + if (DBG) Rlog.d(TAG, "getInt(): item = " + item + ", ret =" + ret); return ret; } /** - * Gets the provisioned value for IMS service/capabilities parameters used by IMS stack. - * This function should not be called from the mainthread as it could block the - * mainthread. + * @deprecated see {@link #getConfigString(int)} instead + */ + public String getProvisionedStringValue(int item) throws ImsException { + return getConfigString(item); + } + + /** + * Gets the configuration value for IMS service/capabilities parameters used by IMS stack. * * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. * @return value in String format. * - * @throws ImsException if calling the IMS service results in an error. + * @throws ImsException if the ImsService is unavailable. */ - public String getProvisionedStringValue(int item) throws ImsException { + public String getConfigString(int item) throws ImsException { String ret = "Unknown"; try { - ret = miConfig.getProvisionedStringValue(item); + ret = miConfig.getConfigString(item); } catch (RemoteException e) { - throw new ImsException("getProvisionedStringValue()", e, + throw new ImsException("getConfigString()", e, ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE); } - if (DBG) Rlog.d(TAG, "getProvisionedStringValue(): item = " + item + ", ret =" + ret); + if (DBG) Rlog.d(TAG, "getConfigString(): item = " + item + ", ret =" + ret); return ret; } /** - * Sets the value for IMS service/capabilities parameters by - * the operator device management entity. - * This function should not be called from main thread as it could block - * mainthread. + * @deprecated see {@link #setConfig(int, int)} instead. + */ + public int setProvisionedValue(int item, int value) throws ImsException { + return setConfig(item, value); + } + + /** + * @deprecated see {@link #setConfig(int, String)} instead. + */ + public int setProvisionedStringValue(int item, String value) throws ImsException { + return setConfig(item, value); + } + + /** + * Sets the value for ImsService configuration item. * * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. * @param value in Integer format. * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants * - * @throws ImsException if calling the IMS service results in an error. + * @throws ImsException if the ImsService is unavailable. */ - public int setProvisionedValue(int item, int value) - throws ImsException { + public int setConfig(int item, int value) throws ImsException { int ret = OperationStatusConstants.UNKNOWN; if (DBG) { - Rlog.d(TAG, "setProvisionedValue(): item = " + item + + Rlog.d(TAG, "setConfig(): item = " + item + "value = " + value); } try { - ret = miConfig.setProvisionedValue(item, value); + ret = miConfig.setConfigInt(item, value); } catch (RemoteException e) { - throw new ImsException("setProvisionedValue()", e, + throw new ImsException("setConfig()", e, ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE); } if (DBG) { - Rlog.d(TAG, "setProvisionedValue(): item = " + item + + Rlog.d(TAG, "setConfig(): item = " + item + " value = " + value + " ret = " + ret); } return ret; + } /** - * Sets the value for IMS service/capabilities parameters by - * the operator device management entity. - * This function should not be called from main thread as it could block - * mainthread. + * Sets the value for ImsService configuration item. * * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. - * @param value in String format. + * @param value in Integer format. * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants * - * @throws ImsException if calling the IMS service results in an error. + * @throws ImsException if the ImsService is unavailable. */ - public int setProvisionedStringValue(int item, String value) - throws ImsException { + public int setConfig(int item, String value) throws ImsException { int ret = OperationStatusConstants.UNKNOWN; + if (DBG) { + Rlog.d(TAG, "setConfig(): item = " + item + + "value = " + value); + } try { - ret = miConfig.setProvisionedStringValue(item, value); + ret = miConfig.setConfigString(item, value); } catch (RemoteException e) { - throw new ImsException("setProvisionedStringValue()", e, + throw new ImsException("setConfig()", e, ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE); } if (DBG) { - Rlog.d(TAG, "setProvisionedStringValue(): item = " + item + - ", value =" + value); + Rlog.d(TAG, "setConfig(): item = " + item + + " value = " + value + " ret = " + ret); } return ret; } /** - * Gets the value for IMS feature item for specified network type. + * Adds a {@link ImsConfigImplBase.Callback} to the ImsService to notify when a Configuration + * item has changed. * - * @param feature, defined as in FeatureConstants. - * @param network, defined as in android.telephony.TelephonyManager#NETWORK_TYPE_XXX. - * @param listener, provided to be notified for the feature on/off status. - * @return void - * - * @throws ImsException if calling the IMS service results in an error. + * Make sure to call {@link #removeConfigCallback(ImsConfigImplBase.Callback)} when finished + * using this callback. */ - public void getFeatureValue(int feature, int network, - ImsConfigListener listener) throws ImsException { - if (DBG) { - Rlog.d(TAG, "getFeatureValue: feature = " + feature + ", network =" + network + - ", listener =" + listener); - } + public void addConfigCallback(ImsConfigImplBase.Callback callback) throws ImsException { + if (DBG) Rlog.d(TAG, "addConfigCallback: " + callback); try { - miConfig.getFeatureValue(feature, network, listener); - } catch (RemoteException e) { - throw new ImsException("getFeatureValue()", e, + miConfig.addImsConfigCallback(callback); + } catch (RemoteException e) { + throw new ImsException("addConfigCallback()", e, ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE); } } /** - * Sets the value for IMS feature item for specified network type. - * - * @param feature, as defined in FeatureConstants. - * @param network, as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX. - * @param value, as defined in FeatureValueConstants. - * @param listener, provided if caller needs to be notified for set result. - * @return void - * - * @throws ImsException if calling the IMS service results in an error. + * Removes a {@link ImsConfigImplBase.Callback} from the ImsService that was previously added + * by {@link #addConfigCallback(ImsConfigImplBase.Callback)}. */ - public void setFeatureValue(int feature, int network, int value, - ImsConfigListener listener) throws ImsException { - if (DBG) { - Rlog.d(TAG, "setFeatureValue: feature = " + feature + ", network =" + network + - ", value =" + value + ", listener =" + listener); - } + public void removeConfigCallback(ImsConfigImplBase.Callback callback) throws ImsException { + if (DBG) Rlog.d(TAG, "removeConfigCallback: " + callback); try { - miConfig.setFeatureValue(feature, network, value, listener); - } catch (RemoteException e) { - throw new ImsException("setFeatureValue()", e, + miConfig.removeImsConfigCallback(callback); + } catch (RemoteException e) { + throw new ImsException("removeConfigCallback()", e, ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE); } } diff --git a/telephony/java/com/android/ims/ImsException.java b/telephony/java/com/android/ims/ImsException.java index 0e8bad79c59b..f35e88672a23 100644 --- a/telephony/java/com/android/ims/ImsException.java +++ b/telephony/java/com/android/ims/ImsException.java @@ -16,6 +16,8 @@ package com.android.ims; +import android.telephony.ims.ImsReasonInfo; + /** * This class defines a general IMS-related exception. * diff --git a/telephony/java/com/android/ims/ImsUtInterface.java b/telephony/java/com/android/ims/ImsUtInterface.java index 14c184a64061..c9d440551631 100644 --- a/telephony/java/com/android/ims/ImsUtInterface.java +++ b/telephony/java/com/android/ims/ImsUtInterface.java @@ -18,6 +18,8 @@ package com.android.ims; import android.os.Handler; import android.os.Message; +import android.telephony.ims.ImsCallForwardInfo; +import android.telephony.ims.ImsSsInfo; /** * Provides APIs for the supplementary service settings using IMS (Ut interface). diff --git a/telephony/java/com/android/ims/internal/IImsCallSession.aidl b/telephony/java/com/android/ims/internal/IImsCallSession.aidl index c6fc5e563bf4..203e6cf9c577 100644 --- a/telephony/java/com/android/ims/internal/IImsCallSession.aidl +++ b/telephony/java/com/android/ims/internal/IImsCallSession.aidl @@ -17,9 +17,10 @@ package com.android.ims.internal; import android.os.Message; -import com.android.ims.ImsCallProfile; -import com.android.ims.ImsStreamMediaProfile; -import com.android.ims.internal.IImsCallSessionListener; +import android.telephony.ims.aidl.IImsCallSessionListener; + +import android.telephony.ims.ImsCallProfile; +import android.telephony.ims.ImsStreamMediaProfile; import com.android.ims.internal.IImsVideoCallProvider; /** diff --git a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl index 748092d2a3bd..a8e8b7dd03aa 100644 --- a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl +++ b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl @@ -16,12 +16,12 @@ package com.android.ims.internal; -import com.android.ims.ImsStreamMediaProfile; -import com.android.ims.ImsCallProfile; -import com.android.ims.ImsReasonInfo; -import com.android.ims.ImsConferenceState; +import android.telephony.ims.ImsStreamMediaProfile; +import android.telephony.ims.ImsCallProfile; +import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.ImsConferenceState; import com.android.ims.internal.IImsCallSession; -import com.android.ims.ImsSuppServiceNotification; +import android.telephony.ims.ImsSuppServiceNotification; /** * A listener type for receiving notification on IMS call session events. diff --git a/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl b/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl index 16219671cea5..b3d813960c55 100644 --- a/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl +++ b/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl @@ -16,7 +16,7 @@ package com.android.ims.internal; -import com.android.ims.ImsExternalCallState; +import android.telephony.ims.ImsExternalCallState; /** * A listener type for receiving notifications about DEP through IMS diff --git a/telephony/java/com/android/ims/internal/IImsFeatureStatusCallback.aidl b/telephony/java/com/android/ims/internal/IImsFeatureStatusCallback.aidl index 41b1042e9a86..b83b13060aff 100644 --- a/telephony/java/com/android/ims/internal/IImsFeatureStatusCallback.aidl +++ b/telephony/java/com/android/ims/internal/IImsFeatureStatusCallback.aidl @@ -17,9 +17,9 @@ package com.android.ims.internal; /** -* Interface from ImsFeature in the ImsService to ImsServiceController. + * Interface from ImsFeature in the ImsService to ImsServiceController. * {@hide} */ oneway interface IImsFeatureStatusCallback { void notifyImsFeatureStatus(int featureStatus); -}
\ No newline at end of file +} diff --git a/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl b/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl index 10c7f3e8a2d7..51511923402f 100644 --- a/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl +++ b/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl @@ -18,14 +18,12 @@ package com.android.ims.internal; import android.app.PendingIntent; -import com.android.ims.ImsCallProfile; +import android.telephony.ims.ImsCallProfile; import com.android.ims.internal.IImsCallSession; -import com.android.ims.internal.IImsCallSessionListener; import com.android.ims.internal.IImsConfig; import com.android.ims.internal.IImsEcbm; import com.android.ims.internal.IImsMultiEndpoint; import com.android.ims.internal.IImsRegistrationListener; -import com.android.ims.internal.IImsSmsListener; import com.android.ims.internal.IImsUt; import android.os.Message; @@ -44,8 +42,7 @@ interface IImsMMTelFeature { void addRegistrationListener(in IImsRegistrationListener listener); void removeRegistrationListener(in IImsRegistrationListener listener); ImsCallProfile createCallProfile(int sessionId, int callSessionType, int callType); - IImsCallSession createCallSession(int sessionId, in ImsCallProfile profile, - IImsCallSessionListener listener); + IImsCallSession createCallSession(int sessionId, in ImsCallProfile profile); IImsCallSession getPendingCallSession(int sessionId, String callId); IImsUt getUtInterface(); IImsConfig getConfigInterface(); @@ -54,12 +51,4 @@ interface IImsMMTelFeature { IImsEcbm getEcbmInterface(); void setUiTTYMode(int uiTtyMode, in Message onComplete); IImsMultiEndpoint getMultiEndpointInterface(); - // SMS APIs - void setSmsListener(IImsSmsListener l); - oneway void sendSms(in int token, int messageRef, String format, String smsc, boolean retry, - in byte[] pdu); - oneway void acknowledgeSms(int token, int messageRef, int result); - oneway void acknowledgeSmsReport(int token, int messageRef, int result); - String getSmsFormat(); - oneway void onSmsReady(); } diff --git a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl index 15f872603bfb..2212109c8a67 100644 --- a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl +++ b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl @@ -16,7 +16,7 @@ package com.android.ims.internal; -import com.android.ims.ImsReasonInfo; +import android.telephony.ims.ImsReasonInfo; import android.net.Uri; diff --git a/telephony/java/com/android/ims/internal/IImsService.aidl b/telephony/java/com/android/ims/internal/IImsService.aidl index 406d22d9bd8e..c3cc6fb7a385 100644 --- a/telephony/java/com/android/ims/internal/IImsService.aidl +++ b/telephony/java/com/android/ims/internal/IImsService.aidl @@ -18,7 +18,7 @@ package com.android.ims.internal; import android.app.PendingIntent; -import com.android.ims.ImsCallProfile; +import android.telephony.ims.ImsCallProfile; import com.android.ims.internal.IImsCallSession; import com.android.ims.internal.IImsCallSessionListener; import com.android.ims.internal.IImsConfig; diff --git a/telephony/java/com/android/ims/internal/IImsServiceController.aidl b/telephony/java/com/android/ims/internal/IImsServiceController.aidl index 7ac25ac13fbe..857089fac33a 100644 --- a/telephony/java/com/android/ims/internal/IImsServiceController.aidl +++ b/telephony/java/com/android/ims/internal/IImsServiceController.aidl @@ -18,7 +18,6 @@ package com.android.ims.internal; import com.android.ims.internal.IImsFeatureStatusCallback; import com.android.ims.internal.IImsMMTelFeature; -import com.android.ims.internal.IImsRegistration; import com.android.ims.internal.IImsRcsFeature; /** @@ -30,5 +29,4 @@ interface IImsServiceController { IImsMMTelFeature createMMTelFeature(int slotId, in IImsFeatureStatusCallback c); IImsRcsFeature createRcsFeature(int slotId, in IImsFeatureStatusCallback c); void removeImsFeature(int slotId, int featureType, in IImsFeatureStatusCallback c); - IImsRegistration getRegistration(int slotId); } diff --git a/telephony/java/com/android/ims/internal/IImsUtListener.aidl b/telephony/java/com/android/ims/internal/IImsUtListener.aidl index 1bc036979356..a603cd34dfcd 100644 --- a/telephony/java/com/android/ims/internal/IImsUtListener.aidl +++ b/telephony/java/com/android/ims/internal/IImsUtListener.aidl @@ -18,11 +18,11 @@ package com.android.ims.internal; import android.os.Bundle; -import com.android.ims.ImsCallForwardInfo; -import com.android.ims.ImsSsData; -import com.android.ims.ImsSsInfo; +import android.telephony.ims.ImsCallForwardInfo; +import android.telephony.ims.ImsSsInfo; import com.android.ims.internal.IImsUt; -import com.android.ims.ImsReasonInfo; +import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.ImsSsData; /** * {@hide} diff --git a/telephony/java/com/android/internal/telephony/ExponentialBackoff.java b/telephony/java/com/android/internal/telephony/ExponentialBackoff.java index 80958c077d6a..f323a0cc6201 100644 --- a/telephony/java/com/android/internal/telephony/ExponentialBackoff.java +++ b/telephony/java/com/android/internal/telephony/ExponentialBackoff.java @@ -20,6 +20,8 @@ import android.annotation.NonNull; import android.os.Handler; import android.os.Looper; +import com.android.internal.annotations.VisibleForTesting; + /** The implementation of exponential backoff with jitter applied. */ public class ExponentialBackoff { private int mRetryCounter; @@ -27,8 +29,31 @@ public class ExponentialBackoff { private long mMaximumDelayMs; private long mCurrentDelayMs; private int mMultiplier; - private Runnable mRunnable; - private Handler mHandler; + private final Runnable mRunnable; + private final Handler mHandler; + + /** + * Implementation of Handler methods, Adapter for testing (can't spy on final methods). + */ + private HandlerAdapter mHandlerAdapter = new HandlerAdapter() { + @Override + public boolean postDelayed(Runnable runnable, long delayMillis) { + return mHandler.postDelayed(runnable, delayMillis); + } + + @Override + public void removeCallbacks(Runnable runnable) { + mHandler.removeCallbacks(runnable); + } + }; + + /** + * Need to spy final methods for testing. + */ + public interface HandlerAdapter { + boolean postDelayed(Runnable runnable, long delayMillis); + void removeCallbacks(Runnable runnable); + } public ExponentialBackoff( long initialDelayMs, @@ -57,14 +82,14 @@ public class ExponentialBackoff { public void start() { mRetryCounter = 0; mCurrentDelayMs = mStartDelayMs; - mHandler.removeCallbacks(mRunnable); - mHandler.postDelayed(mRunnable, mCurrentDelayMs); + mHandlerAdapter.removeCallbacks(mRunnable); + mHandlerAdapter.postDelayed(mRunnable, mCurrentDelayMs); } /** Stops the backoff, all pending messages will be removed from the message queue. */ public void stop() { mRetryCounter = 0; - mHandler.removeCallbacks(mRunnable); + mHandlerAdapter.removeCallbacks(mRunnable); } /** Should call when the retry action has failed and we want to retry after a longer delay. */ @@ -73,12 +98,17 @@ public class ExponentialBackoff { long temp = Math.min( mMaximumDelayMs, (long) (mStartDelayMs * Math.pow(mMultiplier, mRetryCounter))); mCurrentDelayMs = (long) (((1 + Math.random()) / 2) * temp); - mHandler.removeCallbacks(mRunnable); - mHandler.postDelayed(mRunnable, mCurrentDelayMs); + mHandlerAdapter.removeCallbacks(mRunnable); + mHandlerAdapter.postDelayed(mRunnable, mCurrentDelayMs); } /** Returns the delay for the most recently posted message. */ public long getCurrentDelay() { return mCurrentDelayMs; } + + @VisibleForTesting + public void setHandlerAdapter(HandlerAdapter a) { + mHandlerAdapter = a; + } } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 797805b52368..2b4c059cf69f 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -38,9 +38,10 @@ import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.TelephonyHistogram; import android.telephony.VisualVoicemailSmsFilterSettings; -import com.android.ims.internal.IImsMMTelFeature; -import com.android.ims.internal.IImsRcsFeature; -import com.android.ims.internal.IImsRegistration; +import android.telephony.ims.aidl.IImsConfig; +import android.telephony.ims.aidl.IImsMmTelFeature; +import android.telephony.ims.aidl.IImsRcsFeature; +import android.telephony.ims.aidl.IImsRegistration; import com.android.ims.internal.IImsServiceFeatureCallback; import com.android.internal.telephony.CellNetworkScanResult; import com.android.internal.telephony.OperatorInfo; @@ -788,20 +789,21 @@ interface ITelephony { int getTetherApnRequired(); /** - * Get IImsMMTelFeature binder from ImsResolver that corresponds to the subId and MMTel feature - * as well as registering the MMTelFeature for callbacks using the IImsServiceFeatureCallback - * interface. - */ - IImsMMTelFeature getMMTelFeatureAndListen(int slotId, in IImsServiceFeatureCallback callback); + * Enables framework IMS and triggers IMS Registration. + */ + void enableIms(int slotId); /** - * Get IImsMMTelFeature binder from ImsResolver that corresponds to the subId and MMTel feature - * as well as registering the MMTelFeature for callbacks using the IImsServiceFeatureCallback + * Disables framework IMS and triggers IMS deregistration. + */ + void disableIms(int slotId); + + /** + * Get IImsMmTelFeature binder from ImsResolver that corresponds to the subId and MMTel feature + * as well as registering the MmTelFeature for callbacks using the IImsServiceFeatureCallback * interface. - * Used for emergency calling only. */ - IImsMMTelFeature getEmergencyMMTelFeatureAndListen(int slotId, - in IImsServiceFeatureCallback callback); + IImsMmTelFeature getMmTelFeatureAndListen(int slotId, in IImsServiceFeatureCallback callback); /** * Get IImsRcsFeature binder from ImsResolver that corresponds to the subId and RCS feature @@ -816,6 +818,11 @@ interface ITelephony { IImsRegistration getImsRegistration(int slotId, int feature); /** + * Returns the IImsConfig associated with the slot and feature specified. + */ + IImsConfig getImsConfig(int slotId, int feature); + + /** * Set the network selection mode to automatic. * * @param subId the id of the subscription to update. diff --git a/test-base/Android.bp b/test-base/Android.bp index cc7d4bd44bdf..b65cda9302a7 100644 --- a/test-base/Android.bp +++ b/test-base/Android.bp @@ -72,8 +72,8 @@ java_library_static { // =============================================== // This contains the android.test classes from android.test.base plus // the com.android.internal.util.Predicate[s] classes. This is only -// intended for inclusion in the android.test.legacy static library and -// must not be used elsewhere. +// intended for inclusion in the android.test.legacy and +// legacy-android-test static libraries and must not be used elsewhere. java_library_static { name: "android.test.base-minus-junit", diff --git a/test-mock/api/android-test-mock-current.txt b/test-mock/api/android-test-mock-current.txt index 73f794b8e431..10286c297152 100644 --- a/test-mock/api/android-test-mock-current.txt +++ b/test-mock/api/android-test-mock-current.txt @@ -1,5 +1,9 @@ package android.test.mock { + public deprecated class MockAccountManager { + method public static android.accounts.AccountManager newMockAccountManager(android.content.Context); + } + public deprecated class MockApplication extends android.app.Application { ctor public MockApplication(); } @@ -9,6 +13,7 @@ package android.test.mock { ctor public MockContentProvider(android.content.Context); ctor public MockContentProvider(android.content.Context, java.lang.String, java.lang.String, android.content.pm.PathPermission[]); method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>); + method public static deprecated void attachInfoForTesting(android.content.ContentProvider, android.content.Context, android.content.pm.ProviderInfo); method public int delete(android.net.Uri, java.lang.String, java.lang.String[]); method public final android.content.IContentProvider getIContentProvider(); method public java.lang.String getType(android.net.Uri); @@ -411,5 +416,9 @@ package android.test.mock { method public void updateConfiguration(android.content.res.Configuration, android.util.DisplayMetrics); } + public deprecated class MockService { + method public static <T extends android.app.Service> void attachForTesting(android.app.Service, android.content.Context, java.lang.String, android.app.Application); + } + } diff --git a/test-mock/src/android/test/mock/MockAccountManager.java b/test-mock/src/android/test/mock/MockAccountManager.java new file mode 100644 index 000000000000..c9b4c7ba0f8f --- /dev/null +++ b/test-mock/src/android/test/mock/MockAccountManager.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.test.mock; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.accounts.AccountManagerCallback; +import android.accounts.AccountManagerFuture; +import android.accounts.AuthenticatorException; +import android.accounts.OnAccountsUpdateListener; +import android.accounts.OperationCanceledException; +import android.content.Context; +import android.os.Handler; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +/** + * A mock {@link android.accounts.AccountManager} class. + * + * <p>Provided for use by {@code android.test.IsolatedContext}. + * + * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>. + * New tests should be written using the + * <a href="{@docRoot} + * tools/testing-support-library/index.html">Android Testing Support Library</a>. + */ +@Deprecated +public class MockAccountManager { + + /** + * Create a new mock {@link AccountManager} instance. + * + * @param context the {@link Context} to which the returned object belongs. + * @return the new instance. + */ + public static AccountManager newMockAccountManager(Context context) { + return new MockAccountManagerImpl(context); + } + + private MockAccountManager() { + } + + private static class MockAccountManagerImpl extends AccountManager { + + MockAccountManagerImpl(Context context) { + super(context, null /* IAccountManager */, null /* handler */); + } + + public void addOnAccountsUpdatedListener(OnAccountsUpdateListener listener, + Handler handler, boolean updateImmediately) { + // do nothing + } + + public Account[] getAccounts() { + return new Account[] {}; + } + + public AccountManagerFuture<Account[]> getAccountsByTypeAndFeatures( + final String type, final String[] features, + AccountManagerCallback<Account[]> callback, Handler handler) { + return new MockAccountManagerFuture<Account[]>(new Account[0]); + } + + public String blockingGetAuthToken(Account account, String authTokenType, + boolean notifyAuthFailure) + throws OperationCanceledException, IOException, AuthenticatorException { + return null; + } + } + + /** + * A very simple AccountManagerFuture class + * that returns what ever was passed in + */ + private static class MockAccountManagerFuture<T> + implements AccountManagerFuture<T> { + + T mResult; + + MockAccountManagerFuture(T result) { + mResult = result; + } + + public boolean cancel(boolean mayInterruptIfRunning) { + return false; + } + + public boolean isCancelled() { + return false; + } + + public boolean isDone() { + return true; + } + + public T getResult() + throws OperationCanceledException, IOException, AuthenticatorException { + return mResult; + } + + public T getResult(long timeout, TimeUnit unit) + throws OperationCanceledException, IOException, AuthenticatorException { + return getResult(); + } + } +} diff --git a/test-mock/src/android/test/mock/MockContentProvider.java b/test-mock/src/android/test/mock/MockContentProvider.java index d5f3ce880b8f..b917fbd8a1fe 100644 --- a/test-mock/src/android/test/mock/MockContentProvider.java +++ b/test-mock/src/android/test/mock/MockContentProvider.java @@ -277,4 +277,21 @@ public class MockContentProvider extends ContentProvider { public final IContentProvider getIContentProvider() { return mIContentProvider; } + + /** + * Like {@link #attachInfo(Context, android.content.pm.ProviderInfo)}, but for use + * when directly instantiating the provider for testing. + * + * <p>Provided for use by {@code android.test.ProviderTestCase2} and + * {@code android.test.RenamingDelegatingContext}. + * + * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>. + * New tests should be written using the + * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>. + */ + @Deprecated + public static void attachInfoForTesting( + ContentProvider provider, Context context, ProviderInfo providerInfo) { + provider.attachInfoForTesting(context, providerInfo); + } } diff --git a/test-mock/src/android/test/mock/MockService.java b/test-mock/src/android/test/mock/MockService.java new file mode 100644 index 000000000000..dbba4f329eae --- /dev/null +++ b/test-mock/src/android/test/mock/MockService.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.test.mock; + +import android.app.Application; +import android.app.Service; +import android.content.Context; + +/** + * A mock {@link android.app.Service} class. + * + * <p>Provided for use by {@code android.test.ServiceTestCase}. + * + * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>. + * New tests should be written using the + * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>. + */ +@Deprecated +public class MockService { + + public static <T extends Service> void attachForTesting(Service service, Context context, + String serviceClassName, + Application application) { + service.attach( + context, + null, // ActivityThread not actually used in Service + serviceClassName, + null, // token not needed when not talking with the activity manager + application, + null // mocked services don't talk with the activity manager + ); + } + + private MockService() { + } +} diff --git a/test-runner/Android.bp b/test-runner/Android.bp index b902011dc996..66b95271ee06 100644 --- a/test-runner/Android.bp +++ b/test-runner/Android.bp @@ -33,7 +33,8 @@ java_library { // Build the android.test.runner-minus-junit library // ================================================= -// This is provided solely for use by the legacy-android-test module. +// This is only intended for inclusion in the android.test.legacy and +// legacy-android-test static libraries and must not be used elsewhere. java_library { name: "android.test.runner-minus-junit", diff --git a/test-runner/src/android/test/IsolatedContext.java b/test-runner/src/android/test/IsolatedContext.java index 0b77c0062dfb..6e4c41eef81c 100644 --- a/test-runner/src/android/test/IsolatedContext.java +++ b/test-runner/src/android/test/IsolatedContext.java @@ -17,12 +17,6 @@ package android.test; import android.accounts.AccountManager; -import android.accounts.AccountManagerCallback; -import android.accounts.AccountManagerFuture; -import android.accounts.AuthenticatorException; -import android.accounts.OnAccountsUpdateListener; -import android.accounts.OperationCanceledException; -import android.accounts.Account; import android.content.ContextWrapper; import android.content.ContentResolver; import android.content.Intent; @@ -32,12 +26,10 @@ import android.content.BroadcastReceiver; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.net.Uri; -import android.os.Handler; +import android.test.mock.MockAccountManager; import java.io.File; -import java.io.IOException; import java.util.ArrayList; -import java.util.concurrent.TimeUnit; import java.util.List; @@ -52,7 +44,7 @@ import java.util.List; public class IsolatedContext extends ContextWrapper { private ContentResolver mResolver; - private final MockAccountManager mMockAccountManager; + private final AccountManager mMockAccountManager; private List<Intent> mBroadcastIntents = new ArrayList<>(); @@ -60,7 +52,7 @@ public class IsolatedContext extends ContextWrapper { ContentResolver resolver, Context targetContext) { super(targetContext); mResolver = resolver; - mMockAccountManager = new MockAccountManager(); + mMockAccountManager = MockAccountManager.newMockAccountManager(IsolatedContext.this); } /** Returns the list of intents that were broadcast since the last call to this method. */ @@ -123,71 +115,6 @@ public class IsolatedContext extends ContextWrapper { return null; } - private class MockAccountManager extends AccountManager { - public MockAccountManager() { - super(IsolatedContext.this, null /* IAccountManager */, null /* handler */); - } - - public void addOnAccountsUpdatedListener(OnAccountsUpdateListener listener, - Handler handler, boolean updateImmediately) { - // do nothing - } - - public Account[] getAccounts() { - return new Account[]{}; - } - - public AccountManagerFuture<Account[]> getAccountsByTypeAndFeatures( - final String type, final String[] features, - AccountManagerCallback<Account[]> callback, Handler handler) { - return new MockAccountManagerFuture<Account[]>(new Account[0]); - } - - public String blockingGetAuthToken(Account account, String authTokenType, - boolean notifyAuthFailure) - throws OperationCanceledException, IOException, AuthenticatorException { - return null; - } - - - /** - * A very simple AccountManagerFuture class - * that returns what ever was passed in - */ - private class MockAccountManagerFuture<T> - implements AccountManagerFuture<T> { - - T mResult; - - public MockAccountManagerFuture(T result) { - mResult = result; - } - - public boolean cancel(boolean mayInterruptIfRunning) { - return false; - } - - public boolean isCancelled() { - return false; - } - - public boolean isDone() { - return true; - } - - public T getResult() - throws OperationCanceledException, IOException, AuthenticatorException { - return mResult; - } - - public T getResult(long timeout, TimeUnit unit) - throws OperationCanceledException, IOException, AuthenticatorException { - return getResult(); - } - } - - } - @Override public File getFilesDir() { return new File("/dev/null"); diff --git a/test-runner/src/android/test/ProviderTestCase2.java b/test-runner/src/android/test/ProviderTestCase2.java index 1fa633e26961..be18b53059f3 100644 --- a/test-runner/src/android/test/ProviderTestCase2.java +++ b/test-runner/src/android/test/ProviderTestCase2.java @@ -21,6 +21,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.pm.ProviderInfo; import android.content.res.Resources; +import android.test.mock.MockContentProvider; import android.test.mock.MockContext; import android.test.mock.MockContentResolver; import android.database.DatabaseUtils; @@ -152,7 +153,7 @@ public abstract class ProviderTestCase2<T extends ContentProvider> extends Andro T instance = providerClass.newInstance(); ProviderInfo providerInfo = new ProviderInfo(); providerInfo.authority = authority; - instance.attachInfoForTesting(context, providerInfo); + MockContentProvider.attachInfoForTesting(instance, context, providerInfo); return instance; } diff --git a/test-runner/src/android/test/RenamingDelegatingContext.java b/test-runner/src/android/test/RenamingDelegatingContext.java index fd3332154611..10ccebc42dd0 100644 --- a/test-runner/src/android/test/RenamingDelegatingContext.java +++ b/test-runner/src/android/test/RenamingDelegatingContext.java @@ -21,6 +21,7 @@ import android.content.ContextWrapper; import android.content.ContentProvider; import android.database.DatabaseErrorHandler; import android.database.sqlite.SQLiteDatabase; +import android.test.mock.MockContentProvider; import android.util.Log; import java.io.File; @@ -71,7 +72,7 @@ public class RenamingDelegatingContext extends ContextWrapper { if (allowAccessToExistingFilesAndDbs) { mContext.makeExistingFilesAndDbsAccessible(); } - mProvider.attachInfoForTesting(mContext, null); + MockContentProvider.attachInfoForTesting(mProvider, mContext, null); return mProvider; } diff --git a/test-runner/src/android/test/ServiceTestCase.java b/test-runner/src/android/test/ServiceTestCase.java index c8ff0f904d6d..cd54955f22fa 100644 --- a/test-runner/src/android/test/ServiceTestCase.java +++ b/test-runner/src/android/test/ServiceTestCase.java @@ -23,6 +23,7 @@ import android.content.Intent; import android.os.IBinder; import android.test.mock.MockApplication; +import android.test.mock.MockService; import java.util.Random; /** @@ -163,14 +164,8 @@ public abstract class ServiceTestCase<T extends Service> extends AndroidTestCase if (getApplication() == null) { setApplication(new MockApplication()); } - mService.attach( - getContext(), - null, // ActivityThread not actually used in Service - mServiceClass.getName(), - null, // token not needed when not talking with the activity manager - getApplication(), - null // mocked services don't talk with the activity manager - ); + MockService.attachForTesting( + mService, getContext(), mServiceClass.getName(), getApplication()); assertNotNull(mService); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 6e643a3dae12..e7abede4cda4 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -318,6 +318,7 @@ public class ConnectivityServiceTest { // This test has an inherent race condition in it, and cannot be enabled for continuous testing // or presubmit tests. It is kept for manual runs and documentation purposes. + @Ignore public void verifyThatNotWaitingForIdleCausesRaceConditions() { // Bring up a network that we can use to send messages to ConnectivityService. ConditionVariable cv = waitForConnectivityBroadcasts(1); diff --git a/tools/sdkparcelables/src/com/android/sdkparcelables/AncestorCollector.kt b/tools/sdkparcelables/src/com/android/sdkparcelables/AncestorCollector.kt index f278aec8eb6f..d75aea507980 100644 --- a/tools/sdkparcelables/src/com/android/sdkparcelables/AncestorCollector.kt +++ b/tools/sdkparcelables/src/com/android/sdkparcelables/AncestorCollector.kt @@ -1,3 +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 com.android.sdkparcelables import org.objectweb.asm.ClassVisitor @@ -25,4 +41,4 @@ class AncestorCollector(api: Int, dest: ClassVisitor?) : ClassVisitor(api, dest) super.visit(version, access, name, signature, superName, interfaces) } -}
\ No newline at end of file +} diff --git a/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt b/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt index 3e9d92cd978f..22e8d781335b 100644 --- a/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt +++ b/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt @@ -1,3 +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 com.android.sdkparcelables import org.objectweb.asm.ClassReader @@ -53,4 +69,4 @@ fun main(args: Array<String>) { fun usage() { System.err.println("Usage: <input jar> <output aidl>") kotlin.system.exitProcess(1) -}
\ No newline at end of file +} diff --git a/tools/sdkparcelables/src/com/android/sdkparcelables/ParcelableDetector.kt b/tools/sdkparcelables/src/com/android/sdkparcelables/ParcelableDetector.kt index 620f798daf48..d6a0a4516a6d 100644 --- a/tools/sdkparcelables/src/com/android/sdkparcelables/ParcelableDetector.kt +++ b/tools/sdkparcelables/src/com/android/sdkparcelables/ParcelableDetector.kt @@ -1,3 +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 com.android.sdkparcelables /** A class that uses an ancestor map to find all classes that diff --git a/tools/sdkparcelables/tests/com/android/sdkparcelables/ParcelableDetectorTest.kt b/tools/sdkparcelables/tests/com/android/sdkparcelables/ParcelableDetectorTest.kt index edfc8259a738..c9bcbc9cadcf 100644 --- a/tools/sdkparcelables/tests/com/android/sdkparcelables/ParcelableDetectorTest.kt +++ b/tools/sdkparcelables/tests/com/android/sdkparcelables/ParcelableDetectorTest.kt @@ -1,3 +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 com.android.sdkparcelables import junit.framework.TestCase.assertEquals diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index b235ccc7a89e..8ac659f83b5e 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -599,6 +599,7 @@ public class WifiManagerTest { /** * Verify the watchLocalOnlyHotspot call goes to WifiServiceImpl. */ + @Test public void testWatchLocalOnlyHotspot() throws Exception { TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver(); |