diff options
9 files changed, 706 insertions, 59 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index 6fa5d8abce92..9f182b4db749 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5483,6 +5483,7 @@ package android.telephony.ims { } 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; @@ -5550,7 +5551,6 @@ package android.telephony.ims.feature { 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 final int getFeatureState(); method public abstract void onFeatureReady(); method public abstract void onFeatureRemoved(); method public final void setFeatureState(int); @@ -5579,10 +5579,12 @@ package android.telephony.ims.feature { 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 diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java index 52a6ab902d9a..7b7749102590 100644 --- a/telephony/java/android/telephony/ims/ImsReasonInfo.java +++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java @@ -421,13 +421,13 @@ public final class ImsReasonInfo implements Parcelable { // For main reason code /** @hide */ - public final int mCode; + public int mCode; // For the extra code value; it depends on the code value. /** @hide */ - public final int mExtraCode; + public int mExtraCode; // For the additional message of the reason info. /** @hide */ - public final String mExtraMessage; + public String mExtraMessage; /** @hide */ public ImsReasonInfo() { diff --git a/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java index e6f6f1b021f8..efaade825224 100644 --- a/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java +++ b/telephony/java/android/telephony/ims/ImsSuppServiceNotification.java @@ -46,6 +46,17 @@ public final class ImsSuppServiceNotification implements Parcelable { /** List of forwarded numbers, if any */ public final String[] history; + + 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) { notificationType = in.readInt(); diff --git a/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java b/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java index 7a1b1b218fab..d3d17f4fb198 100644 --- a/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java +++ b/telephony/java/android/telephony/ims/compat/feature/MMTelFeature.java @@ -22,6 +22,7 @@ import android.os.RemoteException; 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.IImsMMTelFeature; @@ -29,6 +30,10 @@ import com.android.ims.internal.IImsMultiEndpoint; import com.android.ims.internal.IImsRegistrationListener; import com.android.ims.internal.IImsUt; 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,7 +115,7 @@ public class MMTelFeature extends ImsFeature { public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile) throws RemoteException { synchronized (mLock) { - return MMTelFeature.this.createCallSession(sessionId, profile); + return MMTelFeature.this.createCallSession(sessionId, profile, null); } } @@ -125,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; } } @@ -153,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; } } @@ -167,7 +174,8 @@ public class MMTelFeature extends ImsFeature { @Override public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException { synchronized (mLock) { - return MMTelFeature.this.getMultiEndpointInterface(); + ImsMultiEndpointImplBase implBase = MMTelFeature.this.getMultiEndpointInterface(); + return implBase != null ? implBase.getIImsMultiEndpoint() : null; } } }; @@ -281,7 +289,8 @@ 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 */ - public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile) { + public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile, + IImsCallSessionListener listener) { return null; } @@ -298,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; } @@ -324,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; } @@ -339,7 +348,7 @@ public class MMTelFeature extends ImsFeature { /** * @return MultiEndpoint interface for DEP notifications */ - public IImsMultiEndpoint getMultiEndpointInterface() { + public ImsMultiEndpointImplBase getMultiEndpointInterface() { return null; } diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java index 48a5a75ad035..00cb1e25f66d 100644 --- a/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java +++ b/telephony/java/android/telephony/ims/compat/stub/ImsCallSessionImplBase.java @@ -16,16 +16,18 @@ package android.telephony.ims.compat.stub; +import android.os.Message; import android.os.RemoteException; -import android.telephony.ims.ImsCallSessionListener; 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.IImsCallSessionListener; +import com.android.ims.internal.IImsVideoCallProvider; + import android.telephony.ims.ImsCallSession; /** @@ -37,10 +39,12 @@ import android.telephony.ims.ImsCallSession; * @hide */ -public class ImsCallSessionImplBase extends android.telephony.ims.stub.ImsCallSessionImplBase { +public class ImsCallSessionImplBase extends IImsCallSession.Stub { @Override - public final void setListener(ImsCallSessionListener listener) { + // convert to old implementation of listener + public final void setListener(IImsCallSessionListener listener) + throws RemoteException { setListener(new ImsCallSessionListenerConverter(listener)); } @@ -51,8 +55,312 @@ public class ImsCallSessionImplBase extends android.telephony.ims.stub.ImsCallSe * * @param listener to listen to the session events of this object */ - public void setListener(IImsCallSessionListener listener) { + 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) { } /** @@ -61,11 +369,12 @@ public class ImsCallSessionImplBase extends android.telephony.ims.stub.ImsCallSe * "new" version of the Listener android.telephony.ims.ImsCallSessionListener when calling * back to the framework. */ - private class ImsCallSessionListenerConverter extends IImsCallSessionListener.Stub { + private class ImsCallSessionListenerConverter + extends com.android.ims.internal.IImsCallSessionListener.Stub { - private final ImsCallSessionListener mNewListener; + private final IImsCallSessionListener mNewListener; - public ImsCallSessionListenerConverter(ImsCallSessionListener listener) { + public ImsCallSessionListenerConverter(IImsCallSessionListener listener) { mNewListener = listener; } diff --git a/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java index b5417e77c008..2c325ba8e134 100644 --- a/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java +++ b/telephony/java/android/telephony/ims/compat/stub/ImsConfigImplBase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * 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. @@ -16,15 +16,23 @@ 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, which implements stub versions of the methods - * in the IImsConfig AIDL. Override the methods that your implementation of ImsConfig supports. + * 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. @@ -34,10 +42,25 @@ import com.android.ims.internal.IImsConfig; * 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 extends IImsConfig.Stub { +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 @@ -46,7 +69,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub { * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. * @return value in Integer format. */ - @Override public int getProvisionedValue(int item) throws RemoteException { return -1; } @@ -58,7 +80,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub { * @param item, as defined in com.android.ims.ImsConfig#ConfigConstants. * @return value in String format. */ - @Override public String getProvisionedStringValue(int item) throws RemoteException { return null; } @@ -72,7 +93,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub { * @param value in Integer format. * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants. */ - @Override public int setProvisionedValue(int item, int value) throws RemoteException { return ImsConfig.OperationStatusConstants.FAILED; } @@ -86,7 +106,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub { * @param value in String format. * @return as defined in com.android.ims.ImsConfig#OperationStatusConstants. */ - @Override public int setProvisionedStringValue(int item, String value) throws RemoteException { return ImsConfig.OperationStatusConstants.FAILED; } @@ -100,7 +119,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub { * @param network as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX. * @param listener feature value returned asynchronously through listener. */ - @Override public void getFeatureValue(int feature, int network, ImsConfigListener listener) throws RemoteException { } @@ -115,7 +133,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub { * @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 { } @@ -124,7 +141,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub { * Gets the value for IMS VoLTE provisioned. * This should be the same as the operator provisioned value if applies. */ - @Override public boolean getVolteProvisioned() throws RemoteException { return false; } @@ -134,7 +150,6 @@ public class ImsConfigImplBase extends IImsConfig.Stub { * * @param listener Video quality value returned asynchronously through listener. */ - @Override public void getVideoQuality(ImsConfigListener listener) throws RemoteException { } @@ -144,7 +159,233 @@ public class ImsConfigImplBase extends IImsConfig.Stub { * @param quality, defines the value of video quality. * @param listener, provided if caller needs to be notified for set result. */ - @Override 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/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java index a23ce6316a94..bfdd4533275b 100644 --- a/telephony/java/android/telephony/ims/feature/ImsFeature.java +++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java @@ -363,8 +363,9 @@ public abstract class ImsFeature { /** * @return The current state of the feature, defined as {@link #STATE_UNAVAILABLE}, * {@link #STATE_INITIALIZING}, or {@link #STATE_READY}. + * @hide */ - public final int getFeatureState() { + public int getFeatureState() { synchronized (mLock) { return mState; } @@ -489,7 +490,7 @@ public abstract class ImsFeature { */ @VisibleForTesting public final void requestChangeEnabledCapabilities(CapabilityChangeRequest request, - IImsCapabilityCallback c) throws RemoteException { + IImsCapabilityCallback c) { if (request == null) { throw new IllegalArgumentException( "ImsFeature#requestChangeEnabledCapabilities called with invalid params."); diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java index 2baf076d391f..09267fc2554c 100644 --- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java +++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java @@ -70,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()); + } } } @@ -79,15 +83,18 @@ 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) { - ImsCallSessionImplBase s = MmTelFeature.this.createCallSession(profile); - return s != null ? s.getServiceImpl() : null; + return createCallSessionInterface(profile); } } @@ -101,30 +108,32 @@ public class MmTelFeature extends ImsFeature { @Override public IImsUt getUtInterface() throws RemoteException { synchronized (mLock) { - return MmTelFeature.this.getUt().getInterface(); + return MmTelFeature.this.getUtInterface(); } } @Override public IImsEcbm getEcbmInterface() throws RemoteException { synchronized (mLock) { - ImsEcbmImplBase ecbm = MmTelFeature.this.getEcbm(); - return ecbm != null ? ecbm.getImsEcbm() : null; + 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) { - ImsMultiEndpointImplBase multiEndPoint = MmTelFeature.this.getMultiEndpoint(); - return multiEndPoint != null ? multiEndPoint.getIImsMultiEndpoint() : null; + return MmTelFeature.this.getMultiEndpointInterface(); } } @@ -317,18 +326,18 @@ public class MmTelFeature extends ImsFeature { } /** - * To be returned by {@link #shouldProcessCall(Uri[])} when the ImsService should process the + * 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(Uri[])} when the telephony framework should not - * process the outgoing NON_EMERGENCY call as IMS and should instead use circuit switch. + * 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(Uri[])} when the telephony framework should not - * process the outgoing EMERGENCY call as IMS and should instead use circuit switch. + * 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; @@ -401,10 +410,7 @@ public class MmTelFeature extends ImsFeature { /** * Notify the framework of an incoming call. * @param c The {@link ImsCallSessionImplBase} of the new incoming call. - * - * @throws RuntimeException 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. - * */ + */ public final void notifyIncomingCall(ImsCallSessionImplBase c, Bundle extras) { synchronized (mLock) { if (mListener == null) { @@ -419,6 +425,40 @@ public class MmTelFeature extends ImsFeature { } /** + * + * @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."); + } + try { + mListener.onVoiceMessageCountUpdate(count); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + } + + /** * Provides the MmTelFeature with the ability to return the framework Capability Configuration * for a provided Capability. If the framework calls {@link #changeEnabledCapabilities} and * includes a capability A to enable or disable, this method should return the correct enabled @@ -474,6 +514,15 @@ 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. @@ -489,7 +538,7 @@ public class MmTelFeature extends ImsFeature { * 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 Strings}s listed in the case when we want to place an outgoing + * 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. @@ -499,6 +548,31 @@ public class MmTelFeature extends ImsFeature { } /** + * + * @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. */ @@ -534,7 +608,7 @@ 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 } diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java index 412bef0cc089..dcd7ea714f8c 100644 --- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java @@ -148,7 +148,7 @@ public class ImsConfigImplBase { mProvisionedIntValue.remove(item); int retVal = getImsConfigImpl().setConfig(item, value); if (retVal == ImsConfig.OperationStatusConstants.SUCCESS) { - updateCachedValue(item, retVal, true); + updateCachedValue(item, value, true); } else { Log.d(TAG, "Set provision value of " + item + " to " + value + " failed with error code " + retVal); @@ -174,7 +174,7 @@ public class ImsConfigImplBase { mProvisionedStringValue.remove(item); int retVal = getImsConfigImpl().setConfig(item, value); if (retVal == ImsConfig.OperationStatusConstants.SUCCESS) { - updateCachedValue(item, retVal, true); + updateCachedValue(item, value, true); } return retVal; |