From 24c01a2f792032ac48b61de25f6ad4707b35f4d8 Mon Sep 17 00:00:00 2001 From: Amit Mahajan <amitmahajan@google.com> Date: Fri, 20 Sep 2019 11:13:05 -0700 Subject: [PATCH] Remove unused @hide APIs from SmsManager. Also created a new MmsManager and moved imms APIs there. Will make MmsManager @SystemApi in a later CL. Test: basic sanity Bug: 140763963 Change-Id: If22a85887c1aae0ab80562d58bc08c6965fd470f --- .../java/android/telephony/MmsManager.java | 118 +++ .../java/android/telephony/SmsManager.java | 874 +++--------------- .../internal/telephony/SmsApplication.java | 4 - 3 files changed, 229 insertions(+), 767 deletions(-) create mode 100644 telephony/java/android/telephony/MmsManager.java diff --git a/telephony/java/android/telephony/MmsManager.java b/telephony/java/android/telephony/MmsManager.java new file mode 100644 index 0000000000000..4bcf046916524 --- /dev/null +++ b/telephony/java/android/telephony/MmsManager.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +import android.app.ActivityThread; +import android.app.PendingIntent; +import android.net.Uri; +import android.os.Bundle; +import android.os.RemoteException; +import android.os.ServiceManager; + +import com.android.internal.telephony.IMms; + +/** + * Manages MMS operations such as sending multimedia messages. + * Get this object by calling the static method {@link #getInstance()}. + * @hide + */ +public class MmsManager { + private static final String TAG = "MmsManager"; + + /** Singleton object constructed during class initialization. */ + private static final MmsManager sInstance = new MmsManager(); + + /** + * Get the MmsManager singleton instance. + * + * @return the {@link MmsManager} singleton instance. + */ + public static MmsManager getInstance() { + return sInstance; + } + + /** + * Send an MMS message + * + * @param subId the subscription id + * @param contentUri the content Uri from which the message pdu will be read + * @param locationUrl the optional location url where message should be sent to + * @param configOverrides the carrier-specific messaging configuration values to override for + * sending the message. + * @param sentIntent if not NULL this <code>PendingIntent</code> is broadcast when the message + * is successfully sent, or failed + */ + public void sendMultimediaMessage(int subId, Uri contentUri, String locationUrl, + Bundle configOverrides, PendingIntent sentIntent) { + try { + final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); + if (iMms == null) { + return; + } + + iMms.sendMessage(subId, ActivityThread.currentPackageName(), contentUri, + locationUrl, configOverrides, sentIntent); + } catch (RemoteException e) { + // Ignore it + } + } + + /** + * Download an MMS message from carrier by a given location URL + * + * @param subId the subscription id + * @param locationUrl the location URL of the MMS message to be downloaded, usually obtained + * from the MMS WAP push notification + * @param contentUri the content uri to which the downloaded pdu will be written + * @param configOverrides the carrier-specific messaging configuration values to override for + * downloading the message. + * @param downloadedIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is downloaded, or the download is failed + * @throws IllegalArgumentException if locationUrl or contentUri is empty + */ + public void downloadMultimediaMessage(int subId, String locationUrl, Uri contentUri, + Bundle configOverrides, PendingIntent downloadedIntent) { + try { + final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); + if (iMms == null) { + return; + } + iMms.downloadMessage(subId, ActivityThread.currentPackageName(), + locationUrl, contentUri, configOverrides, downloadedIntent); + } catch (RemoteException e) { + // Ignore it + } + } + + /** + * Get carrier-dependent configuration values. + * + * @param subId the subscription id + * @return bundle key/values pairs of configuration values + */ + public Bundle getCarrierConfigValues(int subId) { + try { + IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); + if (iMms != null) { + return iMms.getCarrierConfigValues(subId); + } + } catch (RemoteException ex) { + // ignore it + } + return null; + } +} diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 8c14cb444d89e..5c39da7003a91 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -27,7 +27,6 @@ import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.app.ActivityThread; import android.app.PendingIntent; -import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; @@ -45,7 +44,6 @@ import android.util.ArrayMap; import android.util.Log; import com.android.internal.telephony.IIntegerConsumer; -import com.android.internal.telephony.IMms; import com.android.internal.telephony.ISms; import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.SmsRawData; @@ -357,6 +355,68 @@ public final class SmsManager { true /* persistMessage*/, ActivityThread.currentPackageName()); } + /** + * Send a text based SMS with messaging options. + * + * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this + * manager on a multi-SIM device, this operation may fail sending the SMS message because no + * suitable default subscription could be found. In this case, if {@code sentIntent} is + * non-null, then the {@link PendingIntent} will be sent with an error code + * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the + * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions + * where this operation may fail. + * </p> + * + * @param destinationAddress the address to send the message to + * @param scAddress is the service center address or null to use + * the current default SMSC + * @param text the body of the message to send + * @param sentIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is successfully sent, or failed. + * The result code will be <code>Activity.RESULT_OK</code> for success, + * or one of these errors:<br> + * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> + * <code>RESULT_ERROR_RADIO_OFF</code><br> + * <code>RESULT_ERROR_NULL_PDU</code><br> + * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include + * the extra "errorCode" containing a radio technology specific value, + * generally only useful for troubleshooting.<br> + * The per-application based SMS control checks sentIntent. If sentIntent + * is NULL the caller will be checked against all unknown applications, + * which cause smaller number of SMS to be sent in checking period. + * @param deliveryIntent if not NULL this <code>PendingIntent</code> is + * broadcast when the message is delivered to the recipient. The + * raw pdu of the status report is in the extended data ("pdu"). + * @param priority Priority level of the message + * Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1 + * --------------------------------- + * PRIORITY | Level of Priority + * --------------------------------- + * '00' | Normal + * '01' | Interactive + * '10' | Urgent + * '11' | Emergency + * ---------------------------------- + * Any Other values included Negative considered as Invalid Priority Indicator of the message. + * @param expectMore is a boolean to indicate the sending messages through same link or not. + * @param validityPeriod Validity Period of the message in mins. + * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1. + * Validity Period(Minimum) -> 5 mins + * Validity Period(Maximum) -> 635040 mins(i.e.63 weeks). + * Any Other values included Negative considered as Invalid Validity Period of the message. + * + * @throws IllegalArgumentException if destinationAddress or text are empty + * {@hide} + */ + @UnsupportedAppUsage + public void sendTextMessage( + String destinationAddress, String scAddress, String text, + PendingIntent sentIntent, PendingIntent deliveryIntent, + int priority, boolean expectMore, int validityPeriod) { + sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, + true /* persistMessage*/, priority, expectMore, validityPeriod); + } + private void sendTextMessageInternal(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, String packageName) { @@ -455,109 +515,6 @@ public final class SmsManager { false /* persistMessage */, ActivityThread.currentPackageName()); } - /** - * A variant of {@link SmsManager#sendTextMessage} that allows self to be the caller. This is - * for internal use only. - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier - * applications or the Telephony framework and will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the SMS being sent on the subscription associated with logical - * slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the - * correct subscription. - * </p> - * - * @param persistMessage whether to persist the sent message in the SMS app. the caller must be - * the Phone process if set to false. - * - * @hide - */ - public void sendTextMessageWithSelfPermissions( - String destinationAddress, String scAddress, String text, - PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage) { - if (TextUtils.isEmpty(destinationAddress)) { - throw new IllegalArgumentException("Invalid destinationAddress"); - } - - if (TextUtils.isEmpty(text)) { - throw new IllegalArgumentException("Invalid message body"); - } - - try { - ISms iSms = getISmsServiceOrThrow(); - iSms.sendTextForSubscriberWithSelfPermissions(getSubscriptionId(), - ActivityThread.currentPackageName(), - destinationAddress, - scAddress, text, sentIntent, deliveryIntent, persistMessage); - } catch (RemoteException ex) { - notifySmsGenericError(sentIntent); - } - } - - /** - * Send a text based SMS with messaging options. - * - * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this - * manager on a multi-SIM device, this operation may fail sending the SMS message because no - * suitable default subscription could be found. In this case, if {@code sentIntent} is - * non-null, then the {@link PendingIntent} will be sent with an error code - * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the - * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions - * where this operation may fail. - * </p> - * - * @param destinationAddress the address to send the message to - * @param scAddress is the service center address or null to use - * the current default SMSC - * @param text the body of the message to send - * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is successfully sent, or failed. - * The result code will be <code>Activity.RESULT_OK</code> for success, - * or one of these errors:<br> - * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> - * <code>RESULT_ERROR_RADIO_OFF</code><br> - * <code>RESULT_ERROR_NULL_PDU</code><br> - * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.<br> - * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applications, - * which cause smaller number of SMS to be sent in checking period. - * @param deliveryIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - * @param priority Priority level of the message - * Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1 - * --------------------------------- - * PRIORITY | Level of Priority - * --------------------------------- - * '00' | Normal - * '01' | Interactive - * '10' | Urgent - * '11' | Emergency - * ---------------------------------- - * Any Other values included Negative considered as Invalid Priority Indicator of the message. - * @param expectMore is a boolean to indicate the sending messages through same link or not. - * @param validityPeriod Validity Period of the message in mins. - * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1. - * Validity Period(Minimum) -> 5 mins - * Validity Period(Maximum) -> 635040 mins(i.e.63 weeks). - * Any Other values included Negative considered as Invalid Validity Period of the message. - * - * @throws IllegalArgumentException if destinationAddress or text are empty - * {@hide} - */ - @UnsupportedAppUsage - public void sendTextMessage( - String destinationAddress, String scAddress, String text, - PendingIntent sentIntent, PendingIntent deliveryIntent, - int priority, boolean expectMore, int validityPeriod) { - sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, - true /* persistMessage*/, priority, expectMore, validityPeriod); - } - private void sendTextMessageInternal( String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, @@ -1077,37 +1034,6 @@ public final class SmsManager { } } - /** - * Send a multi-part text based SMS without writing it into the SMS Provider. - * - * <p>Requires Permission: - * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or the calling app has carrier - * privileges. - * </p> - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use the Telephony - * framework and will never trigger an SMS disambiguation dialog. If this method is called on a - * device that has multiple active subscriptions, this {@link SmsManager} instance has been - * created with {@link #getDefault()}, and no user-defined default subscription is defined, the - * subscription ID associated with this message will be INVALID, which will result in the SMS - * being sent on the subscription associated with logical slot 0. Use - * {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the correct - * subscription. - * </p> - * - * @see #sendMultipartTextMessage(String, String, ArrayList, ArrayList, - * ArrayList, int, boolean, int) - * @hide - **/ - public void sendMultipartTextMessageWithoutPersisting( - String destinationAddress, String scAddress, List<String> parts, - List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, - int priority, boolean expectMore, int validityPeriod) { - sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents, - deliveryIntents, false /* persistMessage*/, priority, expectMore, - validityPeriod); - } - /** * Send a data based SMS to a specific application port. * @@ -1179,45 +1105,6 @@ public final class SmsManager { }); } - /** - * A variant of {@link SmsManager#sendDataMessage} that allows self to be the caller. This is - * for internal use only. - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier - * applications or the Telephony framework and will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the SMS being sent on the subscription associated with logical - * slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the - * correct subscription. - * </p> - * - * @hide - */ - public void sendDataMessageWithSelfPermissions( - String destinationAddress, String scAddress, short destinationPort, - byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) { - if (TextUtils.isEmpty(destinationAddress)) { - throw new IllegalArgumentException("Invalid destinationAddress"); - } - - if (data == null || data.length == 0) { - throw new IllegalArgumentException("Invalid message data"); - } - - try { - ISms iSms = getISmsServiceOrThrow(); - iSms.sendDataForSubscriberWithSelfPermissions(getSubscriptionId(), - ActivityThread.currentPackageName(), destinationAddress, scAddress, - destinationPort & 0xFFFF, data, sentIntent, deliveryIntent); - } catch (RemoteException e) { - Log.e(TAG, "sendDataMessageWithSelfPermissions: Couldn't send SMS - Exception: " - + e.getMessage()); - notifySmsGenericError(sentIntent); - } - } - /** * Get the SmsManager associated with the default subscription id. The instance will always be * associated with the default subscription id, even if the default subscription id changes. @@ -1650,9 +1537,9 @@ public final class SmsManager { /** * Enable reception of cell broadcast (SMS-CB) messages with the given - * message identifier and RAN type. The RAN type specify this message ID - * belong to 3GPP (GSM) or 3GPP2(CDMA).Note that if two different clients - * enable the same message identifier, they must both disable it for the device to stop + * message identifier range and RAN type. The RAN type specifies if this message ID + * belongs to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients enable + * the same message identifier, they must both disable it for the device to stop * receiving those messages. All received messages will be broadcast in an * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED". * Note: This call is blocking, callers may want to avoid calling it from @@ -1663,30 +1550,41 @@ public final class SmsManager { * dialog. If this method is called on a device that has multiple active subscriptions, this * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the operation being completed on the subscription associated - * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the - * operation is performed on the correct subscription. + * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}, which will result in the operation + * being completed on the subscription associated with logical slot 0. Use + * {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation is performed on the + * correct subscription. * </p> * - * @param messageIdentifier Message identifier as specified in TS 23.041 (3GPP) + * <p>Requires {@link android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST}</p> + * + * @param startMessageId first message identifier as specified in TS 23.041 (3GPP) + * or C.R1001-G (3GPP2) + * @param endMessageId last message identifier as specified in TS 23.041 (3GPP) * or C.R1001-G (3GPP2) - * @param ranType the message format as defined in {@link SmsCbMessage] - * @return true if successful, false otherwise - * @see #disableCellBroadcast(int, int) + * @param ranType the message format as defined in {@link SmsCbMessage} + * @return true if successful, false if the modem reports a failure (e.g. the given range or + * RAN type is invalid). + * @see #disableCellBroadcastRange(int, int, int) * + * @throws IllegalArgumentException if endMessageId < startMessageId * {@hide} */ - public boolean enableCellBroadcast(int messageIdentifier, + @SystemApi + public boolean enableCellBroadcastRange(int startMessageId, int endMessageId, @android.telephony.SmsCbMessage.MessageFormat int ranType) { boolean success = false; + if (endMessageId < startMessageId) { + throw new IllegalArgumentException("endMessageId < startMessageId"); + } try { ISms iSms = getISmsService(); if (iSms != null) { // If getSubscriptionId() returns INVALID or an inactive subscription, we will use // the default phone internally. - success = iSms.enableCellBroadcastForSubscriber(getSubscriptionId(), - messageIdentifier, ranType); + success = iSms.enableCellBroadcastRangeForSubscriber(getSubscriptionId(), + startMessageId, endMessageId, ranType); } } catch (RemoteException ex) { // ignore it @@ -1697,10 +1595,10 @@ public final class SmsManager { /** * Disable reception of cell broadcast (SMS-CB) messages with the given - * message identifier and RAN type. The RAN type specify this message ID - * belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients - * enable the same message identifier, they must both disable it for the - * device to stop receiving those messages. + * message identifier range and RAN type. The RAN type specify this message + * ID range belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different + * clients enable the same message identifier, they must both disable it for + * the device to stop receiving those messages. * Note: This call is blocking, callers may want to avoid calling it from * the main thread of an application. * @@ -1714,128 +1612,23 @@ public final class SmsManager { * operation is performed on the correct subscription. * </p> * - * @param messageIdentifier Message identifier as specified in TS 23.041 (3GPP) + * <p>Requires {@link android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST}</p> + * + * @param startMessageId first message identifier as specified in TS 23.041 (3GPP) + * or C.R1001-G (3GPP2) + * @param endMessageId last message identifier as specified in TS 23.041 (3GPP) * or C.R1001-G (3GPP2) * @param ranType the message format as defined in {@link SmsCbMessage} - * @return true if successful, false otherwise + * @return true if successful, false if the modem reports a failure (e.g. the given range or + * RAN type is invalid). * - * @see #enableCellBroadcast(int, int) + * @see #enableCellBroadcastRange(int, int, int) * + * @throws IllegalArgumentException if endMessageId < startMessageId * {@hide} */ - public boolean disableCellBroadcast(int messageIdentifier, - @android.telephony.SmsCbMessage.MessageFormat int ranType) { - boolean success = false; - - try { - ISms iSms = getISmsService(); - if (iSms != null) { - // If getSubscriptionId() returns INVALID or an inactive subscription, we will use - // the default phone internally. - success = iSms.disableCellBroadcastForSubscriber(getSubscriptionId(), - messageIdentifier, ranType); - } - } catch (RemoteException ex) { - // ignore it - } - - return success; - } - - /** - * Enable reception of cell broadcast (SMS-CB) messages with the given - * message identifier range and RAN type. The RAN type specifies if this message ID - * belongs to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients enable - * the same message identifier, they must both disable it for the device to stop - * receiving those messages. All received messages will be broadcast in an - * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED". - * Note: This call is blocking, callers may want to avoid calling it from - * the main thread of an application. - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier - * applications or the Telephony framework and will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}, which will result in the operation - * being completed on the subscription associated with logical slot 0. Use - * {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation is performed on the - * correct subscription. - * </p> - * - * <p>Requires {@link android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST}</p> - * - * @param startMessageId first message identifier as specified in TS 23.041 (3GPP) - * or C.R1001-G (3GPP2) - * @param endMessageId last message identifier as specified in TS 23.041 (3GPP) - * or C.R1001-G (3GPP2) - * @param ranType the message format as defined in {@link SmsCbMessage} - * @return true if successful, false if the modem reports a failure (e.g. the given range or - * RAN type is invalid). - * @see #disableCellBroadcastRange(int, int, int) - * - * @throws IllegalArgumentException if endMessageId < startMessageId - * {@hide} - */ - @SystemApi - public boolean enableCellBroadcastRange(int startMessageId, int endMessageId, - @android.telephony.SmsCbMessage.MessageFormat int ranType) { - boolean success = false; - - if (endMessageId < startMessageId) { - throw new IllegalArgumentException("endMessageId < startMessageId"); - } - try { - ISms iSms = getISmsService(); - if (iSms != null) { - // If getSubscriptionId() returns INVALID or an inactive subscription, we will use - // the default phone internally. - success = iSms.enableCellBroadcastRangeForSubscriber(getSubscriptionId(), - startMessageId, endMessageId, ranType); - } - } catch (RemoteException ex) { - // ignore it - } - - return success; - } - - /** - * Disable reception of cell broadcast (SMS-CB) messages with the given - * message identifier range and RAN type. The RAN type specify this message - * ID range belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different - * clients enable the same message identifier, they must both disable it for - * the device to stop receiving those messages. - * Note: This call is blocking, callers may want to avoid calling it from - * the main thread of an application. - * - * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier - * applications or the Telephony framework and will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the operation being completed on the subscription associated - * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the - * operation is performed on the correct subscription. - * </p> - * - * <p>Requires {@link android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST}</p> - * - * @param startMessageId first message identifier as specified in TS 23.041 (3GPP) - * or C.R1001-G (3GPP2) - * @param endMessageId last message identifier as specified in TS 23.041 (3GPP) - * or C.R1001-G (3GPP2) - * @param ranType the message format as defined in {@link SmsCbMessage} - * @return true if successful, false if the modem reports a failure (e.g. the given range or - * RAN type is invalid). - * - * @see #enableCellBroadcastRange(int, int, int) - * - * @throws IllegalArgumentException if endMessageId < startMessageId - * {@hide} - */ - @SystemApi - public boolean disableCellBroadcastRange(int startMessageId, int endMessageId, + @SystemApi + public boolean disableCellBroadcastRange(int startMessageId, int endMessageId, @android.telephony.SmsCbMessage.MessageFormat int ranType) { boolean success = false; @@ -2144,9 +1937,6 @@ public final class SmsManager { @SystemApi static public final int RESULT_REQUEST_NOT_SUPPORTED = 24; - - static private final String PHONE_PACKAGE_NAME = "com.android.phone"; - /** * Send an MMS message * @@ -2173,17 +1963,8 @@ public final class SmsManager { if (contentUri == null) { throw new IllegalArgumentException("Uri contentUri null"); } - try { - final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms == null) { - return; - } - - iMms.sendMessage(getSubscriptionId(), ActivityThread.currentPackageName(), contentUri, + MmsManager.getInstance().sendMultimediaMessage(getSubscriptionId(), contentUri, locationUrl, configOverrides, sentIntent); - } catch (RemoteException e) { - // Ignore it - } } /** @@ -2216,16 +1997,8 @@ public final class SmsManager { if (contentUri == null) { throw new IllegalArgumentException("Uri contentUri null"); } - try { - final IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms == null) { - return; - } - iMms.downloadMessage(getSubscriptionId(), ActivityThread.currentPackageName(), - locationUrl, contentUri, configOverrides, downloadedIntent); - } catch (RemoteException e) { - // Ignore it - } + MmsManager.getInstance().downloadMultimediaMessage(getSubscriptionId(), locationUrl, + contentUri, configOverrides, downloadedIntent); } // MMS send/download failure result codes @@ -2243,433 +2016,16 @@ public final class SmsManager { /** Intent extra name for HTTP status code for MMS HTTP failure in integer type */ public static final String EXTRA_MMS_HTTP_STATUS = "android.telephony.extra.MMS_HTTP_STATUS"; - /** - * Import a text message into system's SMS store - * - * Only default SMS apps can import SMS - * - * @param address the destination(source) address of the sent(received) message - * @param type the type of the message - * @param text the message text - * @param timestampMillis the message timestamp in milliseconds - * @param seen if the message is seen - * @param read if the message is read - * @return the message URI, null if failed - * @hide - */ - public Uri importTextMessage(String address, int type, String text, long timestampMillis, - boolean seen, boolean read) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.importTextMessage(ActivityThread.currentPackageName(), - address, type, text, timestampMillis, seen, read); - } - } catch (RemoteException ex) { - // ignore it - } - return null; - } - /** Represents the received SMS message for importing {@hide} */ public static final int SMS_TYPE_INCOMING = 0; /** Represents the sent SMS message for importing {@hide} */ public static final int SMS_TYPE_OUTGOING = 1; - /** - * Import a multimedia message into system's MMS store. Only the following PDU type is - * supported: Retrieve.conf, Send.req, Notification.ind, Delivery.ind, Read-Orig.ind - * - * Only default SMS apps can import MMS - * - * @param contentUri the content uri from which to read the PDU of the message to import - * @param messageId the optional message id. Use null if not specifying - * @param timestampSecs the optional message timestamp. Use -1 if not specifying - * @param seen if the message is seen - * @param read if the message is read - * @return the message URI, null if failed - * @throws IllegalArgumentException if pdu is empty - * {@hide} - */ - public Uri importMultimediaMessage(Uri contentUri, String messageId, long timestampSecs, - boolean seen, boolean read) { - if (contentUri == null) { - throw new IllegalArgumentException("Uri contentUri null"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.importMultimediaMessage(ActivityThread.currentPackageName(), - contentUri, messageId, timestampSecs, seen, read); - } - } catch (RemoteException ex) { - // ignore it - } - return null; - } - - /** - * Delete a system stored SMS or MMS message - * - * Only default SMS apps can delete system stored SMS and MMS messages - * - * @param messageUri the URI of the stored message - * @return true if deletion is successful, false otherwise - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public boolean deleteStoredMessage(Uri messageUri) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.deleteStoredMessage(ActivityThread.currentPackageName(), messageUri); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - - /** - * Delete a system stored SMS or MMS thread - * - * Only default SMS apps can delete system stored SMS and MMS conversations - * - * @param conversationId the ID of the message conversation - * @return true if deletion is successful, false otherwise - * {@hide} - */ - public boolean deleteStoredConversation(long conversationId) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.deleteStoredConversation( - ActivityThread.currentPackageName(), conversationId); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - - /** - * Update the status properties of a system stored SMS or MMS message, e.g. - * the read status of a message, etc. - * - * @param messageUri the URI of the stored message - * @param statusValues a list of status properties in key-value pairs to update - * @return true if update is successful, false otherwise - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public boolean updateStoredMessageStatus(Uri messageUri, ContentValues statusValues) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.updateStoredMessageStatus(ActivityThread.currentPackageName(), - messageUri, statusValues); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - /** Message status property: whether the message has been seen. 1 means seen, 0 not {@hide} */ public static final String MESSAGE_STATUS_SEEN = "seen"; /** Message status property: whether the message has been read. 1 means read, 0 not {@hide} */ public static final String MESSAGE_STATUS_READ = "read"; - /** - * Archive or unarchive a stored conversation - * - * @param conversationId the ID of the message conversation - * @param archived true to archive the conversation, false to unarchive - * @return true if update is successful, false otherwise - * {@hide} - */ - public boolean archiveStoredConversation(long conversationId, boolean archived) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.archiveStoredConversation(ActivityThread.currentPackageName(), - conversationId, archived); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - - /** - * Add a text message draft to system SMS store - * - * Only default SMS apps can add SMS draft - * - * @param address the destination address of message - * @param text the body of the message to send - * @return the URI of the stored draft message - * {@hide} - */ - public Uri addTextMessageDraft(String address, String text) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.addTextMessageDraft(ActivityThread.currentPackageName(), address, text); - } - } catch (RemoteException ex) { - // ignore it - } - return null; - } - - /** - * Add a multimedia message draft to system MMS store - * - * Only default SMS apps can add MMS draft - * - * @param contentUri the content uri from which to read the PDU data of the draft MMS - * @return the URI of the stored draft message - * @throws IllegalArgumentException if pdu is empty - * {@hide} - */ - public Uri addMultimediaMessageDraft(Uri contentUri) { - if (contentUri == null) { - throw new IllegalArgumentException("Uri contentUri null"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.addMultimediaMessageDraft(ActivityThread.currentPackageName(), - contentUri); - } - } catch (RemoteException ex) { - // ignore it - } - return null; - } - - /** - * Send a system stored text message. - * - * You can only send a failed text message or a draft text message. - * - * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this - * manager on a multi-SIM device, this operation may fail sending the SMS message because no - * suitable default subscription could be found. In this case, if {@code sentIntent} is - * non-null, then the {@link PendingIntent} will be sent with an error code - * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the - * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions - * where this operation may fail. - * </p> - * - * @param messageUri the URI of the stored message - * @param scAddress is the service center address or null to use the current default SMSC - * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is successfully sent, or failed. - * The result code will be <code>Activity.RESULT_OK</code> for success, - * or one of these errors:<br> - * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> - * <code>RESULT_ERROR_RADIO_OFF</code><br> - * <code>RESULT_ERROR_NULL_PDU</code><br> - * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.<br> - * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applications, - * which cause smaller number of SMS to be sent in checking period. - * @param deliveryIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - * - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public void sendStoredTextMessage(Uri messageUri, String scAddress, PendingIntent sentIntent, - PendingIntent deliveryIntent) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - final Context context = ActivityThread.currentApplication().getApplicationContext(); - resolveSubscriptionForOperation(new SubscriptionResolverResult() { - @Override - public void onSuccess(int subId) { - try { - ISms iSms = getISmsServiceOrThrow(); - iSms.sendStoredText(subId, ActivityThread.currentPackageName(), messageUri, - scAddress, sentIntent, deliveryIntent); - } catch (RemoteException e) { - Log.e(TAG, "sendStoredTextMessage: Couldn't send SMS - Exception: " - + e.getMessage()); - notifySmsGenericError(sentIntent); - } - } - @Override - public void onFailure() { - notifySmsErrorNoDefaultSet(context, sentIntent); - } - }); - } - - /** - * Send a system stored multi-part text message. - * - * You can only send a failed text message or a draft text message. - * The provided <code>PendingIntent</code> lists should match the part number of the - * divided text of the stored message by using <code>divideMessage</code> - * - * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this - * manager on a multi-SIM device, this operation may fail sending the SMS message because no - * suitable default subscription could be found. In this case, if {@code sentIntent} is - * non-null, then the {@link PendingIntent} will be sent with an error code - * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the - * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions - * where this operation may fail. - * </p> - * - * @param messageUri the URI of the stored message - * @param scAddress is the service center address or null to use - * the current default SMSC - * @param sentIntents if not null, an <code>ArrayList</code> of - * <code>PendingIntent</code>s (one for each message part) that is - * broadcast when the corresponding message part has been sent. - * The result code will be <code>Activity.RESULT_OK</code> for success, - * or one of these errors:<br> - * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> - * <code>RESULT_ERROR_RADIO_OFF</code><br> - * <code>RESULT_ERROR_NULL_PDU</code><br> - * For <code>RESULT_ERROR_GENERIC_FAILURE</code> each sentIntent may include - * the extra "errorCode" containing a radio technology specific value, - * generally only useful for troubleshooting.<br> - * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applications, - * which cause smaller number of SMS to be sent in checking period. - * @param deliveryIntents if not null, an <code>ArrayList</code> of - * <code>PendingIntent</code>s (one for each message part) that is - * broadcast when the corresponding message part has been delivered - * to the recipient. The raw pdu of the status report is in the - * extended data ("pdu"). - * - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public void sendStoredMultipartTextMessage(Uri messageUri, String scAddress, - ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - final Context context = ActivityThread.currentApplication().getApplicationContext(); - resolveSubscriptionForOperation(new SubscriptionResolverResult() { - @Override - public void onSuccess(int subId) { - try { - ISms iSms = getISmsServiceOrThrow(); - iSms.sendStoredMultipartText(subId, ActivityThread.currentPackageName(), - messageUri, scAddress, sentIntents, deliveryIntents); - } catch (RemoteException e) { - Log.e(TAG, "sendStoredTextMessage: Couldn't send SMS - Exception: " - + e.getMessage()); - notifySmsGenericError(sentIntents); - } - } - @Override - public void onFailure() { - notifySmsErrorNoDefaultSet(context, sentIntents); - } - }); - } - - /** - * Send a system stored MMS message - * - * This is used for sending a previously sent, but failed-to-send, message or - * for sending a text message that has been stored as a draft. - * - * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation - * dialog. If this method is called on a device that has multiple active subscriptions, this - * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined - * default subscription is defined, the subscription ID associated with this message will be - * INVALID, which will result in the operation being completed on the subscription associated - * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the - * operation is performed on the correct subscription. - * </p> - * - * @param messageUri the URI of the stored message - * @param configOverrides the carrier-specific messaging configuration values to override for - * sending the message. - * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is successfully sent, or failed - * @throws IllegalArgumentException if messageUri is empty - * {@hide} - */ - public void sendStoredMultimediaMessage(Uri messageUri, Bundle configOverrides, - PendingIntent sentIntent) { - if (messageUri == null) { - throw new IllegalArgumentException("Empty message URI"); - } - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - iMms.sendStoredMessage( - getSubscriptionId(), ActivityThread.currentPackageName(), messageUri, - configOverrides, sentIntent); - } - } catch (RemoteException ex) { - // ignore it - } - } - - /** - * Turns on/off the flag to automatically write sent/received SMS/MMS messages into system - * - * When this flag is on, all SMS/MMS sent/received are stored by system automatically - * When this flag is off, only SMS/MMS sent by non-default SMS apps are stored by system - * automatically - * - * This flag can only be changed by default SMS apps - * - * @param enabled Whether to enable message auto persisting - * {@hide} - */ - public void setAutoPersisting(boolean enabled) { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - iMms.setAutoPersisting(ActivityThread.currentPackageName(), enabled); - } - } catch (RemoteException ex) { - // ignore it - } - } - - /** - * Get the value of the flag to automatically write sent/received SMS/MMS messages into system - * - * When this flag is on, all SMS/MMS sent/received are stored by system automatically - * When this flag is off, only SMS/MMS sent by non-default SMS apps are stored by system - * automatically - * - * @return the current value of the auto persist flag - * {@hide} - */ - public boolean getAutoPersisting() { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.getAutoPersisting(); - } - } catch (RemoteException ex) { - // ignore it - } - return false; - } - /** * Get carrier-dependent configuration values. * @@ -2686,15 +2042,7 @@ public final class SmsManager { * @return bundle key/values pairs of configuration values */ public Bundle getCarrierConfigValues() { - try { - IMms iMms = IMms.Stub.asInterface(ServiceManager.getService("imms")); - if (iMms != null) { - return iMms.getCarrierConfigValues(getSubscriptionId()); - } - } catch (RemoteException ex) { - // ignore it - } - return null; + return MmsManager.getInstance().getCarrierConfigValues(getSubscriptionId()); } /** @@ -2780,38 +2128,38 @@ public final class SmsManager { } /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * The prefixes is a list of prefix {@code String} separated by this delimiter. * @hide */ public static final String REGEX_PREFIX_DELIMITER = ","; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * The success status to be added into the intent to be sent to the calling package. * @hide */ public static final int RESULT_STATUS_SUCCESS = 0; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * The timeout status to be added into the intent to be sent to the calling package. * @hide */ public static final int RESULT_STATUS_TIMEOUT = 1; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * Intent extra key of the retrieved SMS message as a {@code String}. * @hide */ public static final String EXTRA_SMS_MESSAGE = "android.telephony.extra.SMS_MESSAGE"; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * Intent extra key of SMS retriever status, which indicates whether the request for the * coming SMS message is SUCCESS or TIMEOUT * @hide */ public static final String EXTRA_STATUS = "android.telephony.extra.STATUS"; /** - * @see #createAppSpecificSmsTokenWithPackageInfo(). + * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent). * [Optional] Intent extra key of the retrieved Sim card subscription Id if any. {@code int} * @hide */ diff --git a/telephony/java/com/android/internal/telephony/SmsApplication.java b/telephony/java/com/android/internal/telephony/SmsApplication.java index f10398f096032..f4eae8ef4b2a7 100644 --- a/telephony/java/com/android/internal/telephony/SmsApplication.java +++ b/telephony/java/com/android/internal/telephony/SmsApplication.java @@ -40,7 +40,6 @@ import android.os.UserHandle; import android.provider.Telephony; import android.provider.Telephony.Sms.Intents; import android.telephony.Rlog; -import android.telephony.SmsManager; import android.telephony.TelephonyManager; import android.util.Log; @@ -1045,9 +1044,6 @@ public final class SmsApplication { */ @UnsupportedAppUsage public static boolean shouldWriteMessageForPackage(String packageName, Context context) { - if (SmsManager.getDefault().getAutoPersisting()) { - return true; - } return !isDefaultSmsApplication(context, packageName); } -- GitLab