diff --git a/Android.bp b/Android.bp index 69fb4597d088a..0cd985d045966 100644 --- a/Android.bp +++ b/Android.bp @@ -460,8 +460,8 @@ java_library { "telecomm/java/com/android/internal/telecom/IInCallService.aidl", "telecomm/java/com/android/internal/telecom/ITelecomService.aidl", "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/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", @@ -471,8 +471,7 @@ java_library { "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/ims/internal/aidl/IImsSmsListener.aidl", - "telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.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", @@ -496,6 +495,7 @@ java_library { "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/system-current.txt b/api/system-current.txt index 041c21324fb7b..0ac628e983360 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4044,6 +4044,24 @@ package android.telephony { public final class SmsManager { method public void sendMultipartTextMessageWithoutPersisting(java.lang.String, java.lang.String, java.util.List, java.util.List, java.util.List); method public void sendTextMessageWithoutPersisting(java.lang.String, java.lang.String, java.lang.String, android.app.PendingIntent, android.app.PendingIntent); + field public static final int RESULT_CANCELLED = 23; // 0x17 + field public static final int RESULT_ENCODING_ERROR = 18; // 0x12 + field public static final int RESULT_ERROR_FDN_CHECK_FAILURE = 6; // 0x6 + field public static final int RESULT_ERROR_NONE = 0; // 0x0 + field public static final int RESULT_INTERNAL_ERROR = 21; // 0x15 + field public static final int RESULT_INVALID_ARGUMENTS = 11; // 0xb + field public static final int RESULT_INVALID_SMSC_ADDRESS = 19; // 0x13 + field public static final int RESULT_INVALID_SMS_FORMAT = 14; // 0xe + field public static final int RESULT_INVALID_STATE = 12; // 0xc + field public static final int RESULT_MODEM_ERROR = 16; // 0x10 + field public static final int RESULT_NETWORK_ERROR = 17; // 0x11 + field public static final int RESULT_NETWORK_REJECT = 10; // 0xa + field public static final int RESULT_NO_MEMORY = 13; // 0xd + field public static final int RESULT_NO_RESOURCES = 22; // 0x16 + field public static final int RESULT_OPERATION_NOT_ALLOWED = 20; // 0x14 + field public static final int RESULT_RADIO_NOT_AVAILABLE = 9; // 0x9 + field public static final int RESULT_REQUEST_NOT_SUPPORTED = 24; // 0x18 + field public static final int RESULT_SYSTEM_ERROR = 15; // 0xf } public class SubscriptionManager { @@ -4287,6 +4305,30 @@ package android.telephony.ims { } +package android.telephony.ims.internal.stub { + + public class SmsImplBase { + ctor public SmsImplBase(); + method public void acknowledgeSms(int, int, int); + method public void acknowledgeSmsReport(int, int, int); + method public java.lang.String getSmsFormat(); + method public void onReady(); + method public final void onSendSmsResult(int, int, int, int) throws java.lang.RuntimeException; + method public final void onSmsReceived(int, java.lang.String, byte[]) throws java.lang.RuntimeException; + method public final void onSmsStatusReportReceived(int, int, java.lang.String, byte[]) throws java.lang.RuntimeException; + method public void sendSms(int, int, java.lang.String, java.lang.String, boolean, byte[]); + field public static final int DELIVER_STATUS_ERROR = 2; // 0x2 + field public static final int DELIVER_STATUS_OK = 1; // 0x1 + field public static final int SEND_STATUS_ERROR = 2; // 0x2 + field public static final int SEND_STATUS_ERROR_FALLBACK = 4; // 0x4 + field public static final int SEND_STATUS_ERROR_RETRY = 3; // 0x3 + field public static final int SEND_STATUS_OK = 1; // 0x1 + field public static final int STATUS_REPORT_STATUS_ERROR = 2; // 0x2 + field public static final int STATUS_REPORT_STATUS_OK = 1; // 0x1 + } + +} + package android.telephony.mbms { public final class DownloadRequest implements android.os.Parcelable { diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 78a4c654ba1a9..9a45e7b9cc36c 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -1127,7 +1127,11 @@ public final class SmsManager { // SMS send failure result codes - /** No error. {@hide}*/ + /** + * No error. + * @hide + */ + @SystemApi static public final int RESULT_ERROR_NONE = 0; /** Generic failure cause */ static public final int RESULT_ERROR_GENERIC_FAILURE = 1; @@ -1139,12 +1143,113 @@ public final class SmsManager { static public final int RESULT_ERROR_NO_SERVICE = 4; /** Failed because we reached the sending queue limit. */ static public final int RESULT_ERROR_LIMIT_EXCEEDED = 5; - /** Failed because FDN is enabled. {@hide} */ + /** + * Failed because FDN is enabled. + * @hide + */ + @SystemApi static public final int RESULT_ERROR_FDN_CHECK_FAILURE = 6; /** Failed because user denied the sending of this short code. */ static public final int RESULT_ERROR_SHORT_CODE_NOT_ALLOWED = 7; /** Failed because the user has denied this app ever send premium short codes. */ static public final int RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED = 8; + /** + * Failed because the radio was not available + * @hide + */ + @SystemApi + static public final int RESULT_RADIO_NOT_AVAILABLE = 9; + /** + * Failed because of network rejection + * @hide + */ + @SystemApi + static public final int RESULT_NETWORK_REJECT = 10; + /** + * Failed because of invalid arguments + * @hide + */ + @SystemApi + static public final int RESULT_INVALID_ARGUMENTS = 11; + /** + * Failed because of an invalid state + * @hide + */ + @SystemApi + static public final int RESULT_INVALID_STATE = 12; + /** + * Failed because there is no memory + * @hide + */ + @SystemApi + static public final int RESULT_NO_MEMORY = 13; + /** + * Failed because the sms format is not valid + * @hide + */ + @SystemApi + static public final int RESULT_INVALID_SMS_FORMAT = 14; + /** + * Failed because of a system error + * @hide + */ + @SystemApi + static public final int RESULT_SYSTEM_ERROR = 15; + /** + * Failed because of a modem error + * @hide + */ + @SystemApi + static public final int RESULT_MODEM_ERROR = 16; + /** + * Failed because of a network error + * @hide + */ + @SystemApi + static public final int RESULT_NETWORK_ERROR = 17; + /** + * Failed because of an encoding error + * @hide + */ + @SystemApi + static public final int RESULT_ENCODING_ERROR = 18; + /** + * Failed because of an invalid smsc address + * @hide + */ + @SystemApi + static public final int RESULT_INVALID_SMSC_ADDRESS = 19; + /** + * Failed because the operation is not allowed + * @hide + */ + @SystemApi + static public final int RESULT_OPERATION_NOT_ALLOWED = 20; + /** + * Failed because of an internal error + * @hide + */ + @SystemApi + static public final int RESULT_INTERNAL_ERROR = 21; + /** + * Failed because there are no resources + * @hide + */ + @SystemApi + static public final int RESULT_NO_RESOURCES = 22; + /** + * Failed because the operation was cancelled + * @hide + */ + @SystemApi + static public final int RESULT_CANCELLED = 23; + /** + * Failed because the request is not supported + * @hide + */ + @SystemApi + static public final int RESULT_REQUEST_NOT_SUPPORTED = 24; + static private final String PHONE_PACKAGE_NAME = "com.android.phone"; diff --git a/telephony/java/android/telephony/ims/feature/MMTelFeature.java b/telephony/java/android/telephony/ims/feature/MMTelFeature.java index 4e095e3a70033..93c316f3dcb91 100644 --- a/telephony/java/android/telephony/ims/feature/MMTelFeature.java +++ b/telephony/java/android/telephony/ims/feature/MMTelFeature.java @@ -19,6 +19,7 @@ package android.telephony.ims.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 com.android.ims.internal.IImsCallSession; @@ -28,6 +29,7 @@ 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; @@ -171,6 +173,49 @@ public class MMTelFeature extends ImsFeature { 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(); + } + } }; /** @@ -346,6 +391,43 @@ public class MMTelFeature extends ImsFeature { 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/SmsImplBase.java b/telephony/java/android/telephony/ims/internal/SmsImplBase.java deleted file mode 100644 index 47414cf73b953..0000000000000 --- a/telephony/java/android/telephony/ims/internal/SmsImplBase.java +++ /dev/null @@ -1,260 +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.annotation.IntDef; -import android.annotation.SystemApi; -import android.os.RemoteException; -import android.telephony.SmsManager; -import android.telephony.SmsMessage; -import android.telephony.ims.internal.aidl.IImsSmsListener; -import android.telephony.ims.internal.feature.MmTelFeature; -import android.util.Log; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Base implementation for SMS over IMS. - * - * Any service wishing to provide SMS over IMS should extend this class and implement all methods - * that the service supports. - * @hide - */ -public class SmsImplBase { - private static final String LOG_TAG = "SmsImplBase"; - - @IntDef({ - SEND_STATUS_OK, - SEND_STATUS_ERROR, - SEND_STATUS_ERROR_RETRY, - SEND_STATUS_ERROR_FALLBACK - }) - @Retention(RetentionPolicy.SOURCE) - public @interface SendStatusResult {} - /** - * Message was sent successfully. - */ - public static final int SEND_STATUS_OK = 1; - - /** - * IMS provider failed to send the message and platform should not retry falling back to sending - * the message using the radio. - */ - public static final int SEND_STATUS_ERROR = 2; - - /** - * IMS provider failed to send the message and platform should retry again after setting TP-RD bit - * to high. - */ - public static final int SEND_STATUS_ERROR_RETRY = 3; - - /** - * IMS provider failed to send the message and platform should retry falling back to sending - * the message using the radio. - */ - public static final int SEND_STATUS_ERROR_FALLBACK = 4; - - @IntDef({ - DELIVER_STATUS_OK, - DELIVER_STATUS_ERROR - }) - @Retention(RetentionPolicy.SOURCE) - public @interface DeliverStatusResult {} - /** - * Message was delivered successfully. - */ - public static final int DELIVER_STATUS_OK = 1; - - /** - * Message was not delivered. - */ - public static final int DELIVER_STATUS_ERROR = 2; - - @IntDef({ - STATUS_REPORT_STATUS_OK, - STATUS_REPORT_STATUS_ERROR - }) - @Retention(RetentionPolicy.SOURCE) - public @interface StatusReportResult {} - - /** - * Status Report was set successfully. - */ - public static final int STATUS_REPORT_STATUS_OK = 1; - - /** - * Error while setting status report. - */ - public static final int STATUS_REPORT_STATUS_ERROR = 2; - - - // Lock for feature synchronization - private final Object mLock = new Object(); - private IImsSmsListener mListener; - - /** - * Registers a listener responsible for handling tasks like delivering messages. - * - * @param listener listener to register. - * - * @hide - */ - public final void registerSmsListener(IImsSmsListener listener) { - synchronized (mLock) { - mListener = listener; - } - } - - /** - * This method will be triggered by the platform when the user attempts to send an SMS. This - * method should be implemented by the IMS providers to provide implementation of sending an SMS - * over IMS. - * - * @param smsc the Short Message Service Center address. - * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and - * {@link SmsMessage#FORMAT_3GPP2}. - * @param messageRef the message reference. - * @param isRetry whether it is a retry of an already attempted message or not. - * @param pdu PDUs representing the contents of the message. - */ - public void sendSms(int messageRef, String format, String smsc, boolean isRetry, byte[] pdu) { - // Base implementation returns error. Should be overridden. - try { - onSendSmsResult(messageRef, SEND_STATUS_ERROR, SmsManager.RESULT_ERROR_GENERIC_FAILURE); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Can not send sms: " + e.getMessage()); - } - } - - /** - * This method will be triggered by the platform after {@link #onSmsReceived(String, byte[])} has - * been called to deliver the result to the IMS provider. - * - * @param result result of delivering the message. Valid values are defined in - * {@link DeliverStatusResult} - * @param messageRef the message reference or -1 of unavailable. - */ - public void acknowledgeSms(int messageRef, @DeliverStatusResult int result) { - - } - - /** - * This method will be triggered by the platform after - * {@link #onSmsStatusReportReceived(int, int, byte[])} has been called to provide the result to - * the IMS provider. - * - * @param result result of delivering the message. Valid values are defined in - * {@link StatusReportResult} - * @param messageRef the message reference or -1 of unavailable. - */ - public void acknowledgeSmsReport(int messageRef, @StatusReportResult int result) { - - } - - /** - * This method should be triggered by the IMS providers when there is an incoming message. The - * platform will deliver the message to the messages database and notify the IMS provider of the - * result by calling {@link #acknowledgeSms(int, int)}. - * - * This method must not be called before {@link MmTelFeature#onFeatureReady()} is called. - * - * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and - * {@link SmsMessage#FORMAT_3GPP2}. - * @param pdu PDUs representing the contents of the message. - * @throws IllegalStateException if called before {@link MmTelFeature#onFeatureReady()} - */ - public final void onSmsReceived(String format, byte[] pdu) throws IllegalStateException { - synchronized (mLock) { - if (mListener == null) { - throw new IllegalStateException("Feature not ready."); - } - try { - mListener.onSmsReceived(format, pdu); - acknowledgeSms(-1, DELIVER_STATUS_OK); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Can not deliver sms: " + e.getMessage()); - acknowledgeSms(-1, DELIVER_STATUS_ERROR); - } - } - } - - /** - * This method should be triggered by the IMS providers to pass the result of the sent message - * to the platform. - * - * This method must not be called before {@link MmTelFeature#onFeatureReady()} is called. - * - * @param messageRef the message reference. Should be between 0 and 255 per TS.123.040 - * @param status result of sending the SMS. Valid values are defined in {@link SendStatusResult} - * @param reason reason in case status is failure. Valid values are: - * {@link SmsManager#RESULT_ERROR_NONE}, - * {@link SmsManager#RESULT_ERROR_GENERIC_FAILURE}, - * {@link SmsManager#RESULT_ERROR_RADIO_OFF}, - * {@link SmsManager#RESULT_ERROR_NULL_PDU}, - * {@link SmsManager#RESULT_ERROR_NO_SERVICE}, - * {@link SmsManager#RESULT_ERROR_LIMIT_EXCEEDED}, - * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NOT_ALLOWED}, - * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED} - * @throws IllegalStateException if called before {@link MmTelFeature#onFeatureReady()} - * @throws RemoteException if the connection to the framework is not available. If this happens - * attempting to send the SMS should be aborted. - */ - public final void onSendSmsResult(int messageRef, @SendStatusResult int status, int reason) - throws IllegalStateException, RemoteException { - synchronized (mLock) { - if (mListener == null) { - throw new IllegalStateException("Feature not ready."); - } - mListener.onSendSmsResult(messageRef, status, reason); - } - } - - /** - * Sets the status report of the sent message. - * - * @param messageRef the message reference. - * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and - * {@link SmsMessage#FORMAT_3GPP2}. - * @param pdu PDUs representing the content of the status report. - * @throws IllegalStateException if called before {@link MmTelFeature#onFeatureReady()} - */ - public final void onSmsStatusReportReceived(int messageRef, String format, byte[] pdu) { - synchronized (mLock) { - if (mListener == null) { - throw new IllegalStateException("Feature not ready."); - } - try { - mListener.onSmsStatusReportReceived(messageRef, format, pdu); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Can not process sms status report: " + e.getMessage()); - acknowledgeSmsReport(messageRef, STATUS_REPORT_STATUS_ERROR); - } - } - } - - /** - * Returns the SMS format. Default is {@link SmsMessage#FORMAT_3GPP} unless overridden by IMS - * Provider. - * - * @return the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and - * {@link SmsMessage#FORMAT_3GPP2}. - */ - public String getSmsFormat() { - return SmsMessage.FORMAT_3GPP; - } - -} diff --git a/telephony/java/android/telephony/ims/internal/aidl/IImsMmTelFeature.aidl b/telephony/java/android/telephony/ims/internal/aidl/IImsMmTelFeature.aidl index d976686750946..e226adaac07fb 100644 --- a/telephony/java/android/telephony/ims/internal/aidl/IImsMmTelFeature.aidl +++ b/telephony/java/android/telephony/ims/internal/aidl/IImsMmTelFeature.aidl @@ -18,7 +18,6 @@ package android.telephony.ims.internal.aidl; import android.os.Message; import android.telephony.ims.internal.aidl.IImsMmTelListener; -import android.telephony.ims.internal.aidl.IImsSmsListener; import android.telephony.ims.internal.aidl.IImsCapabilityCallback; import android.telephony.ims.internal.aidl.IImsCallSessionListener; import android.telephony.ims.internal.feature.CapabilityChangeRequest; @@ -50,10 +49,4 @@ interface IImsMmTelFeature { IImsCapabilityCallback c); oneway void queryCapabilityConfiguration(int capability, int radioTech, IImsCapabilityCallback c); - // SMS APIs - void setSmsListener(IImsSmsListener l); - oneway void sendSms(int messageRef, String format, String smsc, boolean retry, in byte[] pdu); - oneway void acknowledgeSms(int messageRef, int result); - oneway void acknowledgeSmsReport(int messageRef, int result); - String getSmsFormat(); } diff --git a/telephony/java/android/telephony/ims/internal/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/internal/feature/MmTelFeature.java index 057c9a86d04e5..9b576c72fa967 100644 --- a/telephony/java/android/telephony/ims/internal/feature/MmTelFeature.java +++ b/telephony/java/android/telephony/ims/internal/feature/MmTelFeature.java @@ -21,14 +21,10 @@ import android.os.Message; import android.os.RemoteException; import android.telecom.TelecomManager; import android.telephony.ims.internal.ImsCallSessionListener; -import android.telephony.ims.internal.SmsImplBase; -import android.telephony.ims.internal.SmsImplBase.DeliverStatusResult; -import android.telephony.ims.internal.SmsImplBase.StatusReportResult; 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.internal.aidl.IImsSmsListener; import android.telephony.ims.stub.ImsRegistrationImplBase; import android.telephony.ims.stub.ImsEcbmImplBase; import android.telephony.ims.stub.ImsMultiEndpointImplBase; @@ -67,11 +63,6 @@ public class MmTelFeature extends ImsFeature { } } - @Override - public void setSmsListener(IImsSmsListener l) throws RemoteException { - MmTelFeature.this.setSmsListener(l); - } - @Override public int getFeatureState() throws RemoteException { synchronized (mLock) { @@ -152,34 +143,6 @@ public class MmTelFeature extends ImsFeature { IImsCapabilityCallback c) { queryCapabilityConfigurationInternal(capability, radioTech, c); } - - @Override - public void sendSms(int messageRef, String format, String smsc, boolean retry, byte[] pdu) { - synchronized (mLock) { - MmTelFeature.this.sendSms(messageRef, format, smsc, retry, pdu); - } - } - - @Override - public void acknowledgeSms(int messageRef, int result) { - synchronized (mLock) { - MmTelFeature.this.acknowledgeSms(messageRef, result); - } - } - - @Override - public void acknowledgeSmsReport(int messageRef, int result) { - synchronized (mLock) { - MmTelFeature.this.acknowledgeSmsReport(messageRef, result); - } - } - - @Override - public String getSmsFormat() { - synchronized (mLock) { - return MmTelFeature.this.getSmsFormat(); - } - } }; /** @@ -291,10 +254,6 @@ public class MmTelFeature extends ImsFeature { } } - private void setSmsListener(IImsSmsListener listener) { - getSmsImplementation().registerSmsListener(listener); - } - private void queryCapabilityConfigurationInternal(int capability, int radioTech, IImsCapabilityCallback c) { boolean enabled = queryCapabilityConfiguration(capability, radioTech); @@ -456,32 +415,6 @@ public class MmTelFeature extends ImsFeature { // Base Implementation - Should be overridden } - private void sendSms(int messageRef, String format, String smsc, boolean isRetry, byte[] pdu) { - getSmsImplementation().sendSms(messageRef, format, smsc, isRetry, pdu); - } - - private void acknowledgeSms(int messageRef, @DeliverStatusResult int result) { - getSmsImplementation().acknowledgeSms(messageRef, result); - } - - private void acknowledgeSmsReport(int messageRef, @StatusReportResult int result) { - getSmsImplementation().acknowledgeSmsReport(messageRef, result); - } - - private String getSmsFormat() { - return getSmsImplementation().getSmsFormat(); - } - - /** - * 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(); - } - /**{@inheritDoc}*/ @Override public void onFeatureRemoved() { diff --git a/telephony/java/android/telephony/ims/internal/stub/SmsImplBase.java b/telephony/java/android/telephony/ims/internal/stub/SmsImplBase.java new file mode 100644 index 0000000000000..57df526b4a4e7 --- /dev/null +++ b/telephony/java/android/telephony/ims/internal/stub/SmsImplBase.java @@ -0,0 +1,313 @@ +/* + * 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.internal.stub; + +import android.annotation.IntDef; +import android.annotation.SystemApi; +import android.os.RemoteException; +import android.telephony.SmsManager; +import android.telephony.SmsMessage; +import android.util.Log; + +import com.android.ims.internal.IImsSmsListener; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Base implementation for SMS over IMS. + * + * Any service wishing to provide SMS over IMS should extend this class and implement all methods + * that the service supports. + * + * @hide + */ +@SystemApi +public class SmsImplBase { + private static final String LOG_TAG = "SmsImplBase"; + + /** @hide */ + @IntDef({ + SEND_STATUS_OK, + SEND_STATUS_ERROR, + SEND_STATUS_ERROR_RETRY, + SEND_STATUS_ERROR_FALLBACK + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SendStatusResult {} + /** + * Message was sent successfully. + */ + public static final int SEND_STATUS_OK = 1; + + /** + * IMS provider failed to send the message and platform should not retry falling back to sending + * the message using the radio. + */ + public static final int SEND_STATUS_ERROR = 2; + + /** + * IMS provider failed to send the message and platform should retry again after setting TP-RD + * bit to high. + */ + public static final int SEND_STATUS_ERROR_RETRY = 3; + + /** + * IMS provider failed to send the message and platform should retry falling back to sending + * the message using the radio. + */ + public static final int SEND_STATUS_ERROR_FALLBACK = 4; + + /** @hide */ + @IntDef({ + DELIVER_STATUS_OK, + DELIVER_STATUS_ERROR + }) + @Retention(RetentionPolicy.SOURCE) + public @interface DeliverStatusResult {} + /** + * Message was delivered successfully. + */ + public static final int DELIVER_STATUS_OK = 1; + + /** + * Message was not delivered. + */ + public static final int DELIVER_STATUS_ERROR = 2; + + /** @hide */ + @IntDef({ + STATUS_REPORT_STATUS_OK, + STATUS_REPORT_STATUS_ERROR + }) + @Retention(RetentionPolicy.SOURCE) + public @interface StatusReportResult {} + + /** + * Status Report was set successfully. + */ + public static final int STATUS_REPORT_STATUS_OK = 1; + + /** + * Error while setting status report. + */ + public static final int STATUS_REPORT_STATUS_ERROR = 2; + + + // Lock for feature synchronization + private final Object mLock = new Object(); + private IImsSmsListener mListener; + + /** + * Registers a listener responsible for handling tasks like delivering messages. + * + * @param listener listener to register. + * + * @hide + */ + public final void registerSmsListener(IImsSmsListener listener) { + synchronized (mLock) { + mListener = listener; + } + } + + /** + * This method will be triggered by the platform when the user attempts to send an SMS. This + * method should be implemented by the IMS providers to provide implementation of sending an SMS + * over IMS. + * + * @param token unique token generated by the platform that should be used when triggering + * callbacks for this specific message. + * @param messageRef the message reference. + * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and + * {@link SmsMessage#FORMAT_3GPP2}. + * @param smsc the Short Message Service Center address. + * @param isRetry whether it is a retry of an already attempted message or not. + * @param pdu PDUs representing the contents of the message. + */ + public void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry, + byte[] pdu) { + // Base implementation returns error. Should be overridden. + try { + onSendSmsResult(token, messageRef, SEND_STATUS_ERROR, + SmsManager.RESULT_ERROR_GENERIC_FAILURE); + } catch (RuntimeException e) { + Log.e(LOG_TAG, "Can not send sms: " + e.getMessage()); + } + } + + /** + * This method will be triggered by the platform after + * {@link #onSmsReceived(int, String, byte[])} has been called to deliver the result to the IMS + * provider. + * + * @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} + * @param messageRef the message reference + */ + public void acknowledgeSms(int token, @DeliverStatusResult int messageRef, int result) { + Log.e(LOG_TAG, "acknowledgeSms() not implemented."); + } + + /** + * This method will be triggered by the platform after + * {@link #onSmsStatusReportReceived(int, int, String, byte[])} has been called to provide the + * result to the IMS provider. + * + * @param token token provided in {@link #sendSms(int, int, String, String, boolean, byte[])} + * @param result result of delivering the message. Valid values are: + * {@link #STATUS_REPORT_STATUS_OK}, + * {@link #STATUS_REPORT_STATUS_ERROR} + * @param messageRef the message reference + */ + public void acknowledgeSmsReport(int token, int messageRef, @StatusReportResult int result) { + Log.e(LOG_TAG, "acknowledgeSmsReport() not implemented."); + } + + /** + * This method should be triggered by the IMS providers when there is an incoming message. The + * platform will deliver the message to the messages database and notify the IMS provider of the + * result by calling {@link #acknowledgeSms(int, int, int)}. + * + * This method must not be called before {@link #onReady()} is called. + * + * @param token unique token generated by IMS providers that the platform will use to trigger + * callbacks for this message. + * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and + * {@link SmsMessage#FORMAT_3GPP2}. + * @param pdu PDUs representing the contents of the message. + * @throws RuntimeException if called before {@link #onReady()} is triggered. + */ + public final void onSmsReceived(int token, String format, byte[] pdu) throws RuntimeException { + synchronized (mLock) { + if (mListener == null) { + throw new RuntimeException("Feature not ready."); + } + try { + mListener.onSmsReceived(token, format, pdu); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Can not deliver sms: " + e.getMessage()); + acknowledgeSms(token, 0, DELIVER_STATUS_ERROR); + } + } + } + + /** + * This method should be triggered by the IMS providers to pass the result of the sent message + * to the platform. + * + * This method must not be called before {@link #onReady()} is called. + * + * @param token token provided in {@link #sendSms(int, int, String, String, boolean, byte[])} + * @param messageRef the message reference. Should be between 0 and 255 per TS.123.040 + * @param status result of sending the SMS. Valid values are: + * {@link #SEND_STATUS_OK}, + * {@link #SEND_STATUS_ERROR}, + * {@link #SEND_STATUS_ERROR_RETRY}, + * {@link #SEND_STATUS_ERROR_FALLBACK}, + * @param reason reason in case status is failure. Valid values are: + * {@link SmsManager#RESULT_ERROR_NONE}, + * {@link SmsManager#RESULT_ERROR_GENERIC_FAILURE}, + * {@link SmsManager#RESULT_ERROR_RADIO_OFF}, + * {@link SmsManager#RESULT_ERROR_NULL_PDU}, + * {@link SmsManager#RESULT_ERROR_NO_SERVICE}, + * {@link SmsManager#RESULT_ERROR_LIMIT_EXCEEDED}, + * {@link SmsManager#RESULT_ERROR_FDN_CHECK_FAILURE}, + * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NOT_ALLOWED}, + * {@link SmsManager#RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED}, + * {@link SmsManager#RESULT_RADIO_NOT_AVAILABLE}, + * {@link SmsManager#RESULT_NETWORK_REJECT}, + * {@link SmsManager#RESULT_INVALID_ARGUMENTS}, + * {@link SmsManager#RESULT_INVALID_STATE}, + * {@link SmsManager#RESULT_NO_MEMORY}, + * {@link SmsManager#RESULT_INVALID_SMS_FORMAT}, + * {@link SmsManager#RESULT_SYSTEM_ERROR}, + * {@link SmsManager#RESULT_MODEM_ERROR}, + * {@link SmsManager#RESULT_NETWORK_ERROR}, + * {@link SmsManager#RESULT_ENCODING_ERROR}, + * {@link SmsManager#RESULT_INVALID_SMSC_ADDRESS}, + * {@link SmsManager#RESULT_OPERATION_NOT_ALLOWED}, + * {@link SmsManager#RESULT_INTERNAL_ERROR}, + * {@link SmsManager#RESULT_NO_RESOURCES}, + * {@link SmsManager#RESULT_CANCELLED}, + * {@link SmsManager#RESULT_REQUEST_NOT_SUPPORTED} + * + * @throws RuntimeException if called before {@link #onReady()} is triggered or if the + * connection to the framework is not available. If this happens attempting to send the SMS + * should be aborted. + */ + public final void onSendSmsResult(int token, int messageRef, @SendStatusResult int status, + int reason) throws RuntimeException { + synchronized (mLock) { + if (mListener == null) { + throw new RuntimeException("Feature not ready."); + } + try { + mListener.onSendSmsResult(token, messageRef, status, reason); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + } + + /** + * Sets the status report of the sent message. + * + * @param token token provided in {@link #sendSms(int, int, String, String, boolean, byte[])} + * @param messageRef the message reference. + * @param format the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and + * {@link SmsMessage#FORMAT_3GPP2}. + * @param pdu PDUs representing the content of the status report. + * @throws RuntimeException if called before {@link #onReady()} is triggered + */ + public final void onSmsStatusReportReceived(int token, int messageRef, String format, + byte[] pdu) throws RuntimeException{ + synchronized (mLock) { + if (mListener == null) { + throw new RuntimeException("Feature not ready."); + } + try { + mListener.onSmsStatusReportReceived(token, messageRef, format, pdu); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Can not process sms status report: " + e.getMessage()); + acknowledgeSmsReport(token, messageRef, STATUS_REPORT_STATUS_ERROR); + } + } + } + + /** + * Returns the SMS format. Default is {@link SmsMessage#FORMAT_3GPP} unless overridden by IMS + * Provider. + * + * @return the format of the message. Valid values are {@link SmsMessage#FORMAT_3GPP} and + * {@link SmsMessage#FORMAT_3GPP2}. + */ + public String getSmsFormat() { + return SmsMessage.FORMAT_3GPP; + } + + /** + * Called when SmsImpl 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}. + */ + public void onReady() { + // Base Implementation - Should be overridden + } +} diff --git a/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl b/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl index 52b3853ec5b6a..10c7f3e8a2d7b 100644 --- a/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl +++ b/telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl @@ -25,6 +25,7 @@ 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; @@ -53,4 +54,12 @@ 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/android/telephony/ims/internal/aidl/IImsSmsListener.aidl b/telephony/java/com/android/ims/internal/IImsSmsListener.aidl similarity index 67% rename from telephony/java/android/telephony/ims/internal/aidl/IImsSmsListener.aidl rename to telephony/java/com/android/ims/internal/IImsSmsListener.aidl index 468629ae0343d..5a4b7e4890251 100644 --- a/telephony/java/android/telephony/ims/internal/aidl/IImsSmsListener.aidl +++ b/telephony/java/com/android/ims/internal/IImsSmsListener.aidl @@ -14,14 +14,15 @@ * limitations under the License. */ -package android.telephony.ims.internal.aidl; +package com.android.ims.internal; /** - * See MMTelFeature for more information. + * See SmsImplBase for more information. * {@hide} */ interface IImsSmsListener { - void onSendSmsResult(in int messageRef, in int status, in int reason); - void onSmsStatusReportReceived(in int messageRef, in String format, in byte[] pdu); - void onSmsReceived(in String format, in byte[] pdu); + void onSendSmsResult(int token, int messageRef, int status, int reason); + void onSmsStatusReportReceived(int token, int messageRef, in String format, + in byte[] pdu); + void onSmsReceived(int token, in String format, in byte[] pdu); } \ No newline at end of file