1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.telephony;
18 
19 import android.Manifest;
20 import android.annotation.CallbackExecutor;
21 import android.annotation.IntDef;
22 import android.annotation.IntRange;
23 import android.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.annotation.RequiresFeature;
26 import android.annotation.RequiresPermission;
27 import android.annotation.SuppressAutoDoc;
28 import android.annotation.SystemApi;
29 import android.annotation.TestApi;
30 import android.app.PendingIntent;
31 import android.compat.Compatibility;
32 import android.compat.annotation.ChangeId;
33 import android.compat.annotation.EnabledAfter;
34 import android.compat.annotation.UnsupportedAppUsage;
35 import android.content.Context;
36 import android.content.pm.PackageManager;
37 import android.database.CursorWindow;
38 import android.net.Uri;
39 import android.os.Build;
40 import android.os.Bundle;
41 import android.os.RemoteException;
42 import android.text.TextUtils;
43 import android.util.ArrayMap;
44 import android.util.Log;
45 import android.util.Pair;
46 
47 import com.android.internal.annotations.GuardedBy;
48 import com.android.internal.telephony.IIntegerConsumer;
49 import com.android.internal.telephony.IPhoneSubInfo;
50 import com.android.internal.telephony.ISms;
51 import com.android.internal.telephony.ITelephony;
52 import com.android.internal.telephony.SmsRawData;
53 import com.android.telephony.Rlog;
54 
55 import java.lang.annotation.Retention;
56 import java.lang.annotation.RetentionPolicy;
57 import java.util.ArrayList;
58 import java.util.List;
59 import java.util.Map;
60 import java.util.concurrent.Executor;
61 
62 /*
63  * TODO(code review): Curious question... Why are a lot of these
64  * methods not declared as static, since they do not seem to require
65  * any local object state?  Presumably this cannot be changed without
66  * interfering with the API...
67  */
68 
69 /**
70  * Manages SMS operations such as sending data, text, and pdu SMS messages.
71  * Get this object by calling the static method {@link #getDefault()}. To create an instance of
72  * {@link SmsManager} associated with a specific subscription ID, call
73  * {@link #getSmsManagerForSubscriptionId(int)}. This is typically used for devices that support
74  * multiple active subscriptions at once.
75  *
76  * <p>For information about how to behave as the default SMS app on Android 4.4 (API level 19)
77  * and higher, see {@link android.provider.Telephony}.
78  *
79  * @see SubscriptionManager#getActiveSubscriptionInfoList()
80  */
81 @RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
82 public final class SmsManager {
83     private static final String TAG = "SmsManager";
84 
85     private static final Object sLockObject = new Object();
86 
87     @GuardedBy("sLockObject")
88     private static final Map<Pair<Context, Integer>, SmsManager> sSubInstances =
89             new ArrayMap<>();
90 
91     /** Singleton object constructed during class initialization. */
92     private static final SmsManager DEFAULT_INSTANCE = getSmsManagerForContextAndSubscriptionId(
93             null, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
94 
95     /** SMS record length from TS 51.011 10.5.3
96      * @hide
97      */
98     public static final int SMS_RECORD_LENGTH = 176;
99 
100     /** SMS record length from C.S0023 3.4.27
101      * @hide
102      */
103     public static final int CDMA_SMS_RECORD_LENGTH = 255;
104 
105     /** A concrete subscription id, or the pseudo DEFAULT_SUBSCRIPTION_ID */
106     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
107     private int mSubId;
108 
109     /**
110      * Context this SmsManager is for. Can be {@code null} in the case the manager was created via
111      * legacy APIs
112      */
113     private final @Nullable Context mContext;
114 
115     /*
116      * Key for the various carrier-dependent configuration values.
117      * Some of the values are used by the system in processing SMS or MMS messages. Others
118      * are provided for the convenience of SMS applications.
119      */
120 
121     /**
122      * Whether to append transaction id to MMS WAP Push M-Notification.ind's content location URI
123      * when constructing the download URL of a new MMS (boolean type)
124      */
125     public static final String MMS_CONFIG_APPEND_TRANSACTION_ID =
126             CarrierConfigManager.KEY_MMS_APPEND_TRANSACTION_ID_BOOL;
127     /**
128      * Whether MMS is enabled for the current carrier (boolean type)
129      */
130     public static final String
131             MMS_CONFIG_MMS_ENABLED = CarrierConfigManager.KEY_MMS_MMS_ENABLED_BOOL;
132     /**
133      * Whether group MMS is enabled for the current carrier (boolean type)
134      */
135     public static final String
136             MMS_CONFIG_GROUP_MMS_ENABLED = CarrierConfigManager.KEY_MMS_GROUP_MMS_ENABLED_BOOL;
137     /**
138      * If this is enabled, M-NotifyResp.ind should be sent to the WAP Push content location instead
139      * of the default MMSC (boolean type)
140      */
141     public static final String MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED =
142             CarrierConfigManager.KEY_MMS_NOTIFY_WAP_MMSC_ENABLED_BOOL;
143     /**
144      * Whether alias is enabled (boolean type)
145      */
146     public static final String
147             MMS_CONFIG_ALIAS_ENABLED = CarrierConfigManager.KEY_MMS_ALIAS_ENABLED_BOOL;
148     /**
149      * Whether audio is allowed to be attached for MMS messages (boolean type)
150      */
151     public static final String
152             MMS_CONFIG_ALLOW_ATTACH_AUDIO = CarrierConfigManager.KEY_MMS_ALLOW_ATTACH_AUDIO_BOOL;
153     /**
154      * Whether multipart SMS is enabled (boolean type)
155      */
156     public static final String MMS_CONFIG_MULTIPART_SMS_ENABLED =
157             CarrierConfigManager.KEY_MMS_MULTIPART_SMS_ENABLED_BOOL;
158     /**
159      * Whether SMS delivery report is enabled (boolean type)
160      */
161     public static final String MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED =
162             CarrierConfigManager.KEY_MMS_SMS_DELIVERY_REPORT_ENABLED_BOOL;
163     /**
164      * Whether content-disposition field should be expected in an MMS PDU (boolean type)
165      */
166     public static final String MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION =
167             CarrierConfigManager.KEY_MMS_SUPPORT_MMS_CONTENT_DISPOSITION_BOOL;
168     /**
169      * Whether multipart SMS should be sent as separate messages
170      */
171     public static final String MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES =
172             CarrierConfigManager.KEY_MMS_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES_BOOL;
173     /**
174      * Whether MMS read report is enabled (boolean type)
175      */
176     public static final String MMS_CONFIG_MMS_READ_REPORT_ENABLED =
177             CarrierConfigManager.KEY_MMS_MMS_READ_REPORT_ENABLED_BOOL;
178     /**
179      * Whether MMS delivery report is enabled (boolean type)
180      */
181     public static final String MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED =
182             CarrierConfigManager.KEY_MMS_MMS_DELIVERY_REPORT_ENABLED_BOOL;
183     /**
184      * Max MMS message size in bytes (int type)
185      */
186     public static final String
187             MMS_CONFIG_MAX_MESSAGE_SIZE = CarrierConfigManager.KEY_MMS_MAX_MESSAGE_SIZE_INT;
188     /**
189      * Max MMS image width (int type)
190      */
191     public static final String
192             MMS_CONFIG_MAX_IMAGE_WIDTH = CarrierConfigManager.KEY_MMS_MAX_IMAGE_WIDTH_INT;
193     /**
194      * Max MMS image height (int type)
195      */
196     public static final String
197             MMS_CONFIG_MAX_IMAGE_HEIGHT = CarrierConfigManager.KEY_MMS_MAX_IMAGE_HEIGHT_INT;
198     /**
199      * Limit of recipients of MMS messages (int type)
200      */
201     public static final String
202             MMS_CONFIG_RECIPIENT_LIMIT = CarrierConfigManager.KEY_MMS_RECIPIENT_LIMIT_INT;
203     /**
204      * Min alias character count (int type)
205      */
206     public static final String
207             MMS_CONFIG_ALIAS_MIN_CHARS = CarrierConfigManager.KEY_MMS_ALIAS_MIN_CHARS_INT;
208     /**
209      * Max alias character count (int type)
210      */
211     public static final String
212             MMS_CONFIG_ALIAS_MAX_CHARS = CarrierConfigManager.KEY_MMS_ALIAS_MAX_CHARS_INT;
213     /**
214      * When the number of parts of a multipart SMS reaches this threshold, it should be converted
215      * into an MMS (int type)
216      */
217     public static final String MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD =
218             CarrierConfigManager.KEY_MMS_SMS_TO_MMS_TEXT_THRESHOLD_INT;
219     /**
220      * Some carriers require SMS to be converted into MMS when text length reaches this threshold
221      * (int type)
222      */
223     public static final String MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD =
224             CarrierConfigManager.KEY_MMS_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD_INT;
225     /**
226      * Max message text size (int type)
227      */
228     public static final String MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE =
229             CarrierConfigManager.KEY_MMS_MESSAGE_TEXT_MAX_SIZE_INT;
230     /**
231      * Max message subject length (int type)
232      */
233     public static final String
234             MMS_CONFIG_SUBJECT_MAX_LENGTH = CarrierConfigManager.KEY_MMS_SUBJECT_MAX_LENGTH_INT;
235     /**
236      * MMS HTTP socket timeout in milliseconds (int type)
237      */
238     public static final String
239             MMS_CONFIG_HTTP_SOCKET_TIMEOUT = CarrierConfigManager.KEY_MMS_HTTP_SOCKET_TIMEOUT_INT;
240     /**
241      * The name of the UA Prof URL HTTP header for MMS HTTP request (String type)
242      */
243     public static final String
244             MMS_CONFIG_UA_PROF_TAG_NAME = CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING;
245     /**
246      * The User-Agent header value for MMS HTTP request (String type)
247      */
248     public static final String
249             MMS_CONFIG_USER_AGENT = CarrierConfigManager.KEY_MMS_USER_AGENT_STRING;
250     /**
251      * The UA Profile URL header value for MMS HTTP request (String type)
252      */
253     public static final String
254             MMS_CONFIG_UA_PROF_URL = CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING;
255     /**
256      * A list of HTTP headers to add to MMS HTTP request, separated by "|" (String type)
257      */
258     public static final String
259             MMS_CONFIG_HTTP_PARAMS = CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING;
260     /**
261      * Email gateway number (String type)
262      */
263     public static final String MMS_CONFIG_EMAIL_GATEWAY_NUMBER =
264             CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING;
265     /**
266      * The suffix to append to the NAI header value for MMS HTTP request (String type)
267      */
268     public static final String
269             MMS_CONFIG_NAI_SUFFIX = CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING;
270     /**
271      * If true, show the cell broadcast (amber alert) in the SMS settings. Some carriers don't want
272      * this shown. (Boolean type)
273      */
274     public static final String MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS =
275             CarrierConfigManager.KEY_MMS_SHOW_CELL_BROADCAST_APP_LINKS_BOOL;
276     /**
277      * Whether the carrier MMSC supports charset field in Content-Type header. If this is false,
278      * then we don't add "charset" to "Content-Type"
279      */
280     public static final String MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER =
281             CarrierConfigManager.KEY_MMS_SUPPORT_HTTP_CHARSET_HEADER_BOOL;
282     /**
283      * If true, add "Connection: close" header to MMS HTTP requests so the connection
284      * is immediately closed (disabling keep-alive). (Boolean type)
285      * @hide
286      */
287     public static final String MMS_CONFIG_CLOSE_CONNECTION =
288             CarrierConfigManager.KEY_MMS_CLOSE_CONNECTION_BOOL;
289 
290     /**
291      * 3gpp2 SMS priority is not specified
292      * @hide
293      */
294     public static final int SMS_MESSAGE_PRIORITY_NOT_SPECIFIED = -1;
295     /**
296      * 3gpp SMS period is not specified
297      * @hide
298      */
299     public static final int SMS_MESSAGE_PERIOD_NOT_SPECIFIED = -1;
300 
301     // RP-Cause Values For MO SMS as per TS 124 011, table 8.4.
302 
303     /** @hide */
304     @IntDef(prefix = { "SMS_RP_CAUSE" }, value = {
305         SmsManager.SMS_RP_CAUSE_UNALLOCATED_NUMBER,
306         SmsManager.SMS_RP_CAUSE_OPERATOR_DETERMINED_BARRING,
307         SmsManager.SMS_RP_CAUSE_CALL_BARRING,
308         SmsManager.SMS_RP_CAUSE_RESERVED,
309         SmsManager.SMS_RP_CAUSE_SHORT_MESSAGE_TRANSFER_REJECTED,
310         SmsManager.SMS_RP_CAUSE_DESTINATION_OUT_OF_ORDER,
311         SmsManager.SMS_RP_CAUSE_UNIDENTIFIED_SUBSCRIBER,
312         SmsManager.SMS_RP_CAUSE_FACILITY_REJECTED,
313         SmsManager.SMS_RP_CAUSE_UNKNOWN_SUBSCRIBER,
314         SmsManager.SMS_RP_CAUSE_NETWORK_OUT_OF_ORDER,
315         SmsManager.SMS_RP_CAUSE_TEMPORARY_FAILURE,
316         SmsManager.SMS_RP_CAUSE_CONGESTION,
317         SmsManager.SMS_RP_CAUSE_RESOURCES_UNAVAILABLE,
318         SmsManager.SMS_RP_CAUSE_FACILITY_NOT_SUBSCRIBED,
319         SmsManager.SMS_RP_CAUSE_FACILITY_NOT_IMPLEMENTED,
320         SmsManager.SMS_RP_CAUSE_INVALID_MESSAGE_REFERENCE_VALUE,
321         SmsManager.SMS_RP_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,
322         SmsManager.SMS_RP_CAUSE_INVALID_MANDATORY_INFORMATION,
323         SmsManager.SMS_RP_CAUSE_MESSAGE_TYPE_NON_EXISTENT,
324         SmsManager.SMS_RP_CAUSE_MESSAGE_INCOMPATIBLE_WITH_PROTOCOL_STATE,
325         SmsManager.SMS_RP_CAUSE_INFORMATION_ELEMENT_NON_EXISTENT,
326         SmsManager.SMS_RP_CAUSE_PROTOCOL_ERROR,
327         SmsManager.SMS_RP_CAUSE_INTERWORKING_UNSPECIFIED
328     })
329     @Retention(RetentionPolicy.SOURCE)
330     public @interface SMS_RP_CAUSE {}
331 
332     /** Unallocated Number Cause */
333     public static final int SMS_RP_CAUSE_UNALLOCATED_NUMBER = 1;
334 
335     /** RP-Cause for Operator Barring */
336     public static final int SMS_RP_CAUSE_OPERATOR_DETERMINED_BARRING = 8;
337 
338     /** RP-Cause Value for Call Barring */
339     public static final int SMS_RP_CAUSE_CALL_BARRING = 10;
340 
341     /** RP-Cause value for Reserved Number */
342     public static final int SMS_RP_CAUSE_RESERVED = 11;
343 
344     /** RP-Cause Value for Message Transfer Rejected by Network */
345     public static final int SMS_RP_CAUSE_SHORT_MESSAGE_TRANSFER_REJECTED = 21;
346 
347     /** RP-Cause Value for Destination is Out of Order */
348     public static final int SMS_RP_CAUSE_DESTINATION_OUT_OF_ORDER = 27;
349 
350     /** RP-Cause Value when Subscriber is not Identified */
351     public static final int SMS_RP_CAUSE_UNIDENTIFIED_SUBSCRIBER = 28;
352 
353     /** RP-Cause Value when SMS Facility if Rejected by Operator */
354     public static final int SMS_RP_CAUSE_FACILITY_REJECTED = 29;
355 
356     /** RP-Cause Value when Subscriber is not Identified */
357     public static final int SMS_RP_CAUSE_UNKNOWN_SUBSCRIBER = 30;
358 
359     /** RP-Cause Value when network is out of order*/
360     public static final int SMS_RP_CAUSE_NETWORK_OUT_OF_ORDER = 38;
361 
362     /** RP-Cause Value For Temporary failure*/
363     public static final int SMS_RP_CAUSE_TEMPORARY_FAILURE = 41;
364 
365     /** RP-Cause Value for SMS Failure due to Congestion in network*/
366     public static final int SMS_RP_CAUSE_CONGESTION = 42;
367 
368     /** RP-Cause Value when Network Resources are unavailable */
369     public static final int SMS_RP_CAUSE_RESOURCES_UNAVAILABLE = 47;
370 
371     /** RP-Cause Value when SMS Facilty is not subscribed by Reote device */
372     public static final int SMS_RP_CAUSE_FACILITY_NOT_SUBSCRIBED = 50;
373 
374     /** RP-Cause Value when network does not provide the received service */
375     public static final int SMS_RP_CAUSE_FACILITY_NOT_IMPLEMENTED = 69;
376 
377     /** RP-Cause Value when RP-MessageRefere */
378     public static final int SMS_RP_CAUSE_INVALID_MESSAGE_REFERENCE_VALUE = 81;
379 
380     /** RP-Cause Value when network does not provide the received service */
381     public static final int SMS_RP_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE = 95;
382 
383     /** RP-Cause Value when network does not provide the received service */
384     public static final int SMS_RP_CAUSE_INVALID_MANDATORY_INFORMATION = 96;
385 
386     /** RP-Cause Value when network does not provide the received service */
387     public static final int SMS_RP_CAUSE_MESSAGE_TYPE_NON_EXISTENT = 97;
388 
389     /** RP-Cause Value when network does not provide the received service */
390     public static final int SMS_RP_CAUSE_MESSAGE_INCOMPATIBLE_WITH_PROTOCOL_STATE = 98;
391 
392     /** RP-Cause Value when network does not provide the received service */
393     public static final int SMS_RP_CAUSE_INFORMATION_ELEMENT_NON_EXISTENT  = 99;
394 
395     /** RP-Cause Value when network does not provide the received service */
396     public static final int SMS_RP_CAUSE_PROTOCOL_ERROR = 111;
397 
398     /** RP-Cause Value when network does not provide the received service */
399     public static final int SMS_RP_CAUSE_INTERWORKING_UNSPECIFIED = 127;
400 
401     /** @hide */
402     @IntDef(prefix = { "PREMIUM_SMS_CONSENT" }, value = {
403         SmsManager.PREMIUM_SMS_CONSENT_UNKNOWN,
404         SmsManager.PREMIUM_SMS_CONSENT_ASK_USER,
405         SmsManager.PREMIUM_SMS_CONSENT_NEVER_ALLOW,
406         SmsManager.PREMIUM_SMS_CONSENT_ALWAYS_ALLOW
407     })
408     @Retention(RetentionPolicy.SOURCE)
409     public @interface PremiumSmsConsent {}
410 
411     /** Premium SMS Consent for the package is unknown. This indicates that the user
412      *  has not set a permission for this package, because this package has never tried
413      *  to send a premium SMS.
414      * @hide
415      */
416     @SystemApi
417     public static final int PREMIUM_SMS_CONSENT_UNKNOWN = 0;
418 
419     /** Default premium SMS Consent (ask user for each premium SMS sent).
420      * @hide
421      */
422     @SystemApi
423     public static final int PREMIUM_SMS_CONSENT_ASK_USER = 1;
424 
425     /** Premium SMS Consent when the owner has denied the app from sending premium SMS.
426      * @hide
427      */
428     @SystemApi
429     public static final int PREMIUM_SMS_CONSENT_NEVER_ALLOW = 2;
430 
431     /** Premium SMS Consent when the owner has allowed the app to send premium SMS.
432      * @hide
433      */
434     @SystemApi
435     public static final int PREMIUM_SMS_CONSENT_ALWAYS_ALLOW = 3;
436 
437     // result of asking the user for a subscription to perform an operation.
438     private interface SubscriptionResolverResult {
onSuccess(int subId)439         void onSuccess(int subId);
onFailure()440         void onFailure();
441     }
442 
443     /**
444      * Get {@link Context#getOpPackageName()} if this manager has a context, otherwise a dummy
445      * value.
446      *
447      * @return The package name to be used for app-ops checks
448      */
getOpPackageName()449     private @Nullable String getOpPackageName() {
450         if (mContext == null) {
451             return null;
452         } else {
453             return mContext.getOpPackageName();
454         }
455     }
456 
457     /**
458      * Get {@link Context#getAttributionTag()} ()} if this manager has a context, otherwise get the
459      * default attribution tag.
460      *
461      * @return The attribution tag to be used for app-ops checks
462      */
getAttributionTag()463     private @Nullable String getAttributionTag() {
464         if (mContext == null) {
465             return null;
466         } else {
467             return mContext.getAttributionTag();
468         }
469     }
470 
471     /**
472      * Send a text based SMS.
473      *
474      * <p class="note"><strong>Note:</strong> Using this method requires that your app has the
475      * {@link android.Manifest.permission#SEND_SMS} permission.</p>
476      *
477      * <p class="note"><strong>Note:</strong> Beginning with Android 4.4 (API level 19), if
478      * <em>and only if</em> an app is not selected as the default SMS app, the system automatically
479      * writes messages sent using this method to the SMS Provider (the default SMS app is always
480      * responsible for writing its sent messages to the SMS Provider). For information about
481      * how to behave as the default SMS app, see {@link android.provider.Telephony}.</p>
482      *
483      * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
484      * manager on a multi-SIM device, this operation may fail sending the SMS message because no
485      * suitable default subscription could be found. In this case, if {@code sentIntent} is
486      * non-null, then the {@link PendingIntent} will be sent with an error code
487      * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the
488      * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions
489      * where this operation may fail.
490      * </p>
491      *
492      * @param destinationAddress the address to send the message to
493      * @param scAddress is the service center address or null to use
494      *  the current default SMSC
495      * @param text the body of the message to send
496      * @param sentIntent if not NULL this <code>PendingIntent</code> is
497      *  broadcast when the message is successfully sent, or failed.
498      *  The result code will be <code>Activity.RESULT_OK</code> for success,
499      *  or one of these errors:<br>
500      *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
501      *  <code>RESULT_ERROR_RADIO_OFF</code><br>
502      *  <code>RESULT_ERROR_NULL_PDU</code><br>
503      *  <code>RESULT_ERROR_NO_SERVICE</code><br>
504      *  <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br>
505      *  <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
506      *  <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
507      *  <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
508      *  <code>RESULT_RADIO_NOT_AVAILABLE</code><br>
509      *  <code>RESULT_NETWORK_REJECT</code><br>
510      *  <code>RESULT_INVALID_ARGUMENTS</code><br>
511      *  <code>RESULT_INVALID_STATE</code><br>
512      *  <code>RESULT_NO_MEMORY</code><br>
513      *  <code>RESULT_INVALID_SMS_FORMAT</code><br>
514      *  <code>RESULT_SYSTEM_ERROR</code><br>
515      *  <code>RESULT_MODEM_ERROR</code><br>
516      *  <code>RESULT_NETWORK_ERROR</code><br>
517      *  <code>RESULT_ENCODING_ERROR</code><br>
518      *  <code>RESULT_INVALID_SMSC_ADDRESS</code><br>
519      *  <code>RESULT_OPERATION_NOT_ALLOWED</code><br>
520      *  <code>RESULT_INTERNAL_ERROR</code><br>
521      *  <code>RESULT_NO_RESOURCES</code><br>
522      *  <code>RESULT_CANCELLED</code><br>
523      *  <code>RESULT_REQUEST_NOT_SUPPORTED</code><br>
524      *  <code>RESULT_NO_BLUETOOTH_SERVICE</code><br>
525      *  <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
526      *  <code>RESULT_BLUETOOTH_DISCONNECTED</code><br>
527      *  <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
528      *  <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
529      *  <code>RESULT_SMS_SEND_RETRY_FAILED</code><br>
530      *  <code>RESULT_REMOTE_EXCEPTION</code><br>
531      *  <code>RESULT_NO_DEFAULT_SMS_APP</code><br>
532      *  <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
533      *  <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
534      *  <code>RESULT_RIL_NETWORK_REJECT</code><br>
535      *  <code>RESULT_RIL_INVALID_STATE</code><br>
536      *  <code>RESULT_RIL_INVALID_ARGUMENTS</code><br>
537      *  <code>RESULT_RIL_NO_MEMORY</code><br>
538      *  <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
539      *  <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br>
540      *  <code>RESULT_RIL_SYSTEM_ERR</code><br>
541      *  <code>RESULT_RIL_ENCODING_ERR</code><br>
542      *  <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
543      *  <code>RESULT_RIL_MODEM_ERR</code><br>
544      *  <code>RESULT_RIL_NETWORK_ERR</code><br>
545      *  <code>RESULT_RIL_INTERNAL_ERR</code><br>
546      *  <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
547      *  <code>RESULT_RIL_INVALID_MODEM_STATE</code><br>
548      *  <code>RESULT_RIL_NETWORK_NOT_READY</code><br>
549      *  <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
550      *  <code>RESULT_RIL_NO_RESOURCES</code><br>
551      *  <code>RESULT_RIL_CANCELLED</code><br>
552      *  <code>RESULT_RIL_SIM_ABSENT</code><br>
553      *  <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
554      *  <code>RESULT_RIL_ACCESS_BARRED</code><br>
555      *  <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
556      *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
557      *  the sentIntent may include the extra "errorCode" containing a radio technology specific
558      *  value, generally only useful for troubleshooting.<br>
559      * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
560      *  broadcast when the message is delivered to the recipient.  The
561      *  raw pdu of the status report is in the extended data ("pdu").
562      *
563      * @throws IllegalArgumentException if destinationAddress or text are empty
564      */
sendTextMessage( String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)565     public void sendTextMessage(
566             String destinationAddress, String scAddress, String text,
567             PendingIntent sentIntent, PendingIntent deliveryIntent) {
568         sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
569                 true /* persistMessage*/, getOpPackageName(), getAttributionTag(),
570                 0L /* messageId */);
571     }
572 
573 
574     /**
575      * Send a text based SMS. Same as {@link #sendTextMessage( String destinationAddress,
576      * String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)}, but
577      * adds an optional messageId.
578      * @param messageId An id that uniquely identifies the message requested to be sent.
579      * Used for logging and diagnostics purposes. The id may be 0.
580      *
581      * @throws IllegalArgumentException if destinationAddress or text are empty
582      *
583      */
sendTextMessage( @onNull String destinationAddress, @Nullable String scAddress, @NonNull String text, @Nullable PendingIntent sentIntent, @Nullable PendingIntent deliveryIntent, long messageId)584     public void sendTextMessage(
585             @NonNull String destinationAddress, @Nullable String scAddress, @NonNull String text,
586             @Nullable PendingIntent sentIntent, @Nullable PendingIntent deliveryIntent,
587             long messageId) {
588         sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
589                 true /* persistMessage*/, getOpPackageName(), getAttributionTag(),
590                 messageId);
591     }
592 
593     /**
594      * Send a text based SMS with messaging options.
595      *
596      * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
597      * manager on a multi-SIM device, this operation may fail sending the SMS message because no
598      * suitable default subscription could be found. In this case, if {@code sentIntent} is
599      * non-null, then the {@link PendingIntent} will be sent with an error code
600      * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the
601      * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions
602      * where this operation may fail.
603      * </p>
604      *
605      * @param destinationAddress the address to send the message to
606      * @param scAddress is the service center address or null to use
607      *  the current default SMSC
608      * @param text the body of the message to send
609      * @param sentIntent if not NULL this <code>PendingIntent</code> is
610      *  broadcast when the message is successfully sent, or failed.
611      *  The result code will be <code>Activity.RESULT_OK</code> for success,
612      *  or one of these errors:<br>
613      *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
614      *  <code>RESULT_ERROR_RADIO_OFF</code><br>
615      *  <code>RESULT_ERROR_NULL_PDU</code><br>
616      *  <code>RESULT_ERROR_NO_SERVICE</code><br>
617      *  <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br>
618      *  <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
619      *  <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
620      *  <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
621      *  <code>RESULT_RADIO_NOT_AVAILABLE</code><br>
622      *  <code>RESULT_NETWORK_REJECT</code><br>
623      *  <code>RESULT_INVALID_ARGUMENTS</code><br>
624      *  <code>RESULT_INVALID_STATE</code><br>
625      *  <code>RESULT_NO_MEMORY</code><br>
626      *  <code>RESULT_INVALID_SMS_FORMAT</code><br>
627      *  <code>RESULT_SYSTEM_ERROR</code><br>
628      *  <code>RESULT_MODEM_ERROR</code><br>
629      *  <code>RESULT_NETWORK_ERROR</code><br>
630      *  <code>RESULT_ENCODING_ERROR</code><br>
631      *  <code>RESULT_INVALID_SMSC_ADDRESS</code><br>
632      *  <code>RESULT_OPERATION_NOT_ALLOWED</code><br>
633      *  <code>RESULT_INTERNAL_ERROR</code><br>
634      *  <code>RESULT_NO_RESOURCES</code><br>
635      *  <code>RESULT_CANCELLED</code><br>
636      *  <code>RESULT_REQUEST_NOT_SUPPORTED</code><br>
637      *  <code>RESULT_NO_BLUETOOTH_SERVICE</code><br>
638      *  <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
639      *  <code>RESULT_BLUETOOTH_DISCONNECTED</code><br>
640      *  <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
641      *  <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
642      *  <code>RESULT_SMS_SEND_RETRY_FAILED</code><br>
643      *  <code>RESULT_REMOTE_EXCEPTION</code><br>
644      *  <code>RESULT_NO_DEFAULT_SMS_APP</code><br>
645      *  <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
646      *  <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
647      *  <code>RESULT_RIL_NETWORK_REJECT</code><br>
648      *  <code>RESULT_RIL_INVALID_STATE</code><br>
649      *  <code>RESULT_RIL_INVALID_ARGUMENTS</code><br>
650      *  <code>RESULT_RIL_NO_MEMORY</code><br>
651      *  <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
652      *  <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br>
653      *  <code>RESULT_RIL_SYSTEM_ERR</code><br>
654      *  <code>RESULT_RIL_ENCODING_ERR</code><br>
655      *  <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
656      *  <code>RESULT_RIL_MODEM_ERR</code><br>
657      *  <code>RESULT_RIL_NETWORK_ERR</code><br>
658      *  <code>RESULT_RIL_INTERNAL_ERR</code><br>
659      *  <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
660      *  <code>RESULT_RIL_INVALID_MODEM_STATE</code><br>
661      *  <code>RESULT_RIL_NETWORK_NOT_READY</code><br>
662      *  <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
663      *  <code>RESULT_RIL_NO_RESOURCES</code><br>
664      *  <code>RESULT_RIL_CANCELLED</code><br>
665      *  <code>RESULT_RIL_SIM_ABSENT</code><br>
666      *  <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
667      *  <code>RESULT_RIL_ACCESS_BARRED</code><br>
668      *  <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
669      *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
670      *  the sentIntent may include the extra "errorCode" containing a radio technology specific
671      *  value, generally only useful for troubleshooting.<br>
672      * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
673      *  broadcast when the message is delivered to the recipient.  The
674      *  raw pdu of the status report is in the extended data ("pdu").
675      * @param priority Priority level of the message
676      *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
677      *  ---------------------------------
678      *  PRIORITY      | Level of Priority
679      *  ---------------------------------
680      *      '00'      |     Normal
681      *      '01'      |     Interactive
682      *      '10'      |     Urgent
683      *      '11'      |     Emergency
684      *  ----------------------------------
685      *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
686      * @param expectMore is a boolean to indicate the sending messages through same link or not.
687      * @param validityPeriod Validity Period of the message in mins.
688      *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
689      *  Validity Period(Minimum) -> 5 mins
690      *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
691      *  Any Other values included Negative considered as Invalid Validity Period of the message.
692      *
693      * @throws IllegalArgumentException if destinationAddress or text are empty
694      * {@hide}
695      */
696     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
sendTextMessage( String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, int priority, boolean expectMore, int validityPeriod)697     public void sendTextMessage(
698             String destinationAddress, String scAddress, String text,
699             PendingIntent sentIntent, PendingIntent deliveryIntent,
700             int priority, boolean expectMore, int validityPeriod) {
701         sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
702                 true /* persistMessage*/, priority, expectMore, validityPeriod);
703     }
704 
sendTextMessageInternal(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, String packageName, String attributionTag, long messageId)705     private void sendTextMessageInternal(String destinationAddress, String scAddress,
706             String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
707             boolean persistMessage, String packageName, String attributionTag, long messageId) {
708         if (TextUtils.isEmpty(destinationAddress)) {
709             throw new IllegalArgumentException("Invalid destinationAddress");
710         }
711 
712         if (TextUtils.isEmpty(text)) {
713             throw new IllegalArgumentException("Invalid message body");
714         }
715 
716         // We will only show the SMS disambiguation dialog in the case that the message is being
717         // persisted. This is for two reasons:
718         // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific
719         //    subscription and require special permissions. These messages are usually not sent by
720         //    the device user and should not have an SMS disambiguation dialog associated with them
721         //    because the device user did not trigger them.
722         // 2) The SMS disambiguation dialog ONLY checks to make sure that the user has the SEND_SMS
723         //    permission. If we call resolveSubscriptionForOperation from a carrier/OEM app that has
724         //    the correct MODIFY_PHONE_STATE or carrier permissions, but no SEND_SMS, it will throw
725         //    an incorrect SecurityException.
726         if (persistMessage) {
727             resolveSubscriptionForOperation(new SubscriptionResolverResult() {
728                 @Override
729                 public void onSuccess(int subId) {
730                     ISms iSms = getISmsServiceOrThrow();
731                     try {
732                         iSms.sendTextForSubscriber(subId, packageName, attributionTag,
733                                 destinationAddress, scAddress, text, sentIntent, deliveryIntent,
734                                 persistMessage, messageId);
735                     } catch (RemoteException e) {
736                         Log.e(TAG, "sendTextMessageInternal: Couldn't send SMS, exception - "
737                                 + e.getMessage() + " " + formatCrossStackMessageId(messageId));
738                         notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
739                     }
740                 }
741 
742                 @Override
743                 public void onFailure() {
744                     notifySmsError(sentIntent, RESULT_NO_DEFAULT_SMS_APP);
745                 }
746             });
747         } else {
748             // Not persisting the message, used by sendTextMessageWithoutPersisting() and is not
749             // visible to the user.
750             ISms iSms = getISmsServiceOrThrow();
751             try {
752                 iSms.sendTextForSubscriber(getSubscriptionId(), packageName, attributionTag,
753                         destinationAddress, scAddress, text, sentIntent, deliveryIntent,
754                         persistMessage, messageId);
755             } catch (RemoteException e) {
756                 Log.e(TAG, "sendTextMessageInternal (no persist): Couldn't send SMS, exception - "
757                         + e.getMessage() + " " + formatCrossStackMessageId(messageId));
758                 notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
759             }
760         }
761     }
762 
763     /**
764      * Send a text based SMS without writing it into the SMS Provider.
765      *
766      * <p>
767      * The message will be sent directly over the network and will not be visible in SMS
768      * applications. Intended for internal carrier use only.
769      * </p>
770      *
771      * <p>Requires Permission: Both {@link android.Manifest.permission#SEND_SMS} and
772      * {@link android.Manifest.permission#MODIFY_PHONE_STATE}, or that the calling app has carrier
773      * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), or that the calling app is
774      * the default IMS app (see
775      * {@link CarrierConfigManager#KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING}).
776      * </p>
777      *
778      * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
779      * applications or the Telephony framework and will never trigger an SMS disambiguation
780      * dialog. If this method is called on a device that has multiple active subscriptions, this
781      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
782      * default subscription is defined, the subscription ID associated with this message will be
783      * INVALID, which will result in the SMS being sent on the subscription associated with logical
784      * slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the
785      * correct subscription.
786      * </p>
787      *
788      * @see #sendTextMessage(String, String, String, PendingIntent, PendingIntent)
789      */
790     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
791     @RequiresPermission(allOf = {
792             android.Manifest.permission.MODIFY_PHONE_STATE,
793             android.Manifest.permission.SEND_SMS
794     })
sendTextMessageWithoutPersisting( String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)795     public void sendTextMessageWithoutPersisting(
796             String destinationAddress, String scAddress, String text,
797             PendingIntent sentIntent, PendingIntent deliveryIntent) {
798         sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
799                 false /* persistMessage */, getOpPackageName(),
800                 getAttributionTag(), 0L /* messageId */);
801     }
802 
sendTextMessageInternal( String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, int priority, boolean expectMore, int validityPeriod)803     private void sendTextMessageInternal(
804             String destinationAddress, String scAddress, String text,
805             PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage,
806             int priority, boolean expectMore, int validityPeriod) {
807         if (TextUtils.isEmpty(destinationAddress)) {
808             throw new IllegalArgumentException("Invalid destinationAddress");
809         }
810 
811         if (TextUtils.isEmpty(text)) {
812             throw new IllegalArgumentException("Invalid message body");
813         }
814 
815         if (priority < 0x00 || priority > 0x03) {
816             Log.e(TAG, "Invalid Priority " + priority);
817             priority = SMS_MESSAGE_PRIORITY_NOT_SPECIFIED;
818         }
819 
820         if (validityPeriod < 0x05 || validityPeriod > 0x09b0a0) {
821             Log.e(TAG, "Invalid Validity Period " + validityPeriod);
822             validityPeriod = SMS_MESSAGE_PERIOD_NOT_SPECIFIED;
823         }
824 
825         final int finalPriority = priority;
826         final int finalValidity = validityPeriod;
827         // We will only show the SMS disambiguation dialog in the case that the message is being
828         // persisted. This is for two reasons:
829         // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific
830         //    subscription and require special permissions. These messages are usually not sent by
831         //    the device user and should not have an SMS disambiguation dialog associated with them
832         //    because the device user did not trigger them.
833         // 2) The SMS disambiguation dialog ONLY checks to make sure that the user has the SEND_SMS
834         //    permission. If we call resolveSubscriptionForOperation from a carrier/OEM app that has
835         //    the correct MODIFY_PHONE_STATE or carrier permissions, but no SEND_SMS, it will throw
836         //    an incorrect SecurityException.
837         if (persistMessage) {
838             resolveSubscriptionForOperation(new SubscriptionResolverResult() {
839                 @Override
840                 public void onSuccess(int subId) {
841                     try {
842                         ISms iSms = getISmsServiceOrThrow();
843                         if (iSms != null) {
844                             iSms.sendTextForSubscriberWithOptions(subId,
845                                     null, null, destinationAddress,
846                                     scAddress,
847                                     text, sentIntent, deliveryIntent, persistMessage, finalPriority,
848                                     expectMore, finalValidity);
849                         }
850                     } catch (RemoteException e) {
851                         Log.e(TAG, "sendTextMessageInternal: Couldn't send SMS, exception - "
852                                 + e.getMessage());
853                         notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
854                     }
855                 }
856 
857                 @Override
858                 public void onFailure() {
859                     notifySmsError(sentIntent, RESULT_NO_DEFAULT_SMS_APP);
860                 }
861             });
862         } else {
863             try {
864                 ISms iSms = getISmsServiceOrThrow();
865                 if (iSms != null) {
866                     iSms.sendTextForSubscriberWithOptions(getSubscriptionId(),
867                             null, null, destinationAddress,
868                             scAddress,
869                             text, sentIntent, deliveryIntent, persistMessage, finalPriority,
870                             expectMore, finalValidity);
871                 }
872             } catch (RemoteException e) {
873                 Log.e(TAG, "sendTextMessageInternal(no persist): Couldn't send SMS, exception - "
874                         + e.getMessage());
875                 notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
876             }
877         }
878     }
879 
880     /**
881      *
882      * Inject an SMS PDU into the android application framework.
883      *
884      * <p>Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier
885      * privileges per {@link android.telephony.TelephonyManager#hasCarrierPrivileges}.
886      *
887      * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
888      * applications or the Telephony framework and will never trigger an SMS disambiguation
889      * dialog. If this method is called on a device that has multiple active subscriptions, this
890      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
891      * default subscription is defined, the subscription ID associated with this message will be
892      * INVALID, which will result in the SMS being injected on the subscription associated with
893      * logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is
894      * delivered to the correct subscription.
895      * </p>
896      *
897      * @param pdu is the byte array of pdu to be injected into android application framework
898      * @param format is the format of SMS pdu ({@link SmsMessage#FORMAT_3GPP} or
899      *  {@link SmsMessage#FORMAT_3GPP2})
900      * @param receivedIntent if not NULL this <code>PendingIntent</code> is
901      *  broadcast when the message is successfully received by the
902      *  android application framework, or failed. This intent is broadcasted at
903      *  the same time an SMS received from radio is acknowledged back.
904      *  The result code will be {@link android.provider.Telephony.Sms.Intents#RESULT_SMS_HANDLED}
905      *  for success, or {@link android.provider.Telephony.Sms.Intents#RESULT_SMS_GENERIC_ERROR} or
906      *  {@link #RESULT_REMOTE_EXCEPTION} for error.
907      *
908      * @throws IllegalArgumentException if the format is invalid.
909      */
injectSmsPdu( byte[] pdu, @SmsMessage.Format String format, PendingIntent receivedIntent)910     public void injectSmsPdu(
911             byte[] pdu, @SmsMessage.Format String format, PendingIntent receivedIntent) {
912         if (!format.equals(SmsMessage.FORMAT_3GPP) && !format.equals(SmsMessage.FORMAT_3GPP2)) {
913             // Format must be either 3gpp or 3gpp2.
914             throw new IllegalArgumentException(
915                     "Invalid pdu format. format must be either 3gpp or 3gpp2");
916         }
917         try {
918             ISms iSms = TelephonyManager.getSmsService();
919             if (iSms != null) {
920                 iSms.injectSmsPduForSubscriber(
921                         getSubscriptionId(), pdu, format, receivedIntent);
922             }
923         } catch (RemoteException ex) {
924             try {
925                 if (receivedIntent != null) {
926                     receivedIntent.send(RESULT_REMOTE_EXCEPTION);
927                 }
928             } catch (PendingIntent.CanceledException cx) {
929                 // Don't worry about it, we do not need to notify the caller if this is the case.
930             }
931         }
932     }
933 
934     /**
935      * Divide a message text into several fragments, none bigger than the maximum SMS message size.
936      *
937      * @param text the original message. Must not be null.
938      * @return an <code>ArrayList</code> of strings that, in order, comprise the original message.
939      * @throws IllegalArgumentException if text is null.
940      */
divideMessage(String text)941     public ArrayList<String> divideMessage(String text) {
942         if (null == text) {
943             throw new IllegalArgumentException("text is null");
944         }
945         return SmsMessage.fragmentText(text, getSubscriptionId());
946     }
947 
948     /**
949      * Send a multi-part text based SMS.  The callee should have already
950      * divided the message into correctly sized parts by calling
951      * <code>divideMessage</code>.
952      *
953      * <p class="note"><strong>Note:</strong> Using this method requires that your app has the
954      * {@link android.Manifest.permission#SEND_SMS} permission.</p>
955      *
956      * <p class="note"><strong>Note:</strong> Beginning with Android 4.4 (API level 19), if
957      * <em>and only if</em> an app is not selected as the default SMS app, the system automatically
958      * writes messages sent using this method to the SMS Provider (the default SMS app is always
959      * responsible for writing its sent messages to the SMS Provider). For information about
960      * how to behave as the default SMS app, see {@link android.provider.Telephony}.</p>
961      *
962      * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
963      * manager on a multi-SIM device, this operation may fail sending the SMS message because no
964      * suitable default subscription could be found. In this case, if {@code sentIntent} is
965      * non-null, then the {@link PendingIntent} will be sent with an error code
966      * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the
967      * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions
968      * where this operation may fail.
969      * </p>
970      *
971      * @param destinationAddress the address to send the message to
972      * @param scAddress is the service center address or null to use
973      *  the current default SMSC
974      * @param parts an <code>ArrayList</code> of strings that, in order,
975      *  comprise the original message
976      * @param sentIntents if not null, an <code>ArrayList</code> of
977      *  <code>PendingIntent</code>s (one for each message part) that is
978      *  broadcast when the corresponding message part has been sent.
979      *  The result code will be <code>Activity.RESULT_OK</code> for success,
980      *  or one of these errors:<br>
981      *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
982      *  <code>RESULT_ERROR_RADIO_OFF</code><br>
983      *  <code>RESULT_ERROR_NULL_PDU</code><br>
984      *  <code>RESULT_ERROR_NO_SERVICE</code><br>
985      *  <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br>
986      *  <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
987      *  <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
988      *  <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
989      *  <code>RESULT_RADIO_NOT_AVAILABLE</code><br>
990      *  <code>RESULT_NETWORK_REJECT</code><br>
991      *  <code>RESULT_INVALID_ARGUMENTS</code><br>
992      *  <code>RESULT_INVALID_STATE</code><br>
993      *  <code>RESULT_NO_MEMORY</code><br>
994      *  <code>RESULT_INVALID_SMS_FORMAT</code><br>
995      *  <code>RESULT_SYSTEM_ERROR</code><br>
996      *  <code>RESULT_MODEM_ERROR</code><br>
997      *  <code>RESULT_NETWORK_ERROR</code><br>
998      *  <code>RESULT_ENCODING_ERROR</code><br>
999      *  <code>RESULT_INVALID_SMSC_ADDRESS</code><br>
1000      *  <code>RESULT_OPERATION_NOT_ALLOWED</code><br>
1001      *  <code>RESULT_INTERNAL_ERROR</code><br>
1002      *  <code>RESULT_NO_RESOURCES</code><br>
1003      *  <code>RESULT_CANCELLED</code><br>
1004      *  <code>RESULT_REQUEST_NOT_SUPPORTED</code><br>
1005      *  <code>RESULT_NO_BLUETOOTH_SERVICE</code><br>
1006      *  <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
1007      *  <code>RESULT_BLUETOOTH_DISCONNECTED</code><br>
1008      *  <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
1009      *  <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
1010      *  <code>RESULT_SMS_SEND_RETRY_FAILED</code><br>
1011      *  <code>RESULT_REMOTE_EXCEPTION</code><br>
1012      *  <code>RESULT_NO_DEFAULT_SMS_APP</code><br>
1013      *  <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
1014      *  <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
1015      *  <code>RESULT_RIL_NETWORK_REJECT</code><br>
1016      *  <code>RESULT_RIL_INVALID_STATE</code><br>
1017      *  <code>RESULT_RIL_INVALID_ARGUMENTS</code><br>
1018      *  <code>RESULT_RIL_NO_MEMORY</code><br>
1019      *  <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
1020      *  <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br>
1021      *  <code>RESULT_RIL_SYSTEM_ERR</code><br>
1022      *  <code>RESULT_RIL_ENCODING_ERR</code><br>
1023      *  <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
1024      *  <code>RESULT_RIL_MODEM_ERR</code><br>
1025      *  <code>RESULT_RIL_NETWORK_ERR</code><br>
1026      *  <code>RESULT_RIL_INTERNAL_ERR</code><br>
1027      *  <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
1028      *  <code>RESULT_RIL_INVALID_MODEM_STATE</code><br>
1029      *  <code>RESULT_RIL_NETWORK_NOT_READY</code><br>
1030      *  <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
1031      *  <code>RESULT_RIL_NO_RESOURCES</code><br>
1032      *  <code>RESULT_RIL_CANCELLED</code><br>
1033      *  <code>RESULT_RIL_SIM_ABSENT</code><br>
1034      *  <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
1035      *  <code>RESULT_RIL_ACCESS_BARRED</code><br>
1036      *  <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
1037      *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
1038      *  the sentIntent may include the extra "errorCode" containing a radio technology specific
1039      *  value, generally only useful for troubleshooting.<br>
1040      * @param deliveryIntents if not null, an <code>ArrayList</code> of
1041      *  <code>PendingIntent</code>s (one for each message part) that is
1042      *  broadcast when the corresponding message part has been delivered
1043      *  to the recipient.  The raw pdu of the status report is in the
1044      *  extended data ("pdu").
1045      *
1046      * @throws IllegalArgumentException if destinationAddress or data are empty
1047      */
sendMultipartTextMessage( String destinationAddress, String scAddress, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents)1048     public void sendMultipartTextMessage(
1049             String destinationAddress, String scAddress, ArrayList<String> parts,
1050             ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
1051         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
1052                 deliveryIntents, true /* persistMessage*/, getOpPackageName(),
1053                 getAttributionTag(), 0L /* messageId */);
1054     }
1055 
1056     /**
1057      * Send a multi-part text based SMS. Same as #sendMultipartTextMessage(String, String,
1058      * ArrayList, ArrayList, ArrayList), but adds an optional messageId.
1059      * @param messageId An id that uniquely identifies the message requested to be sent.
1060      * Used for logging and diagnostics purposes. The id may be 0.
1061      *
1062      * @throws IllegalArgumentException if destinationAddress or data are empty
1063      *
1064      */
sendMultipartTextMessage( @onNull String destinationAddress, @Nullable String scAddress, @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents, @Nullable List<PendingIntent> deliveryIntents, long messageId)1065     public void sendMultipartTextMessage(
1066             @NonNull String destinationAddress, @Nullable String scAddress,
1067             @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
1068             @Nullable List<PendingIntent> deliveryIntents, long messageId) {
1069         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
1070                 deliveryIntents, true /* persistMessage*/, getOpPackageName(),
1071                 getAttributionTag(), messageId);
1072     }
1073 
1074     /**
1075      * Similar method as #sendMultipartTextMessage(String, String, ArrayList, ArrayList, ArrayList)
1076      * With an additional argument.
1077      *
1078      * <p class="note"><strong>Note:</strong> This method is intended for internal use the Telephony
1079      * framework and will never trigger an SMS disambiguation dialog. If this method is called on a
1080      * device that has multiple active subscriptions, this {@link SmsManager} instance has been
1081      * created with {@link #getDefault()}, and no user-defined default subscription is defined, the
1082      * subscription ID associated with this message will be INVALID, which will result in the SMS
1083      * being sent on the subscription associated with logical slot 0. Use
1084      * {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the correct
1085      * subscription.
1086      * </p>
1087      *
1088      * @param packageName serves as the default package name if the package name that is
1089      *        associated with the user id is null.
1090      */
sendMultipartTextMessage( @onNull String destinationAddress, @Nullable String scAddress, @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents, @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName, @Nullable String attributionTag)1091     public void sendMultipartTextMessage(
1092             @NonNull String destinationAddress, @Nullable String scAddress,
1093             @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
1094             @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName,
1095             @Nullable String attributionTag) {
1096         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
1097                 deliveryIntents, true /* persistMessage*/, packageName, attributionTag,
1098                 0L /* messageId */);
1099     }
1100 
sendMultipartTextMessageInternal( String destinationAddress, String scAddress, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, boolean persistMessage, String packageName, @Nullable String attributionTag, long messageId)1101     private void sendMultipartTextMessageInternal(
1102             String destinationAddress, String scAddress, List<String> parts,
1103             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
1104             boolean persistMessage, String packageName, @Nullable String attributionTag,
1105             long messageId) {
1106         if (TextUtils.isEmpty(destinationAddress)) {
1107             throw new IllegalArgumentException("Invalid destinationAddress");
1108         }
1109         if (parts == null || parts.size() < 1) {
1110             throw new IllegalArgumentException("Invalid message body");
1111         }
1112 
1113         if (parts.size() > 1) {
1114             // We will only show the SMS disambiguation dialog in the case that the message is being
1115             // persisted. This is for two reasons:
1116             // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific
1117             //    subscription and require special permissions. These messages are usually not sent
1118             //    by the device user and should not have an SMS disambiguation dialog associated
1119             //    with them because the device user did not trigger them.
1120             // 2) The SMS disambiguation dialog ONLY checks to make sure that the user has the
1121             //    SEND_SMS permission. If we call resolveSubscriptionForOperation from a carrier/OEM
1122             //    app that has the correct MODIFY_PHONE_STATE or carrier permissions, but no
1123             //    SEND_SMS, it will throw an incorrect SecurityException.
1124             if (persistMessage) {
1125                 resolveSubscriptionForOperation(new SubscriptionResolverResult() {
1126                     @Override
1127                     public void onSuccess(int subId) {
1128                         try {
1129                             ISms iSms = getISmsServiceOrThrow();
1130                             iSms.sendMultipartTextForSubscriber(subId, packageName, attributionTag,
1131                                     destinationAddress, scAddress, parts, sentIntents,
1132                                     deliveryIntents, persistMessage, messageId);
1133                         } catch (RemoteException e) {
1134                             Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - "
1135                                     + e.getMessage() + " " + formatCrossStackMessageId(messageId));
1136                             notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION);
1137                         }
1138                     }
1139 
1140                     @Override
1141                     public void onFailure() {
1142                         notifySmsError(sentIntents, RESULT_NO_DEFAULT_SMS_APP);
1143                     }
1144                 });
1145             } else {
1146                 // Called by apps that are not user facing, don't show disambiguation dialog.
1147                 try {
1148                     ISms iSms = getISmsServiceOrThrow();
1149                     if (iSms != null) {
1150                         iSms.sendMultipartTextForSubscriber(getSubscriptionId(), packageName,
1151                                 attributionTag, destinationAddress, scAddress, parts, sentIntents,
1152                                 deliveryIntents, persistMessage, messageId);
1153                     }
1154                 } catch (RemoteException e) {
1155                     Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - "
1156                             + e.getMessage() + " " + formatCrossStackMessageId(messageId));
1157                     notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION);
1158                 }
1159             }
1160         } else {
1161             PendingIntent sentIntent = null;
1162             PendingIntent deliveryIntent = null;
1163             if (sentIntents != null && sentIntents.size() > 0) {
1164                 sentIntent = sentIntents.get(0);
1165             }
1166             if (deliveryIntents != null && deliveryIntents.size() > 0) {
1167                 deliveryIntent = deliveryIntents.get(0);
1168             }
1169             sendTextMessageInternal(destinationAddress, scAddress, parts.get(0),
1170                     sentIntent, deliveryIntent, true, packageName, attributionTag, messageId);
1171         }
1172     }
1173 
1174     /**
1175      * Send a multi-part text based SMS without writing it into the SMS Provider.
1176      *
1177      * <p>
1178      * If this method is called on a device with multiple active subscriptions, this
1179      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
1180      * default subscription is defined, the subscription ID associated with this message will be
1181      * INVALID, which will result in the SMS sent on the subscription associated with slot
1182      * 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent using the
1183      * correct subscription.
1184      * </p>
1185      *
1186      * <p>Requires Permission:
1187      * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or the calling app has carrier
1188      * privileges.
1189      * </p>
1190      *
1191      * @see #sendMultipartTextMessage(String, String, ArrayList, ArrayList, ArrayList)
1192      * @hide
1193      **/
1194     @SystemApi
1195     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
sendMultipartTextMessageWithoutPersisting( String destinationAddress, String scAddress, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents)1196     public void sendMultipartTextMessageWithoutPersisting(
1197             String destinationAddress, String scAddress, List<String> parts,
1198             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
1199         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
1200                 deliveryIntents, false /* persistMessage*/, getOpPackageName(),
1201                 getAttributionTag(), 0L /* messageId */);
1202     }
1203 
1204     /**
1205      * Send a multi-part text based SMS with messaging options. The callee should have already
1206      * divided the message into correctly sized parts by calling
1207      * <code>divideMessage</code>.
1208      *
1209      * <p class="note"><strong>Note:</strong> Using this method requires that your app has the
1210      * {@link android.Manifest.permission#SEND_SMS} permission.</p>
1211      *
1212      * <p class="note"><strong>Note:</strong> Beginning with Android 4.4 (API level 19), if
1213      * <em>and only if</em> an app is not selected as the default SMS app, the system automatically
1214      * writes messages sent using this method to the SMS Provider (the default SMS app is always
1215      * responsible for writing its sent messages to the SMS Provider). For information about
1216      * how to behave as the default SMS app, see {@link android.provider.Telephony}.</p>
1217      *
1218      * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
1219      * manager on a multi-SIM device, this operation may fail sending the SMS message because no
1220      * suitable default subscription could be found. In this case, if {@code sentIntent} is
1221      * non-null, then the {@link PendingIntent} will be sent with an error code
1222      * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the
1223      * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions
1224      * where this operation may fail.
1225      * </p>
1226      *
1227      * @param destinationAddress the address to send the message to
1228      * @param scAddress is the service center address or null to use
1229      *  the current default SMSC
1230      * @param parts an <code>ArrayList</code> of strings that, in order,
1231      *  comprise the original message
1232      * @param sentIntents if not null, an <code>ArrayList</code> of
1233      *  <code>PendingIntent</code>s (one for each message part) that is
1234      *  broadcast when the corresponding message part has been sent.
1235      *  The result code will be <code>Activity.RESULT_OK</code> for success,
1236      *  or one of these errors:<br>
1237      *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
1238      *  <code>RESULT_ERROR_RADIO_OFF</code><br>
1239      *  <code>RESULT_ERROR_NULL_PDU</code><br>
1240      *  <code>RESULT_ERROR_NO_SERVICE</code><br>
1241      *  <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br>
1242      *  <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
1243      *  <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
1244      *  <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
1245      *  <code>RESULT_RADIO_NOT_AVAILABLE</code><br>
1246      *  <code>RESULT_NETWORK_REJECT</code><br>
1247      *  <code>RESULT_INVALID_ARGUMENTS</code><br>
1248      *  <code>RESULT_INVALID_STATE</code><br>
1249      *  <code>RESULT_NO_MEMORY</code><br>
1250      *  <code>RESULT_INVALID_SMS_FORMAT</code><br>
1251      *  <code>RESULT_SYSTEM_ERROR</code><br>
1252      *  <code>RESULT_MODEM_ERROR</code><br>
1253      *  <code>RESULT_NETWORK_ERROR</code><br>
1254      *  <code>RESULT_ENCODING_ERROR</code><br>
1255      *  <code>RESULT_INVALID_SMSC_ADDRESS</code><br>
1256      *  <code>RESULT_OPERATION_NOT_ALLOWED</code><br>
1257      *  <code>RESULT_INTERNAL_ERROR</code><br>
1258      *  <code>RESULT_NO_RESOURCES</code><br>
1259      *  <code>RESULT_CANCELLED</code><br>
1260      *  <code>RESULT_REQUEST_NOT_SUPPORTED</code><br>
1261      *  <code>RESULT_NO_BLUETOOTH_SERVICE</code><br>
1262      *  <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
1263      *  <code>RESULT_BLUETOOTH_DISCONNECTED</code><br>
1264      *  <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
1265      *  <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
1266      *  <code>RESULT_SMS_SEND_RETRY_FAILED</code><br>
1267      *  <code>RESULT_REMOTE_EXCEPTION</code><br>
1268      *  <code>RESULT_NO_DEFAULT_SMS_APP</code><br>
1269      *  <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
1270      *  <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
1271      *  <code>RESULT_RIL_NETWORK_REJECT</code><br>
1272      *  <code>RESULT_RIL_INVALID_STATE</code><br>
1273      *  <code>RESULT_RIL_INVALID_ARGUMENTS</code><br>
1274      *  <code>RESULT_RIL_NO_MEMORY</code><br>
1275      *  <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
1276      *  <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br>
1277      *  <code>RESULT_RIL_SYSTEM_ERR</code><br>
1278      *  <code>RESULT_RIL_ENCODING_ERR</code><br>
1279      *  <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
1280      *  <code>RESULT_RIL_MODEM_ERR</code><br>
1281      *  <code>RESULT_RIL_NETWORK_ERR</code><br>
1282      *  <code>RESULT_RIL_INTERNAL_ERR</code><br>
1283      *  <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
1284      *  <code>RESULT_RIL_INVALID_MODEM_STATE</code><br>
1285      *  <code>RESULT_RIL_NETWORK_NOT_READY</code><br>
1286      *  <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
1287      *  <code>RESULT_RIL_NO_RESOURCES</code><br>
1288      *  <code>RESULT_RIL_CANCELLED</code><br>
1289      *  <code>RESULT_RIL_SIM_ABSENT</code><br>
1290      *  <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
1291      *  <code>RESULT_RIL_ACCESS_BARRED</code><br>
1292      *  <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
1293      *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
1294      *  the sentIntent may include the extra "errorCode" containing a radio technology specific
1295      *  value, generally only useful for troubleshooting.<br>
1296      * @param deliveryIntents if not null, an <code>ArrayList</code> of
1297      *  <code>PendingIntent</code>s (one for each message part) that is
1298      *  broadcast when the corresponding message part has been delivered
1299      *  to the recipient.  The raw pdu of the status report is in the
1300      *  extended data ("pdu").
1301      * @param priority Priority level of the message
1302      *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
1303      *  ---------------------------------
1304      *  PRIORITY      | Level of Priority
1305      *  ---------------------------------
1306      *      '00'      |     Normal
1307      *      '01'      |     Interactive
1308      *      '10'      |     Urgent
1309      *      '11'      |     Emergency
1310      *  ----------------------------------
1311      *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
1312      * @param expectMore is a boolean to indicate the sending messages through same link or not.
1313      * @param validityPeriod Validity Period of the message in mins.
1314      *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
1315      *  Validity Period(Minimum) -> 5 mins
1316      *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
1317      *  Any Other values included Negative considered as Invalid Validity Period of the message.
1318      *
1319      * @throws IllegalArgumentException if destinationAddress or data are empty
1320      * {@hide}
1321      */
1322     @UnsupportedAppUsage
sendMultipartTextMessage( String destinationAddress, String scAddress, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents, int priority, boolean expectMore, int validityPeriod)1323     public void sendMultipartTextMessage(
1324             String destinationAddress, String scAddress, ArrayList<String> parts,
1325             ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents,
1326             int priority, boolean expectMore, int validityPeriod) {
1327         sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
1328                 deliveryIntents, true /* persistMessage*/, priority, expectMore,
1329                 validityPeriod);
1330     }
1331 
sendMultipartTextMessageInternal( String destinationAddress, String scAddress, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, boolean persistMessage, int priority, boolean expectMore, int validityPeriod)1332     private void sendMultipartTextMessageInternal(
1333             String destinationAddress, String scAddress, List<String> parts,
1334             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
1335             boolean persistMessage, int priority, boolean expectMore, int validityPeriod) {
1336         if (TextUtils.isEmpty(destinationAddress)) {
1337             throw new IllegalArgumentException("Invalid destinationAddress");
1338         }
1339         if (parts == null || parts.size() < 1) {
1340             throw new IllegalArgumentException("Invalid message body");
1341         }
1342 
1343         if (priority < 0x00 || priority > 0x03) {
1344             Log.e(TAG, "Invalid Priority " + priority);
1345             priority = SMS_MESSAGE_PRIORITY_NOT_SPECIFIED;
1346         }
1347 
1348         if (validityPeriod < 0x05 || validityPeriod > 0x09b0a0) {
1349             Log.e(TAG, "Invalid Validity Period " + validityPeriod);
1350             validityPeriod = SMS_MESSAGE_PERIOD_NOT_SPECIFIED;
1351         }
1352 
1353         if (parts.size() > 1) {
1354             final int finalPriority = priority;
1355             final int finalValidity = validityPeriod;
1356             if (persistMessage) {
1357                 resolveSubscriptionForOperation(new SubscriptionResolverResult() {
1358                     @Override
1359                     public void onSuccess(int subId) {
1360                         try {
1361                             ISms iSms = getISmsServiceOrThrow();
1362                             if (iSms != null) {
1363                                 iSms.sendMultipartTextForSubscriberWithOptions(subId,
1364                                         null, null, destinationAddress,
1365                                         scAddress, parts, sentIntents, deliveryIntents,
1366                                         persistMessage, finalPriority, expectMore, finalValidity);
1367                             }
1368                         } catch (RemoteException e) {
1369                             Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - "
1370                                     + e.getMessage());
1371                             notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION);
1372                         }
1373                     }
1374 
1375                     @Override
1376                     public void onFailure() {
1377                         notifySmsError(sentIntents, RESULT_NO_DEFAULT_SMS_APP);
1378                     }
1379                 });
1380             } else {
1381                 // Sent by apps that are not user visible, so don't show SIM disambiguation dialog.
1382                 try {
1383                     ISms iSms = getISmsServiceOrThrow();
1384                     if (iSms != null) {
1385                         iSms.sendMultipartTextForSubscriberWithOptions(getSubscriptionId(),
1386                                 null, null, destinationAddress,
1387                                 scAddress, parts, sentIntents, deliveryIntents,
1388                                 persistMessage, finalPriority, expectMore, finalValidity);
1389                     }
1390                 } catch (RemoteException e) {
1391                     Log.e(TAG, "sendMultipartTextMessageInternal (no persist): Couldn't send SMS - "
1392                             + e.getMessage());
1393                     notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION);
1394                 }
1395             }
1396         } else {
1397             PendingIntent sentIntent = null;
1398             PendingIntent deliveryIntent = null;
1399             if (sentIntents != null && sentIntents.size() > 0) {
1400                 sentIntent = sentIntents.get(0);
1401             }
1402             if (deliveryIntents != null && deliveryIntents.size() > 0) {
1403                 deliveryIntent = deliveryIntents.get(0);
1404             }
1405             sendTextMessageInternal(destinationAddress, scAddress, parts.get(0),
1406                     sentIntent, deliveryIntent, persistMessage, priority, expectMore,
1407                     validityPeriod);
1408         }
1409     }
1410 
1411     /**
1412      * Send a data based SMS to a specific application port.
1413      *
1414      * <p class="note"><strong>Note:</strong> Using this method requires that your app has the
1415      * {@link android.Manifest.permission#SEND_SMS} permission.</p>
1416      *
1417      * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
1418      * manager on a multi-SIM device, this operation may fail sending the SMS message because no
1419      * suitable default subscription could be found. In this case, if {@code sentIntent} is
1420      * non-null, then the {@link PendingIntent} will be sent with an error code
1421      * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the
1422      * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions
1423      * where this operation may fail.
1424      * </p>
1425      *
1426      * @param destinationAddress the address to send the message to
1427      * @param scAddress is the service center address or null to use
1428      *  the current default SMSC
1429      * @param destinationPort the port to deliver the message to
1430      * @param data the body of the message to send
1431      * @param sentIntent if not NULL this <code>PendingIntent</code> is
1432      *  broadcast when the message is successfully sent, or failed.
1433      *  The result code will be <code>Activity.RESULT_OK</code> for success,
1434      *  or one of these errors:<br>
1435      *  <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
1436      *  <code>RESULT_ERROR_RADIO_OFF</code><br>
1437      *  <code>RESULT_ERROR_NULL_PDU</code><br>
1438      *  <code>RESULT_ERROR_NO_SERVICE</code><br>
1439      *  <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br>
1440      *  <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
1441      *  <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
1442      *  <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
1443      *  <code>RESULT_RADIO_NOT_AVAILABLE</code><br>
1444      *  <code>RESULT_NETWORK_REJECT</code><br>
1445      *  <code>RESULT_INVALID_ARGUMENTS</code><br>
1446      *  <code>RESULT_INVALID_STATE</code><br>
1447      *  <code>RESULT_NO_MEMORY</code><br>
1448      *  <code>RESULT_INVALID_SMS_FORMAT</code><br>
1449      *  <code>RESULT_SYSTEM_ERROR</code><br>
1450      *  <code>RESULT_MODEM_ERROR</code><br>
1451      *  <code>RESULT_NETWORK_ERROR</code><br>
1452      *  <code>RESULT_ENCODING_ERROR</code><br>
1453      *  <code>RESULT_INVALID_SMSC_ADDRESS</code><br>
1454      *  <code>RESULT_OPERATION_NOT_ALLOWED</code><br>
1455      *  <code>RESULT_INTERNAL_ERROR</code><br>
1456      *  <code>RESULT_NO_RESOURCES</code><br>
1457      *  <code>RESULT_CANCELLED</code><br>
1458      *  <code>RESULT_REQUEST_NOT_SUPPORTED</code><br>
1459      *  <code>RESULT_NO_BLUETOOTH_SERVICE</code><br>
1460      *  <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
1461      *  <code>RESULT_BLUETOOTH_DISCONNECTED</code><br>
1462      *  <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
1463      *  <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
1464      *  <code>RESULT_SMS_SEND_RETRY_FAILED</code><br>
1465      *  <code>RESULT_REMOTE_EXCEPTION</code><br>
1466      *  <code>RESULT_NO_DEFAULT_SMS_APP</code><br>
1467      *  <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
1468      *  <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
1469      *  <code>RESULT_RIL_NETWORK_REJECT</code><br>
1470      *  <code>RESULT_RIL_INVALID_STATE</code><br>
1471      *  <code>RESULT_RIL_INVALID_ARGUMENTS</code><br>
1472      *  <code>RESULT_RIL_NO_MEMORY</code><br>
1473      *  <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
1474      *  <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br>
1475      *  <code>RESULT_RIL_SYSTEM_ERR</code><br>
1476      *  <code>RESULT_RIL_ENCODING_ERR</code><br>
1477      *  <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
1478      *  <code>RESULT_RIL_MODEM_ERR</code><br>
1479      *  <code>RESULT_RIL_NETWORK_ERR</code><br>
1480      *  <code>RESULT_RIL_INTERNAL_ERR</code><br>
1481      *  <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
1482      *  <code>RESULT_RIL_INVALID_MODEM_STATE</code><br>
1483      *  <code>RESULT_RIL_NETWORK_NOT_READY</code><br>
1484      *  <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
1485      *  <code>RESULT_RIL_NO_RESOURCES</code><br>
1486      *  <code>RESULT_RIL_CANCELLED</code><br>
1487      *  <code>RESULT_RIL_SIM_ABSENT</code><br>
1488      *  <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
1489      *  <code>RESULT_RIL_ACCESS_BARRED</code><br>
1490      *  <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
1491      *  For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
1492      *  the sentIntent may include the extra "errorCode" containing a radio technology specific
1493      *  value, generally only useful for troubleshooting.<br>
1494      * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
1495      *  broadcast when the message is delivered to the recipient.  The
1496      *  raw pdu of the status report is in the extended data ("pdu").
1497      *
1498      * @throws IllegalArgumentException if destinationAddress or data are empty
1499      */
sendDataMessage( String destinationAddress, String scAddress, short destinationPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent)1500     public void sendDataMessage(
1501             String destinationAddress, String scAddress, short destinationPort,
1502             byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
1503         if (TextUtils.isEmpty(destinationAddress)) {
1504             throw new IllegalArgumentException("Invalid destinationAddress");
1505         }
1506 
1507         if (data == null || data.length == 0) {
1508             throw new IllegalArgumentException("Invalid message data");
1509         }
1510 
1511         resolveSubscriptionForOperation(new SubscriptionResolverResult() {
1512             @Override
1513             public void onSuccess(int subId) {
1514                 try {
1515                     ISms iSms = getISmsServiceOrThrow();
1516                     iSms.sendDataForSubscriber(subId, null, null, destinationAddress, scAddress,
1517                             destinationPort & 0xFFFF, data, sentIntent, deliveryIntent);
1518                 } catch (RemoteException e) {
1519                     Log.e(TAG, "sendDataMessage: Couldn't send SMS - Exception: " + e.getMessage());
1520                     notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
1521                 }
1522             }
1523             @Override
1524             public void onFailure() {
1525                 notifySmsError(sentIntent, RESULT_NO_DEFAULT_SMS_APP);
1526             }
1527         });
1528     }
1529 
1530     /**
1531      * Get the SmsManager associated with the default subscription id. The instance will always be
1532      * associated with the default subscription id, even if the default subscription id changes.
1533      *
1534      * <p class="note"><strong>Note:</strong> For devices that support multiple active subscriptions
1535      * at a time, SmsManager will track the subscription set by the user as the default SMS
1536      * subscription. If the user has not set a default, {@link SmsManager} may
1537      * start an activity to kick off a subscription disambiguation dialog. Most operations will not
1538      * complete until the user has chosen the subscription that will be associated with the
1539      * operation. If the user cancels the dialog without choosing a subscription, one of the
1540      * following will happen, depending on the target SDK version of the application. For
1541      * compatibility purposes, if the target SDK level is <= 28, telephony will still send the SMS
1542      * over the first available subscription. If the target SDK level is > 28, the operation will
1543      * fail to complete.
1544      * </p>
1545      *
1546      * <p class="note"><strong>Note:</strong> If this method is used to perform an operation on a
1547      * device that has multiple active subscriptions, the user has not set a default SMS
1548      * subscription, and the operation is being performed while the application is not in the
1549      * foreground, the SMS disambiguation dialog will not be shown. The result of the operation will
1550      * conclude as if the user cancelled the disambiguation dialog and the operation will finish as
1551      * outlined above, depending on the target SDK version of the calling application. It is safer
1552      * to use {@link #getSmsManagerForSubscriptionId(int)} if the application will perform the
1553      * operation while in the background because this can cause unpredictable results, such as the
1554      * operation being sent over the wrong subscription or failing completely, depending on the
1555      * user's default SMS subscription setting.
1556      * </p>
1557      *
1558      * @return the {@link SmsManager} associated with the default subscription id.
1559      *
1560      * @see SubscriptionManager#getDefaultSmsSubscriptionId()
1561      *
1562      * @deprecated Use {@link Context#getSystemService Context.getSystemService(SmsManager.class)}
1563      * instead
1564      */
1565     @Deprecated
getDefault()1566     public static SmsManager getDefault() {
1567         return DEFAULT_INSTANCE;
1568     }
1569 
1570     /**
1571      * Get the instance of the SmsManager associated with a particular context and subscription ID.
1572      *
1573      * @param context The context the manager belongs to
1574      * @param subId an SMS subscription ID, typically accessed using {@link SubscriptionManager}
1575      *
1576      * @return the instance of the SmsManager associated with subscription
1577      *
1578      * @hide
1579      */
getSmsManagerForContextAndSubscriptionId( @ullable Context context, int subId)1580     public static @NonNull SmsManager getSmsManagerForContextAndSubscriptionId(
1581             @Nullable Context context, int subId) {
1582         synchronized(sLockObject) {
1583             Pair<Context, Integer> key = new Pair<>(context, subId);
1584 
1585             SmsManager smsManager = sSubInstances.get(key);
1586             if (smsManager == null) {
1587                 smsManager = new SmsManager(context, subId);
1588                 sSubInstances.put(key, smsManager);
1589             }
1590             return smsManager;
1591         }
1592     }
1593 
1594     /**
1595      * Get the instance of the SmsManager associated with a particular subscription ID.
1596      *
1597      * <p class="note"><strong>Note:</strong> Constructing an {@link SmsManager} in this manner will
1598      * never cause an SMS disambiguation dialog to appear, unlike {@link #getDefault()}.
1599      * </p>
1600      *
1601      * @param subId an SMS subscription ID, typically accessed using {@link SubscriptionManager}
1602      * @return the instance of the SmsManager associated with subscription
1603      *
1604      * @see SubscriptionManager#getActiveSubscriptionInfoList()
1605      * @see SubscriptionManager#getDefaultSmsSubscriptionId()
1606      * @deprecated Use {@link Context#getSystemService Context.getSystemService(SmsManager.class)}
1607      * .{@link #createForSubscriptionId createForSubscriptionId(subId)} instead
1608      */
1609     @Deprecated
getSmsManagerForSubscriptionId(int subId)1610     public static SmsManager getSmsManagerForSubscriptionId(int subId) {
1611         return getSmsManagerForContextAndSubscriptionId(null, subId);
1612     }
1613 
1614     /**
1615      * Get the instance of the SmsManager associated with a particular subscription ID.
1616      *
1617      * <p class="note"><strong>Note:</strong> Constructing an {@link SmsManager} in this manner will
1618      * never cause an SMS disambiguation dialog to appear, unlike {@link #getDefault()}.
1619      * </p>
1620      *
1621      * @param subId an SMS subscription ID, typically accessed using {@link SubscriptionManager}
1622      * @return the instance of the SmsManager associated with subscription
1623      *
1624      * @see SubscriptionManager#getActiveSubscriptionInfoList()
1625      * @see SubscriptionManager#getDefaultSmsSubscriptionId()
1626      */
createForSubscriptionId(int subId)1627     public @NonNull SmsManager createForSubscriptionId(int subId) {
1628         return getSmsManagerForContextAndSubscriptionId(mContext, subId);
1629     }
1630 
SmsManager(@ullable Context context, int subId)1631     private SmsManager(@Nullable Context context, int subId) {
1632         mContext = context;
1633         mSubId = subId;
1634     }
1635 
1636     /**
1637      * Get the associated subscription id. If the instance was returned by {@link #getDefault()},
1638      * then this method may return different values at different points in time (if the user
1639      * changes the default subscription id).
1640      *
1641      * <p class="note"><strong>Note:</strong> This method used to display a disambiguation dialog to
1642      * the user asking them to choose a default subscription to send SMS messages over if they
1643      * haven't chosen yet. Starting in API level 29, we allow the user to not have a default set as
1644      * a valid option for the default SMS subscription on multi-SIM devices. We no longer show the
1645      * disambiguation dialog and return {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if the
1646      * device has multiple active subscriptions and no default is set.
1647      * </p>
1648      *
1649      * @return associated subscription ID or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if
1650      * the default subscription id cannot be determined or the device has multiple active
1651      * subscriptions and and no default is set ("ask every time") by the user.
1652      */
getSubscriptionId()1653     public int getSubscriptionId() {
1654         try {
1655             return (mSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)
1656                     ? getISmsServiceOrThrow().getPreferredSmsSubscription() : mSubId;
1657         } catch (RemoteException e) {
1658             return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1659         }
1660     }
1661 
1662     /**
1663      * Resolves the subscription id to use for the associated operation if
1664      * {@link #getSubscriptionId()} returns {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
1665      *
1666      * If app targets API level 28 or below and they are either sending the SMS from the background
1667      * or the device has more than one active subscription available and no default is set, we will
1668      * use the first logical slot to send the SMS and possibly fail later in the SMS sending
1669      * process.
1670      *
1671      * Regardless of the API level, if the app is the foreground app, then we will show the SMS
1672      * disambiguation dialog. If the app is in the background and tries to perform an operation, we
1673      * will not show the disambiguation dialog.
1674      *
1675      * See {@link #getDefault()} for a detailed explanation of how this method operates.
1676      *
1677      * @param resolverResult The callback that will be called when the subscription is resolved or
1678      *                       fails to be resolved.
1679      */
resolveSubscriptionForOperation(SubscriptionResolverResult resolverResult)1680     private void resolveSubscriptionForOperation(SubscriptionResolverResult resolverResult) {
1681         int subId = getSubscriptionId();
1682         boolean isSmsSimPickActivityNeeded = false;
1683         try {
1684             ISms iSms = getISmsService();
1685             if (iSms != null) {
1686                 // Determines if the SMS SIM pick activity should be shown. This is only shown if:
1687                 // 1) The device has multiple active subscriptions and an SMS default subscription
1688                 //    hasn't been set, and
1689                 // 2) SmsManager is being called from the foreground app.
1690                 // Android does not allow background activity starts, so we need to block this.
1691                 // if Q+, do not perform requested operation if these two operations are not set. If
1692                 // <P, perform these operations on phone 0 (for compatibility purposes, since we
1693                 // used to not wait for the result of this activity).
1694                 isSmsSimPickActivityNeeded = iSms.isSmsSimPickActivityNeeded(subId);
1695             }
1696         } catch (RemoteException ex) {
1697             Log.e(TAG, "resolveSubscriptionForOperation", ex);
1698         }
1699         if (!isSmsSimPickActivityNeeded) {
1700             sendResolverResult(resolverResult, subId, false /*pickActivityShown*/);
1701             return;
1702         }
1703         // We need to ask the user pick an appropriate subid for the operation.
1704         Log.d(TAG, "resolveSubscriptionForOperation isSmsSimPickActivityNeeded is true for calling"
1705                 + " package. ");
1706         try {
1707             // Create the SMS pick activity and call back once the activity is complete. Can't do
1708             // it here because we do not have access to the activity context that is performing this
1709             // operation.
1710             // Requires that the calling process has the SEND_SMS permission.
1711             getITelephony().enqueueSmsPickResult(null, null,
1712                     new IIntegerConsumer.Stub() {
1713                         @Override
1714                         public void accept(int subId) {
1715                             // Runs on binder thread attached to this app's process.
1716                             sendResolverResult(resolverResult, subId, true /*pickActivityShown*/);
1717                         }
1718                     });
1719         } catch (RemoteException ex) {
1720             Log.e(TAG, "Unable to launch activity", ex);
1721             // pickActivityShown is true here because we want to call sendResolverResult and always
1722             // have this operation fail. This is because we received a RemoteException here, which
1723             // means that telephony is not available and the next operation to Telephony will fail
1724             // as well anyways, so we might as well shortcut fail here first.
1725             sendResolverResult(resolverResult, subId, true /*pickActivityShown*/);
1726         }
1727     }
1728 
1729     /**
1730      * To check the SDK version for SmsManager.sendResolverResult method.
1731      */
1732     @ChangeId
1733     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.P)
1734     private static final long GET_TARGET_SDK_VERSION_CODE_CHANGE = 145147528L;
1735 
sendResolverResult(SubscriptionResolverResult resolverResult, int subId, boolean pickActivityShown)1736     private void sendResolverResult(SubscriptionResolverResult resolverResult, int subId,
1737             boolean pickActivityShown) {
1738         if (SubscriptionManager.isValidSubscriptionId(subId)) {
1739             resolverResult.onSuccess(subId);
1740             return;
1741         }
1742 
1743         if (!Compatibility.isChangeEnabled(GET_TARGET_SDK_VERSION_CODE_CHANGE)
1744                 && !pickActivityShown) {
1745             // Do not fail, return a success with an INVALID subid for apps targeting P or below
1746             // that tried to perform an operation and the SMS disambiguation dialog was never shown,
1747             // as these applications may not have been written to handle the failure case properly.
1748             // This will resolve to performing the operation on phone 0 in telephony.
1749             resolverResult.onSuccess(subId);
1750         } else {
1751             // Fail if the app targets Q or above or it targets P and below and the disambiguation
1752             // dialog was shown and the user clicked out of it.
1753             resolverResult.onFailure();
1754         }
1755     }
1756 
getITelephony()1757     private static ITelephony getITelephony() {
1758         ITelephony binder = ITelephony.Stub.asInterface(
1759                 TelephonyFrameworkInitializer
1760                         .getTelephonyServiceManager()
1761                         .getTelephonyServiceRegisterer()
1762                         .get());
1763         if (binder == null) {
1764             throw new RuntimeException("Could not find Telephony Service.");
1765         }
1766         return binder;
1767     }
1768 
notifySmsError(PendingIntent pendingIntent, int error)1769     private static void notifySmsError(PendingIntent pendingIntent, int error) {
1770         if (pendingIntent != null) {
1771             try {
1772                 pendingIntent.send(error);
1773             } catch (PendingIntent.CanceledException e) {
1774                 // Don't worry about it, we do not need to notify the caller if this is the case.
1775             }
1776         }
1777     }
1778 
notifySmsError(List<PendingIntent> pendingIntents, int error)1779     private static void notifySmsError(List<PendingIntent> pendingIntents, int error) {
1780         if (pendingIntents != null) {
1781             for (PendingIntent pendingIntent : pendingIntents) {
1782                 notifySmsError(pendingIntent, error);
1783             }
1784         }
1785     }
1786 
1787     /**
1788      * Returns the ISms service, or throws an UnsupportedOperationException if
1789      * the service does not exist.
1790      */
getISmsServiceOrThrow()1791     private static ISms getISmsServiceOrThrow() {
1792         ISms iSms = TelephonyManager.getSmsService();
1793         if (iSms == null) {
1794             throw new UnsupportedOperationException("Sms is not supported");
1795         }
1796         return iSms;
1797     }
1798 
getISmsService()1799     private static ISms getISmsService() {
1800         return TelephonyManager.getSmsService();
1801     }
1802 
1803     /**
1804      * Copies a raw SMS PDU to the ICC.
1805      * ICC (Integrated Circuit Card) is the card of the device.
1806      * For example, this can be the SIM or USIM for GSM.
1807      *
1808      * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
1809      * applications or the Telephony framework and will never trigger an SMS disambiguation
1810      * dialog. If this method is called on a device that has multiple active subscriptions, this
1811      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
1812      * default subscription is defined, the subscription ID associated with this message will be
1813      * INVALID, which will result in the operation being completed on the subscription associated
1814      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
1815      * operation is performed on the correct subscription.
1816      * </p>
1817      *
1818      * @param smsc the SMSC for this messag or null for the default SMSC.
1819      * @param pdu the raw PDU to store.
1820      * @param status message status. One of these status:
1821      *               <code>STATUS_ON_ICC_READ</code>
1822      *               <code>STATUS_ON_ICC_UNREAD</code>
1823      *               <code>STATUS_ON_ICC_SENT</code>
1824      *               <code>STATUS_ON_ICC_UNSENT</code>
1825      * @return true for success. Otherwise false.
1826      *
1827      * @throws IllegalArgumentException if pdu is null.
1828      * @hide
1829      */
1830     @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC)
copyMessageToIcc( @ullable byte[] smsc, @NonNull byte[] pdu, @StatusOnIcc int status)1831     public boolean copyMessageToIcc(
1832             @Nullable byte[] smsc, @NonNull byte[] pdu, @StatusOnIcc int status) {
1833         boolean success = false;
1834 
1835         if (pdu == null) {
1836             throw new IllegalArgumentException("pdu is null");
1837         }
1838         try {
1839             ISms iSms = getISmsService();
1840             if (iSms != null) {
1841                 success = iSms.copyMessageToIccEfForSubscriber(getSubscriptionId(),
1842                         null,
1843                         status, pdu, smsc);
1844             }
1845         } catch (RemoteException ex) {
1846             // ignore it
1847         }
1848 
1849         return success;
1850     }
1851 
1852     /**
1853      * Deletes the specified message from the ICC.
1854      * ICC (Integrated Circuit Card) is the card of the device.
1855      * For example, this can be the SIM or USIM for GSM.
1856      *
1857      * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
1858      * applications or the Telephony framework and will never trigger an SMS disambiguation
1859      * dialog. If this method is called on a device that has multiple active subscriptions, this
1860      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
1861      * default subscription is defined, the subscription ID associated with this message will be
1862      * INVALID, which will result in the operation being completed on the subscription associated
1863      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
1864      * operation is performed on the correct subscription.
1865      * </p>
1866      *
1867      * @param messageIndex the message index of the message in the ICC (1-based index).
1868      * @return true for success, false if the operation fails. Failure can be due to IPC failure,
1869      * RIL/modem error which results in SMS failed to be deleted on SIM
1870      *
1871      * {@hide}
1872      */
1873     @UnsupportedAppUsage
1874     @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC)
deleteMessageFromIcc(int messageIndex)1875     public boolean deleteMessageFromIcc(int messageIndex) {
1876         boolean success = false;
1877 
1878         try {
1879             ISms iSms = getISmsService();
1880             if (iSms != null) {
1881                 success = iSms.updateMessageOnIccEfForSubscriber(getSubscriptionId(),
1882                         null,
1883                         messageIndex, STATUS_ON_ICC_FREE, null /* pdu */);
1884             }
1885         } catch (RemoteException ex) {
1886             // ignore it
1887         }
1888 
1889         return success;
1890     }
1891 
1892     /**
1893      * Update the specified message on the ICC.
1894      * ICC (Integrated Circuit Card) is the card of the device.
1895      * For example, this can be the SIM or USIM for GSM.
1896      *
1897      * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
1898      * applications or the Telephony framework and will never trigger an SMS disambiguation
1899      * dialog. If this method is called on a device that has multiple active subscriptions, this
1900      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
1901      * default subscription is defined, the subscription ID associated with this message will be
1902      * INVALID, which will result in the operation being completed on the subscription associated
1903      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
1904      * operation is performed on the correct subscription.
1905      * </p>
1906      *
1907      * @param messageIndex record index of message to update
1908      * @param newStatus new message status (STATUS_ON_ICC_READ,
1909      *                  STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
1910      *                  STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
1911      * @param pdu the raw PDU to store
1912      * @return true for success
1913      *
1914      * {@hide}
1915      */
1916     @UnsupportedAppUsage
1917     @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC)
updateMessageOnIcc(int messageIndex, int newStatus, byte[] pdu)1918     public boolean updateMessageOnIcc(int messageIndex, int newStatus, byte[] pdu) {
1919         boolean success = false;
1920 
1921         try {
1922             ISms iSms = getISmsService();
1923             if (iSms != null) {
1924                 success = iSms.updateMessageOnIccEfForSubscriber(getSubscriptionId(),
1925                         null,
1926                         messageIndex, newStatus, pdu);
1927             }
1928         } catch (RemoteException ex) {
1929             // ignore it
1930         }
1931 
1932         return success;
1933     }
1934 
1935     /**
1936      * Retrieves all messages currently stored on the ICC.
1937      * ICC (Integrated Circuit Card) is the card of the device.
1938      * For example, this can be the SIM or USIM for GSM.
1939      *
1940      * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
1941      * applications or the Telephony framework and will never trigger an SMS disambiguation
1942      * dialog. If this method is called on a device that has multiple active subscriptions, this
1943      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
1944      * default subscription is defined, the subscription ID associated with this message will be
1945      * INVALID, which will result in the operation being completed on the subscription associated
1946      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
1947      * operation is performed on the correct subscription.
1948      * </p>
1949      *
1950      * @return <code>List</code> of <code>SmsMessage</code> objects for valid records only.
1951      *
1952      * {@hide}
1953      */
1954     @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC)
getMessagesFromIcc()1955     public @NonNull List<SmsMessage> getMessagesFromIcc() {
1956         return getAllMessagesFromIcc();
1957     }
1958 
1959     /**
1960      * @return <code>ArrayList</code> of <code>SmsMessage</code> objects
1961      *
1962      * This is similar to {@link #getMessagesFromIcc} except that it will return ArrayList.
1963      * Suggested to use {@link #getMessagesFromIcc} instead.
1964      *
1965      * {@hide}
1966      */
1967     @UnsupportedAppUsage
getAllMessagesFromIcc()1968     public ArrayList<SmsMessage> getAllMessagesFromIcc() {
1969         List<SmsRawData> records = null;
1970 
1971         try {
1972             ISms iSms = getISmsService();
1973             if (iSms != null) {
1974                 records = iSms.getAllMessagesFromIccEfForSubscriber(
1975                         getSubscriptionId(),
1976                         null);
1977             }
1978         } catch (RemoteException ex) {
1979             // ignore it
1980         }
1981 
1982         return createMessageListFromRawRecords(records);
1983     }
1984 
1985     /**
1986      * Enable reception of cell broadcast (SMS-CB) messages with the given
1987      * message identifier range and RAN type. The RAN type specifies if this message ID
1988      * belongs to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients enable
1989      * the same message identifier, they must both disable it for the device to stop
1990      * receiving those messages. All received messages will be broadcast in an
1991      * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED".
1992      * Note: This call is blocking, callers may want to avoid calling it from
1993      * the main thread of an application.
1994      *
1995      * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
1996      * applications or the Telephony framework and will never trigger an SMS disambiguation
1997      * dialog. If this method is called on a device that has multiple active subscriptions, this
1998      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
1999      * default subscription is defined, the subscription ID associated with this message will be
2000      * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}, which will result in the operation
2001      * being completed on the subscription associated with logical slot 0. Use
2002      * {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation is performed on the
2003      * correct subscription.
2004      * </p>
2005      *
2006      * <p>Requires {@link android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST}</p>
2007      *
2008      * @param startMessageId first message identifier as specified in TS 23.041 (3GPP)
2009      * or C.R1001-G (3GPP2)
2010      * @param endMessageId last message identifier as specified in TS 23.041 (3GPP)
2011      * or C.R1001-G (3GPP2)
2012      * @param ranType the message format as defined in {@link SmsCbMessage}
2013      * @return true if successful, false if the modem reports a failure (e.g. the given range or
2014      * RAN type is invalid).
2015      * @see #disableCellBroadcastRange(int, int, int)
2016      *
2017      * @throws IllegalArgumentException if endMessageId < startMessageId
2018      * @deprecated Use {@link TelephonyManager#setCellBroadcastIdRanges} instead.
2019      * {@hide}
2020      */
2021     @Deprecated
2022     @SystemApi
enableCellBroadcastRange(int startMessageId, int endMessageId, @android.telephony.SmsCbMessage.MessageFormat int ranType)2023     public boolean enableCellBroadcastRange(int startMessageId, int endMessageId,
2024             @android.telephony.SmsCbMessage.MessageFormat int ranType) {
2025         boolean success = false;
2026         if (endMessageId < startMessageId) {
2027             throw new IllegalArgumentException("endMessageId < startMessageId");
2028         }
2029         try {
2030             ISms iSms = getISmsService();
2031             if (iSms != null) {
2032                 // If getSubscriptionId() returns INVALID or an inactive subscription, we will use
2033                 // the default phone internally.
2034                 int subId = getSubscriptionId();
2035                 success = iSms.enableCellBroadcastRangeForSubscriber(subId,
2036                         startMessageId, endMessageId, ranType);
2037                 Rlog.d(TAG, "enableCellBroadcastRange: " + (success ? "succeeded" : "failed")
2038                         + " at calling enableCellBroadcastRangeForSubscriber. subId = " + subId);
2039             }
2040         } catch (RemoteException ex) {
2041             Rlog.d(TAG, "enableCellBroadcastRange: ", ex);
2042             // ignore it
2043         }
2044 
2045         return success;
2046     }
2047 
2048     /**
2049      * Disable reception of cell broadcast (SMS-CB) messages with the given
2050      * message identifier range and RAN type. The RAN type specify this message
2051      * ID range belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different
2052      * clients enable the same message identifier, they must both disable it for
2053      * the device to stop receiving those messages.
2054      * Note: This call is blocking, callers may want to avoid calling it from
2055      * the main thread of an application.
2056      *
2057      * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
2058      * applications or the Telephony framework and will never trigger an SMS disambiguation
2059      * dialog. If this method is called on a device that has multiple active subscriptions, this
2060      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
2061      * default subscription is defined, the subscription ID associated with this message will be
2062      * INVALID, which will result in the operation being completed on the subscription associated
2063      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
2064      * operation is performed on the correct subscription.
2065      * </p>
2066      *
2067      * <p>Requires {@link android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST}</p>
2068      *
2069      * @param startMessageId first message identifier as specified in TS 23.041 (3GPP)
2070      * or C.R1001-G (3GPP2)
2071      * @param endMessageId last message identifier as specified in TS 23.041 (3GPP)
2072      * or C.R1001-G (3GPP2)
2073      * @param ranType the message format as defined in {@link SmsCbMessage}
2074      * @return true if successful, false if the modem reports a failure (e.g. the given range or
2075      * RAN type is invalid).
2076      *
2077      * @see #enableCellBroadcastRange(int, int, int)
2078      *
2079      * @throws IllegalArgumentException if endMessageId < startMessageId
2080      * @deprecated Use {@link TelephonyManager#setCellBroadcastIdRanges} instead.
2081      * {@hide}
2082      */
2083     @Deprecated
2084     @SystemApi
disableCellBroadcastRange(int startMessageId, int endMessageId, @android.telephony.SmsCbMessage.MessageFormat int ranType)2085     public boolean disableCellBroadcastRange(int startMessageId, int endMessageId,
2086             @android.telephony.SmsCbMessage.MessageFormat int ranType) {
2087         boolean success = false;
2088 
2089         if (endMessageId < startMessageId) {
2090             throw new IllegalArgumentException("endMessageId < startMessageId");
2091         }
2092         try {
2093             ISms iSms = getISmsService();
2094             if (iSms != null) {
2095                 // If getSubscriptionId() returns INVALID or an inactive subscription, we will use
2096                 // the default phone internally.
2097                 int subId = getSubscriptionId();
2098                 success = iSms.disableCellBroadcastRangeForSubscriber(subId,
2099                         startMessageId, endMessageId, ranType);
2100                 Rlog.d(TAG, "disableCellBroadcastRange: " + (success ? "succeeded" : "failed")
2101                         + " at calling disableCellBroadcastRangeForSubscriber. subId = " + subId);
2102             }
2103         } catch (RemoteException ex) {
2104             Rlog.d(TAG, "disableCellBroadcastRange: ", ex);
2105             // ignore it
2106         }
2107 
2108         return success;
2109     }
2110 
2111     /**
2112      * Creates a list of <code>SmsMessage</code>s from a list of SmsRawData records.
2113      *
2114      * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
2115      * applications or the Telephony framework and will never trigger an SMS disambiguation
2116      * dialog. If this method is called on a device that has multiple active subscriptions, this
2117      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
2118      * default subscription is defined, the subscription ID associated with this message will be
2119      * INVALID, which will result in the operation being completed on the subscription associated
2120      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
2121      * operation is performed on the correct subscription.
2122      * </p>
2123      *
2124      * @param records SMS EF records.
2125      * @return <code>ArrayList</code> of <code>SmsMessage</code> objects.
2126      */
createMessageListFromRawRecords(List<SmsRawData> records)2127     private ArrayList<SmsMessage> createMessageListFromRawRecords(List<SmsRawData> records) {
2128         ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>();
2129         if (records != null) {
2130             int count = records.size();
2131             for (int i = 0; i < count; i++) {
2132                 SmsRawData data = records.get(i);
2133                 // List contains all records, including "free" records (null)
2134                 if (data != null) {
2135                     SmsMessage sms = SmsMessage.createFromEfRecord(i + 1, data.getBytes(),
2136                             getSubscriptionId());
2137                     if (sms != null) {
2138                         messages.add(sms);
2139                     }
2140                 }
2141             }
2142         }
2143         return messages;
2144     }
2145 
2146     /**
2147      * SMS over IMS is supported if IMS is registered and SMS is supported
2148      * on IMS.
2149      *
2150      * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
2151      * applications or the Telephony framework and will never trigger an SMS disambiguation
2152      * dialog. If this method is called on a device that has multiple active subscriptions, this
2153      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
2154      * default subscription is defined, the subscription ID associated with this message will be
2155      * INVALID, which will result in the operation being completed on the subscription associated
2156      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
2157      * operation is performed on the correct subscription.
2158      * </p>
2159      *
2160      * @return true if SMS over IMS is supported, false otherwise
2161      *
2162      * @see #getImsSmsFormat()
2163      *
2164      * @hide
2165      */
isImsSmsSupported()2166     public boolean isImsSmsSupported() {
2167         boolean boSupported = false;
2168         try {
2169             ISms iSms = getISmsService();
2170             if (iSms != null) {
2171                 boSupported = iSms.isImsSmsSupportedForSubscriber(getSubscriptionId());
2172             }
2173         } catch (RemoteException ex) {
2174             // ignore it
2175         }
2176         return boSupported;
2177     }
2178 
2179     /**
2180      * Gets SMS format supported on IMS.  SMS over IMS format is either 3GPP or 3GPP2.
2181      *
2182      * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
2183      * applications or the Telephony framework and will never trigger an SMS disambiguation
2184      * dialog. If this method is called on a device that has multiple active subscriptions, this
2185      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
2186      * default subscription is defined, the subscription ID associated with this message will be
2187      * INVALID, which will result in the operation being completed on the subscription associated
2188      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
2189      * operation is performed on the correct subscription.
2190      * </p>
2191      *
2192      * @return SmsMessage.FORMAT_3GPP,
2193      *         SmsMessage.FORMAT_3GPP2
2194      *      or SmsMessage.FORMAT_UNKNOWN
2195      *
2196      * @see #isImsSmsSupported()
2197      *
2198      * @hide
2199      */
getImsSmsFormat()2200     public String getImsSmsFormat() {
2201         String format = com.android.internal.telephony.SmsConstants.FORMAT_UNKNOWN;
2202         try {
2203             ISms iSms = getISmsService();
2204             if (iSms != null) {
2205                 format = iSms.getImsSmsFormatForSubscriber(getSubscriptionId());
2206             }
2207         } catch (RemoteException ex) {
2208             // ignore it
2209         }
2210         return format;
2211     }
2212 
2213     /**
2214      * Get default sms subscription id.
2215      *
2216      * <p class="note"><strong>Note:</strong>This returns a value different from
2217      * {@link SubscriptionManager#getDefaultSmsSubscriptionId} if the user has not chosen a default.
2218      * In this case it returns the active subscription id if there's only one active subscription
2219      * available.
2220      *
2221      * @return the user-defined default SMS subscription id, or the active subscription id if
2222      * there's only one active subscription available, otherwise
2223      * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
2224      */
getDefaultSmsSubscriptionId()2225     public static int getDefaultSmsSubscriptionId() {
2226         try {
2227             return getISmsService().getPreferredSmsSubscription();
2228         } catch (RemoteException e) {
2229             return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2230         } catch (NullPointerException e) {
2231             return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2232         }
2233     }
2234 
2235     /**
2236      * Get SMS prompt property,  enabled or not
2237      *
2238      * @return true if enabled, false otherwise
2239      * @hide
2240      */
2241     @UnsupportedAppUsage
isSMSPromptEnabled()2242     public boolean isSMSPromptEnabled() {
2243         ISms iSms = null;
2244         try {
2245             iSms = TelephonyManager.getSmsService();
2246             return iSms.isSMSPromptEnabled();
2247         } catch (RemoteException ex) {
2248             return false;
2249         } catch (NullPointerException ex) {
2250             return false;
2251         }
2252     }
2253 
2254     /**
2255      * Gets the total capacity of SMS storage on the SIM card.
2256      *
2257      * <p>
2258      * This is the number of 176 byte EF-SMS records which can be stored on the SIM card.
2259      * See 3GPP TS 31.102 - 4.2.25 - EF-SMS for more information.
2260      * </p>
2261      *
2262      * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
2263      * dialog. If this method is called on a device that has multiple active subscriptions, this
2264      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
2265      * default subscription is defined, the subscription ID associated with this method will be
2266      * INVALID, which will result in the operation being completed on the subscription associated
2267      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation
2268      * is performed on the correct subscription.
2269      * </p>
2270      *
2271      * @return the total number of SMS records which can be stored on the SIM card.
2272      */
2273     @RequiresPermission(anyOf = {android.Manifest.permission.READ_PHONE_STATE,
2274             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE})
2275     @IntRange(from = 0)
getSmsCapacityOnIcc()2276     public int getSmsCapacityOnIcc() {
2277         int ret = 0;
2278         try {
2279             ISms iccISms = getISmsService();
2280             if (iccISms != null) {
2281                 ret = iccISms.getSmsCapacityOnIccForSubscriber(getSubscriptionId());
2282             }
2283         } catch (RemoteException ex) {
2284             Log.e(TAG, "getSmsCapacityOnIcc() RemoteException", ex);
2285         }
2286         return ret;
2287     }
2288 
2289     /** @hide */
2290     @IntDef(prefix = { "STATUS_ON_ICC_" }, value = {
2291             STATUS_ON_ICC_FREE,
2292             STATUS_ON_ICC_READ,
2293             STATUS_ON_ICC_UNREAD,
2294             STATUS_ON_ICC_SENT,
2295             STATUS_ON_ICC_UNSENT
2296     })
2297     @Retention(RetentionPolicy.SOURCE)
2298     public @interface StatusOnIcc {}
2299 
2300     // see SmsMessage.getStatusOnIcc
2301 
2302     /** Free space (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
2303     public static final int STATUS_ON_ICC_FREE      = 0;
2304 
2305     /** Received and read (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
2306     public static final int STATUS_ON_ICC_READ      = 1;
2307 
2308     /** Received and unread (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
2309     public static final int STATUS_ON_ICC_UNREAD    = 3;
2310 
2311     /** Stored and sent (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
2312     public static final int STATUS_ON_ICC_SENT      = 5;
2313 
2314     /** Stored and unsent (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
2315     public static final int STATUS_ON_ICC_UNSENT    = 7;
2316 
2317     // SMS send failure result codes
2318 
2319     /** @hide */
2320     @IntDef(prefix = { "RESULT" }, value = {
2321             RESULT_ERROR_NONE,
2322             RESULT_ERROR_GENERIC_FAILURE,
2323             RESULT_ERROR_RADIO_OFF,
2324             RESULT_ERROR_NULL_PDU,
2325             RESULT_ERROR_NO_SERVICE,
2326             RESULT_ERROR_LIMIT_EXCEEDED,
2327             RESULT_ERROR_FDN_CHECK_FAILURE,
2328             RESULT_ERROR_SHORT_CODE_NOT_ALLOWED,
2329             RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED,
2330             RESULT_RADIO_NOT_AVAILABLE,
2331             RESULT_NETWORK_REJECT,
2332             RESULT_INVALID_ARGUMENTS,
2333             RESULT_INVALID_STATE,
2334             RESULT_NO_MEMORY,
2335             RESULT_INVALID_SMS_FORMAT,
2336             RESULT_SYSTEM_ERROR,
2337             RESULT_MODEM_ERROR,
2338             RESULT_NETWORK_ERROR,
2339             RESULT_INVALID_SMSC_ADDRESS,
2340             RESULT_OPERATION_NOT_ALLOWED,
2341             RESULT_INTERNAL_ERROR,
2342             RESULT_NO_RESOURCES,
2343             RESULT_CANCELLED,
2344             RESULT_REQUEST_NOT_SUPPORTED,
2345             RESULT_NO_BLUETOOTH_SERVICE,
2346             RESULT_INVALID_BLUETOOTH_ADDRESS,
2347             RESULT_BLUETOOTH_DISCONNECTED,
2348             RESULT_UNEXPECTED_EVENT_STOP_SENDING,
2349             RESULT_SMS_BLOCKED_DURING_EMERGENCY,
2350             RESULT_SMS_SEND_RETRY_FAILED,
2351             RESULT_REMOTE_EXCEPTION,
2352             RESULT_NO_DEFAULT_SMS_APP,
2353             RESULT_USER_NOT_ALLOWED,
2354             RESULT_RIL_RADIO_NOT_AVAILABLE,
2355             RESULT_RIL_SMS_SEND_FAIL_RETRY,
2356             RESULT_RIL_NETWORK_REJECT,
2357             RESULT_RIL_INVALID_STATE,
2358             RESULT_RIL_INVALID_ARGUMENTS,
2359             RESULT_RIL_NO_MEMORY,
2360             RESULT_RIL_REQUEST_RATE_LIMITED,
2361             RESULT_RIL_INVALID_SMS_FORMAT,
2362             RESULT_RIL_SYSTEM_ERR,
2363             RESULT_RIL_ENCODING_ERR,
2364             RESULT_RIL_INVALID_SMSC_ADDRESS,
2365             RESULT_RIL_MODEM_ERR,
2366             RESULT_RIL_NETWORK_ERR,
2367             RESULT_RIL_INTERNAL_ERR,
2368             RESULT_RIL_REQUEST_NOT_SUPPORTED,
2369             RESULT_RIL_INVALID_MODEM_STATE,
2370             RESULT_RIL_NETWORK_NOT_READY,
2371             RESULT_RIL_OPERATION_NOT_ALLOWED,
2372             RESULT_RIL_NO_RESOURCES,
2373             RESULT_RIL_CANCELLED,
2374             RESULT_RIL_SIM_ABSENT,
2375             RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED,
2376             RESULT_RIL_ACCESS_BARRED,
2377             RESULT_RIL_BLOCKED_DUE_TO_CALL,
2378             RESULT_RIL_GENERIC_ERROR,
2379             RESULT_RIL_INVALID_RESPONSE,
2380             RESULT_RIL_SIM_PIN2,
2381             RESULT_RIL_SIM_PUK2,
2382             RESULT_RIL_SUBSCRIPTION_NOT_AVAILABLE,
2383             RESULT_RIL_SIM_ERROR,
2384             RESULT_RIL_INVALID_SIM_STATE,
2385             RESULT_RIL_NO_SMS_TO_ACK,
2386             RESULT_RIL_SIM_BUSY,
2387             RESULT_RIL_SIM_FULL,
2388             RESULT_RIL_NO_SUBSCRIPTION,
2389             RESULT_RIL_NO_NETWORK_FOUND,
2390             RESULT_RIL_DEVICE_IN_USE,
2391             RESULT_RIL_ABORTED
2392     })
2393     @Retention(RetentionPolicy.SOURCE)
2394     public @interface Result {}
2395 
2396     /**
2397      * No error.
2398      */
2399     public static final int RESULT_ERROR_NONE    = 0;
2400 
2401     /** Generic failure cause */
2402     public static final int RESULT_ERROR_GENERIC_FAILURE    = 1;
2403 
2404     /** Failed because radio was explicitly turned off */
2405     public static final int RESULT_ERROR_RADIO_OFF          = 2;
2406 
2407     /** Failed because no pdu provided */
2408     public static final int RESULT_ERROR_NULL_PDU           = 3;
2409 
2410     /** Failed because service is currently unavailable */
2411     public static final int RESULT_ERROR_NO_SERVICE         = 4;
2412 
2413     /** Failed because we reached the sending queue limit. */
2414     public static final int RESULT_ERROR_LIMIT_EXCEEDED     = 5;
2415 
2416     /**
2417      * Failed because FDN is enabled.
2418      */
2419     public static final int RESULT_ERROR_FDN_CHECK_FAILURE  = 6;
2420 
2421     /** Failed because user denied the sending of this short code. */
2422     public static final int RESULT_ERROR_SHORT_CODE_NOT_ALLOWED = 7;
2423 
2424     /** Failed because the user has denied this app ever send premium short codes. */
2425     public static final int RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED = 8;
2426 
2427     /**
2428      * Failed because the radio was not available
2429      */
2430     public static final int RESULT_RADIO_NOT_AVAILABLE = 9;
2431 
2432     /**
2433      * Failed because of network rejection
2434      */
2435     public static final int RESULT_NETWORK_REJECT = 10;
2436 
2437     /**
2438      * Failed because of invalid arguments
2439      */
2440     public static final int RESULT_INVALID_ARGUMENTS = 11;
2441 
2442     /**
2443      * Failed because of an invalid state
2444      */
2445     public static final int RESULT_INVALID_STATE = 12;
2446 
2447     /**
2448      * Failed because there is no memory
2449      */
2450     public static final int RESULT_NO_MEMORY = 13;
2451 
2452     /**
2453      * Failed because the sms format is not valid
2454      */
2455     public static final int RESULT_INVALID_SMS_FORMAT = 14;
2456 
2457     /**
2458      * Failed because of a system error
2459      */
2460     public static final int RESULT_SYSTEM_ERROR = 15;
2461 
2462     /**
2463      * Failed because of a modem error
2464      */
2465     public static final int RESULT_MODEM_ERROR = 16;
2466 
2467     /**
2468      * Failed because of a network error
2469      */
2470     public static final int RESULT_NETWORK_ERROR = 17;
2471 
2472     /**
2473      * Failed because of an encoding error
2474      */
2475     public static final int RESULT_ENCODING_ERROR = 18;
2476 
2477     /**
2478      * Failed because of an invalid smsc address
2479      */
2480     public static final int RESULT_INVALID_SMSC_ADDRESS = 19;
2481 
2482     /**
2483      * Failed because the operation is not allowed
2484      */
2485     public static final int RESULT_OPERATION_NOT_ALLOWED = 20;
2486 
2487     /**
2488      * Failed because of an internal error
2489      */
2490     public static final int RESULT_INTERNAL_ERROR = 21;
2491 
2492     /**
2493      * Failed because there are no resources
2494      */
2495     public static final int RESULT_NO_RESOURCES = 22;
2496 
2497     /**
2498      * Failed because the operation was cancelled
2499      */
2500     public static final int RESULT_CANCELLED = 23;
2501 
2502     /**
2503      * Failed because the request is not supported
2504      */
2505     public static final int RESULT_REQUEST_NOT_SUPPORTED = 24;
2506 
2507     /**
2508      * Failed sending via bluetooth because the bluetooth service is not available
2509      */
2510     public static final int RESULT_NO_BLUETOOTH_SERVICE = 25;
2511 
2512     /**
2513      * Failed sending via bluetooth because the bluetooth device address is invalid
2514      */
2515     public static final int RESULT_INVALID_BLUETOOTH_ADDRESS = 26;
2516 
2517     /**
2518      * Failed sending via bluetooth because bluetooth disconnected
2519      */
2520     public static final int RESULT_BLUETOOTH_DISCONNECTED = 27;
2521 
2522     /**
2523      * Failed sending because the user denied or canceled the dialog displayed for a premium
2524      * shortcode sms or rate-limited sms.
2525      */
2526     public static final int RESULT_UNEXPECTED_EVENT_STOP_SENDING = 28;
2527 
2528     /**
2529      * Failed sending during an emergency call
2530      */
2531     public static final int RESULT_SMS_BLOCKED_DURING_EMERGENCY = 29;
2532 
2533     /**
2534      * Failed to send an sms retry
2535      */
2536     public static final int RESULT_SMS_SEND_RETRY_FAILED = 30;
2537 
2538     /**
2539      * Set by BroadcastReceiver to indicate a remote exception while handling a message.
2540      */
2541     public static final int RESULT_REMOTE_EXCEPTION = 31;
2542 
2543     /**
2544      * Set by BroadcastReceiver to indicate there's no default sms app.
2545      */
2546     public static final int RESULT_NO_DEFAULT_SMS_APP = 32;
2547 
2548     /**
2549      * User is not associated with the subscription.
2550      */
2551     public static final int RESULT_USER_NOT_ALLOWED = 33;
2552 
2553     // Radio Error results
2554 
2555     /**
2556      * The radio did not start or is resetting.
2557      */
2558     public static final int RESULT_RIL_RADIO_NOT_AVAILABLE = 100;
2559 
2560     /**
2561      * The radio failed to send the sms and needs to retry.
2562      */
2563     public static final int RESULT_RIL_SMS_SEND_FAIL_RETRY = 101;
2564 
2565     /**
2566      * The sms request was rejected by the network.
2567      */
2568     public static final int RESULT_RIL_NETWORK_REJECT = 102;
2569 
2570     /**
2571      * The radio returned an unexpected request for the current state.
2572      */
2573     public static final int RESULT_RIL_INVALID_STATE = 103;
2574 
2575     /**
2576      * The radio received invalid arguments in the request.
2577      */
2578     public static final int RESULT_RIL_INVALID_ARGUMENTS = 104;
2579 
2580     /**
2581      * The radio didn't have sufficient memory to process the request.
2582      */
2583     public static final int RESULT_RIL_NO_MEMORY = 105;
2584 
2585     /**
2586      * The radio denied the operation due to overly-frequent requests.
2587      */
2588     public static final int RESULT_RIL_REQUEST_RATE_LIMITED = 106;
2589 
2590     /**
2591      * The radio returned an error indicating invalid sms format.
2592      */
2593     public static final int RESULT_RIL_INVALID_SMS_FORMAT = 107;
2594 
2595     /**
2596      * The radio encountered a platform or system error.
2597      */
2598     public static final int RESULT_RIL_SYSTEM_ERR = 108;
2599 
2600     /**
2601      * The SMS message was not encoded properly.
2602      */
2603     public static final int RESULT_RIL_ENCODING_ERR = 109;
2604 
2605     /**
2606      * The specified SMSC address was invalid.
2607      */
2608     public static final int RESULT_RIL_INVALID_SMSC_ADDRESS = 110;
2609 
2610     /**
2611      * The vendor RIL received an unexpected or incorrect response.
2612      */
2613     public static final int RESULT_RIL_MODEM_ERR = 111;
2614 
2615     /**
2616      * The radio received an error from the network.
2617      */
2618     public static final int RESULT_RIL_NETWORK_ERR = 112;
2619 
2620     /**
2621      * The modem encountered an unexpected error scenario while handling the request.
2622      */
2623     public static final int RESULT_RIL_INTERNAL_ERR = 113;
2624 
2625     /**
2626      * The request was not supported by the radio.
2627      */
2628     public static final int RESULT_RIL_REQUEST_NOT_SUPPORTED = 114;
2629 
2630     /**
2631      * The radio cannot process the request in the current modem state.
2632      */
2633     public static final int RESULT_RIL_INVALID_MODEM_STATE = 115;
2634 
2635     /**
2636      * The network is not ready to perform the request.
2637      */
2638     public static final int RESULT_RIL_NETWORK_NOT_READY = 116;
2639 
2640     /**
2641      * The radio reports the request is not allowed.
2642      */
2643     public static final int RESULT_RIL_OPERATION_NOT_ALLOWED = 117;
2644 
2645     /**
2646      * There are insufficient resources to process the request.
2647      */
2648     public static final int RESULT_RIL_NO_RESOURCES = 118;
2649 
2650     /**
2651      * The request has been cancelled.
2652      */
2653     public static final int RESULT_RIL_CANCELLED = 119;
2654 
2655     /**
2656      * The radio failed to set the location where the CDMA subscription
2657      * can be retrieved because the SIM or RUIM is absent.
2658      */
2659     public static final int RESULT_RIL_SIM_ABSENT = 120;
2660 
2661     /**
2662      * 1X voice and SMS are not allowed simultaneously.
2663      */
2664     public static final int RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED = 121;
2665 
2666     /**
2667      * Access is barred.
2668      */
2669     public static final int RESULT_RIL_ACCESS_BARRED = 122;
2670 
2671     /**
2672      * SMS is blocked due to call control, e.g., resource unavailable in the SMR entity.
2673      */
2674     public static final int RESULT_RIL_BLOCKED_DUE_TO_CALL = 123;
2675 
2676     /**
2677      * A RIL error occurred during the SMS send.
2678      */
2679     public static final int RESULT_RIL_GENERIC_ERROR = 124;
2680 
2681     /**
2682      * A RIL internal error when one of the RIL layers receives an unrecognized response from a
2683      * lower layer.
2684      */
2685     public static final int RESULT_RIL_INVALID_RESPONSE = 125;
2686 
2687     /**
2688      * Operation requires SIM PIN2 to be entered
2689      */
2690     public static final int RESULT_RIL_SIM_PIN2 = 126;
2691 
2692     /**
2693      * Operation requires SIM PUK2 to be entered
2694      */
2695     public static final int RESULT_RIL_SIM_PUK2 = 127;
2696 
2697     /**
2698      * Fail to find CDMA subscription from specified location
2699      */
2700     public static final int RESULT_RIL_SUBSCRIPTION_NOT_AVAILABLE = 128;
2701 
2702     /**
2703      * Received error from SIM card
2704      */
2705     public static final int RESULT_RIL_SIM_ERROR = 129;
2706 
2707     /**
2708      * Cannot process the request in current SIM state
2709      */
2710     public static final int RESULT_RIL_INVALID_SIM_STATE = 130;
2711 
2712     /**
2713      * ACK received when there is no SMS to ack
2714      */
2715     public static final int RESULT_RIL_NO_SMS_TO_ACK = 131;
2716 
2717     /**
2718      * SIM is busy
2719      */
2720     public static final int RESULT_RIL_SIM_BUSY = 132;
2721 
2722     /**
2723      * The target EF is full
2724      */
2725     public static final int RESULT_RIL_SIM_FULL = 133;
2726 
2727     /**
2728      * Device does not have subscription
2729      */
2730     public static final int RESULT_RIL_NO_SUBSCRIPTION = 134;
2731 
2732     /**
2733      * Network cannot be found
2734      */
2735     public static final int RESULT_RIL_NO_NETWORK_FOUND = 135;
2736 
2737     /**
2738      * Operation cannot be performed because the device is currently in use
2739      */
2740     public static final int RESULT_RIL_DEVICE_IN_USE = 136;
2741 
2742     /**
2743      * Operation aborted
2744      */
2745     public static final int RESULT_RIL_ABORTED = 137;
2746 
2747 
2748     // SMS receiving results sent as a "result" extra in {@link Intents.SMS_REJECTED_ACTION}
2749 
2750     /**
2751      * SMS receive dispatch failure.
2752      */
2753     public static final int RESULT_RECEIVE_DISPATCH_FAILURE = 500;
2754 
2755     /**
2756      * SMS receive injected null PDU.
2757      */
2758     public static final int RESULT_RECEIVE_INJECTED_NULL_PDU = 501;
2759 
2760     /**
2761      * SMS receive encountered runtime exception.
2762      */
2763     public static final int RESULT_RECEIVE_RUNTIME_EXCEPTION = 502;
2764 
2765     /**
2766      * SMS received null message from the radio interface layer.
2767      */
2768     public static final int RESULT_RECEIVE_NULL_MESSAGE_FROM_RIL = 503;
2769 
2770     /**
2771      * SMS short code received while the phone is in encrypted state.
2772      */
2773     public static final int RESULT_RECEIVE_WHILE_ENCRYPTED = 504;
2774 
2775     /**
2776      * SMS receive encountered an SQL exception.
2777      */
2778     public static final int RESULT_RECEIVE_SQL_EXCEPTION = 505;
2779 
2780     /**
2781      * SMS receive an exception parsing a uri.
2782      */
2783     public static final int RESULT_RECEIVE_URI_EXCEPTION = 506;
2784 
2785 
2786 
2787     /**
2788      * Send an MMS message
2789      *
2790      * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
2791      * manager on a multi-SIM device, this operation may fail sending the MMS message because no
2792      * suitable default subscription could be found. In this case, if {@code sentIntent} is
2793      * non-null, then the {@link PendingIntent} will be sent with an error code
2794      * {@code RESULT_NO_DEFAULT_SMS_APP}. See {@link #getDefault()} for more information on the
2795      * conditions where this operation may fail.
2796      * </p>
2797      *
2798      * @param context application context
2799      * @param contentUri the content Uri from which the message pdu will be read
2800      * @param locationUrl the optional location url where message should be sent to
2801      * @param configOverrides the carrier-specific messaging configuration values to override for
2802      *  sending the message.
2803      * @param sentIntent if not NULL this <code>PendingIntent</code> is
2804      *  broadcast when the message is successfully sent, or failed
2805      * The result code will be <code>Activity.RESULT_OK</code> for success
2806      * or one of these errors:<br>
2807      * <code>MMS_ERROR_UNSPECIFIED</code><br>
2808      * <code>MMS_ERROR_INVALID_APN</code><br>
2809      * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br>
2810      * <code>MMS_ERROR_HTTP_FAILURE</code><br>
2811      * <code>MMS_ERROR_IO_ERROR</code><br>
2812      * <code>MMS_ERROR_RETRY</code><br>
2813      * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br>
2814      * <code>MMS_ERROR_NO_DATA_NETWORK</code><br>
2815      * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br>
2816      * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br>
2817      * <code>MMS_ERROR_DATA_DISABLED</code><br>
2818      * @throws IllegalArgumentException if contentUri is empty
2819      */
sendMultimediaMessage(Context context, Uri contentUri, String locationUrl, Bundle configOverrides, PendingIntent sentIntent)2820     public void sendMultimediaMessage(Context context, Uri contentUri, String locationUrl,
2821             Bundle configOverrides, PendingIntent sentIntent) {
2822         sendMultimediaMessage(context, contentUri, locationUrl, configOverrides, sentIntent,
2823                 0L /* messageId */);
2824     }
2825 
2826     /**
2827      * Send an MMS message
2828      *
2829      * Same as {@link #sendMultimediaMessage(Context context, Uri contentUri, String locationUrl,
2830      *           Bundle configOverrides, PendingIntent sentIntent)}, but adds an optional messageId.
2831      * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
2832      * manager on a multi-SIM device, this operation may fail sending the MMS message because no
2833      * suitable default subscription could be found. In this case, if {@code sentIntent} is
2834      * non-null, then the {@link PendingIntent} will be sent with an error code
2835      * {@code RESULT_NO_DEFAULT_SMS_APP}. See {@link #getDefault()} for more information on the
2836      * conditions where this operation may fail.
2837      * </p>
2838      *
2839      * @param context application context
2840      * @param contentUri the content Uri from which the message pdu will be read
2841      * @param locationUrl the optional location url where message should be sent to
2842      * @param configOverrides the carrier-specific messaging configuration values to override for
2843      *  sending the message.
2844      * @param sentIntent if not NULL this <code>PendingIntent</code> is
2845      *  broadcast when the message is successfully sent, or failed
2846      * The result code will be <code>Activity.RESULT_OK</code> for success
2847      * or one of these errors:<br>
2848      * <code>MMS_ERROR_UNSPECIFIED</code><br>
2849      * <code>MMS_ERROR_INVALID_APN</code><br>
2850      * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br>
2851      * <code>MMS_ERROR_HTTP_FAILURE</code><br>
2852      * <code>MMS_ERROR_IO_ERROR</code><br>
2853      * <code>MMS_ERROR_RETRY</code><br>
2854      * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br>
2855      * <code>MMS_ERROR_NO_DATA_NETWORK</code><br>
2856      * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br>
2857      * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br>
2858      * <code>MMS_ERROR_DATA_DISABLED</code><br>
2859      * @param messageId an id that uniquely identifies the message requested to be sent.
2860      * Used for logging and diagnostics purposes. The id may be 0.
2861      * @throws IllegalArgumentException if contentUri is empty
2862      */
sendMultimediaMessage(@onNull Context context, @NonNull Uri contentUri, @Nullable String locationUrl, @SuppressWarnings(R) @Nullable Bundle configOverrides, @Nullable PendingIntent sentIntent, long messageId)2863     public void sendMultimediaMessage(@NonNull Context context, @NonNull Uri contentUri,
2864             @Nullable String locationUrl,
2865             @SuppressWarnings("NullableCollection") @Nullable Bundle configOverrides,
2866             @Nullable PendingIntent sentIntent, long messageId) {
2867         if (contentUri == null) {
2868             throw new IllegalArgumentException("Uri contentUri null");
2869         }
2870         MmsManager m = (MmsManager) context.getSystemService(Context.MMS_SERVICE);
2871         if (m != null) {
2872             resolveSubscriptionForOperation(new SubscriptionResolverResult() {
2873                 @Override
2874                 public void onSuccess(int subId) {
2875                     m.sendMultimediaMessage(subId, contentUri, locationUrl, configOverrides,
2876                             sentIntent, messageId);
2877                 }
2878 
2879                 @Override
2880                 public void onFailure() {
2881                     notifySmsError(sentIntent, RESULT_NO_DEFAULT_SMS_APP);
2882                 }
2883             });
2884         }
2885     }
2886 
2887     /**
2888      * Download an MMS message from carrier by a given location URL
2889      *
2890      * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
2891      * manager on a multi-SIM device, this operation may fail downloading the MMS message because no
2892      * suitable default subscription could be found. In this case, if {@code downloadedIntent} is
2893      * non-null, then the {@link PendingIntent} will be sent with an error code
2894      * {@code RESULT_NO_DEFAULT_SMS_APP}. See {@link #getDefault()} for more information on the
2895      * conditions where this operation may fail.
2896      * </p>
2897      *
2898      * @param context application context
2899      * @param locationUrl the location URL of the MMS message to be downloaded, usually obtained
2900      *  from the MMS WAP push notification
2901      * @param contentUri the content uri to which the downloaded pdu will be written
2902      * @param configOverrides the carrier-specific messaging configuration values to override for
2903      *  downloading the message.
2904      * @param downloadedIntent if not NULL this <code>PendingIntent</code> is
2905      *  broadcast when the message is downloaded, or the download is failed
2906      * The result code will be <code>Activity.RESULT_OK</code> for success
2907      * or one of these errors:<br>
2908      * <code>MMS_ERROR_UNSPECIFIED</code><br>
2909      * <code>MMS_ERROR_INVALID_APN</code><br>
2910      * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br>
2911      * <code>MMS_ERROR_HTTP_FAILURE</code><br>
2912      * <code>MMS_ERROR_IO_ERROR</code><br>
2913      * <code>MMS_ERROR_RETRY</code><br>
2914      * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br>
2915      * <code>MMS_ERROR_NO_DATA_NETWORK</code><br>
2916      * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br>
2917      * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br>
2918      * <code>MMS_ERROR_DATA_DISABLED</code><br>
2919      * @throws IllegalArgumentException if locationUrl or contentUri is empty
2920      */
downloadMultimediaMessage(Context context, String locationUrl, Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent)2921     public void downloadMultimediaMessage(Context context, String locationUrl, Uri contentUri,
2922             Bundle configOverrides, PendingIntent downloadedIntent) {
2923         downloadMultimediaMessage(context, locationUrl, contentUri, configOverrides,
2924                 downloadedIntent, 0L /* messageId */);
2925     }
2926 
2927     /**
2928      * Download an MMS message from carrier by a given location URL
2929      *
2930      * Same as {@link #downloadMultimediaMessage(Context context, String locationUrl,
2931      *      Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent)},
2932      *      but adds an optional messageId.
2933      * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
2934      * manager on a multi-SIM device, this operation may fail downloading the MMS message because no
2935      * suitable default subscription could be found. In this case, if {@code downloadedIntent} is
2936      * non-null, then the {@link PendingIntent} will be sent with an error code
2937      * {@code RESULT_NO_DEFAULT_SMS_APP}. See {@link #getDefault()} for more information on the
2938      * conditions where this operation may fail.
2939      * </p>
2940      *
2941      * @param context application context
2942      * @param locationUrl the location URL of the MMS message to be downloaded, usually obtained
2943      *  from the MMS WAP push notification
2944      * @param contentUri the content uri to which the downloaded pdu will be written
2945      * @param configOverrides the carrier-specific messaging configuration values to override for
2946      *  downloading the message.
2947      * @param downloadedIntent if not NULL this <code>PendingIntent</code> is
2948      *  broadcast when the message is downloaded, or the download is failed
2949      * The result code will be <code>Activity.RESULT_OK</code> for success
2950      * or one of these errors:<br>
2951      * <code>MMS_ERROR_UNSPECIFIED</code><br>
2952      * <code>MMS_ERROR_INVALID_APN</code><br>
2953      * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br>
2954      * <code>MMS_ERROR_HTTP_FAILURE</code><br>
2955      * <code>MMS_ERROR_IO_ERROR</code><br>
2956      * <code>MMS_ERROR_RETRY</code><br>
2957      * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br>
2958      * <code>MMS_ERROR_NO_DATA_NETWORK</code><br>
2959      * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br>
2960      * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br>
2961      * <code>MMS_ERROR_DATA_DISABLED</code><br>
2962      * @param messageId an id that uniquely identifies the message requested to be downloaded.
2963      * Used for logging and diagnostics purposes. The id may be 0.
2964      * @throws IllegalArgumentException if locationUrl or contentUri is empty
2965      */
downloadMultimediaMessage(@onNull Context context, @NonNull String locationUrl, @NonNull Uri contentUri, @SuppressWarnings(R) @Nullable Bundle configOverrides, @Nullable PendingIntent downloadedIntent, long messageId)2966     public void downloadMultimediaMessage(@NonNull Context context, @NonNull String locationUrl,
2967             @NonNull Uri contentUri,
2968             @SuppressWarnings("NullableCollection") @Nullable Bundle configOverrides,
2969             @Nullable PendingIntent downloadedIntent, long messageId) {
2970         if (TextUtils.isEmpty(locationUrl)) {
2971             throw new IllegalArgumentException("Empty MMS location URL");
2972         }
2973         if (contentUri == null) {
2974             throw new IllegalArgumentException("Uri contentUri null");
2975         }
2976         MmsManager m = (MmsManager) context.getSystemService(Context.MMS_SERVICE);
2977         if (m != null) {
2978             resolveSubscriptionForOperation(new SubscriptionResolverResult() {
2979                 @Override
2980                 public void onSuccess(int subId) {
2981                     m.downloadMultimediaMessage(subId, locationUrl, contentUri, configOverrides,
2982                             downloadedIntent, messageId);
2983                 }
2984 
2985                 @Override
2986                 public void onFailure() {
2987                     notifySmsError(downloadedIntent, RESULT_NO_DEFAULT_SMS_APP);
2988                 }
2989             });
2990         }
2991     }
2992 
2993     // MMS send/download failure result codes
2994 
2995     /**
2996      * Unspecific MMS error occurred during send/download.
2997      */
2998     public static final int MMS_ERROR_UNSPECIFIED = 1;
2999 
3000     /**
3001      * ApnException occurred during MMS network setup.
3002      */
3003     public static final int MMS_ERROR_INVALID_APN = 2;
3004 
3005     /**
3006      * An error occurred during the MMS connection setup.
3007      */
3008     public static final int MMS_ERROR_UNABLE_CONNECT_MMS = 3;
3009 
3010     /**
3011      * An error occurred during the HTTP client setup.
3012      */
3013     public static final int MMS_ERROR_HTTP_FAILURE = 4;
3014 
3015     /**
3016      * An I/O error occurred reading the PDU.
3017      */
3018     public static final int MMS_ERROR_IO_ERROR = 5;
3019 
3020     /**
3021      * An error occurred while retrying sending/downloading the MMS.
3022      */
3023     public static final int MMS_ERROR_RETRY = 6;
3024 
3025     /**
3026      * The carrier-dependent configuration values could not be loaded.
3027      */
3028     public static final int MMS_ERROR_CONFIGURATION_ERROR = 7;
3029 
3030     /**
3031      * There is no data network.
3032      */
3033     public static final int MMS_ERROR_NO_DATA_NETWORK = 8;
3034 
3035     /**
3036      * The subscription id for the send/download is invalid.
3037      */
3038     public static final int MMS_ERROR_INVALID_SUBSCRIPTION_ID = 9;
3039 
3040     /**
3041      * The subscription id for the send/download is inactive.
3042      */
3043     public static final int MMS_ERROR_INACTIVE_SUBSCRIPTION = 10;
3044 
3045     /**
3046      * Data is disabled for the MMS APN.
3047      */
3048     public static final int MMS_ERROR_DATA_DISABLED = 11;
3049 
3050     /** Intent extra name for MMS sending result data in byte array type */
3051     public static final String EXTRA_MMS_DATA = "android.telephony.extra.MMS_DATA";
3052     /** Intent extra name for HTTP status code for MMS HTTP failure in integer type */
3053     public static final String EXTRA_MMS_HTTP_STATUS = "android.telephony.extra.MMS_HTTP_STATUS";
3054 
3055     /**
3056      * Get carrier-dependent MMS configuration values.
3057      *
3058      * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
3059      * applications or the Telephony framework and will never trigger an SMS disambiguation dialog.
3060      * If this method is called on a device that has multiple active subscriptions, this {@link
3061      * SmsManager} instance has been created with {@link #getDefault()}, and no user-defined default
3062      * subscription is defined, the subscription ID associated with this message will be INVALID,
3063      * which will result in the operation being completed on the subscription associated with
3064      * logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation is
3065      * performed on the correct subscription.
3066      * </p>
3067      *
3068      * @return the bundle key/values pairs that contains MMS configuration values
3069      *  or an empty Bundle if they cannot be found.
3070      */
getCarrierConfigValues()3071     @NonNull public Bundle getCarrierConfigValues() {
3072         try {
3073             ISms iSms = getISmsService();
3074             if (iSms != null) {
3075                 return iSms.getCarrierConfigValuesForSubscriber(getSubscriptionId());
3076             }
3077         } catch (RemoteException ex) {
3078             // ignore it
3079         }
3080         return new Bundle();
3081     }
3082 
3083     /**
3084      * Create a single use app specific incoming SMS request for the calling package.
3085      *
3086      * This method returns a token that if included in a subsequent incoming SMS message will cause
3087      * {@code intent} to be sent with the SMS data.
3088      *
3089      * The token is only good for one use, after an SMS has been received containing the token all
3090      * subsequent SMS messages with the token will be routed as normal.
3091      *
3092      * An app can only have one request at a time, if the app already has a request pending it will
3093      * be replaced with a new request.
3094      *
3095      * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
3096      * dialog. If this method is called on a device that has multiple active subscriptions, this
3097      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
3098      * default subscription is defined, the subscription ID associated with this message will be
3099      * INVALID, which will result in the operation being completed on the subscription associated
3100      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
3101      * operation is performed on the correct subscription.
3102      * </p>
3103      *
3104      * @return Token to include in an SMS message. The token will be 11 characters long.
3105      * @see android.provider.Telephony.Sms.Intents#getMessagesFromIntent
3106      */
createAppSpecificSmsToken(PendingIntent intent)3107     public String createAppSpecificSmsToken(PendingIntent intent) {
3108         try {
3109             ISms iccSms = getISmsServiceOrThrow();
3110             return iccSms.createAppSpecificSmsToken(getSubscriptionId(),
3111                     null, intent);
3112 
3113         } catch (RemoteException ex) {
3114             ex.rethrowFromSystemServer();
3115             return null;
3116         }
3117     }
3118 
3119     /**
3120      * callback for providing asynchronous sms messages for financial app.
3121      */
3122     public abstract static class FinancialSmsCallback {
3123         /**
3124          * Callback to send sms messages back to financial app asynchronously.
3125          *
3126          * @param msgs SMS messages.
3127          */
onFinancialSmsMessages(CursorWindow msgs)3128         public abstract void onFinancialSmsMessages(CursorWindow msgs);
3129     };
3130 
3131     /**
3132      * Get SMS messages for the calling financial app.
3133      * The result will be delivered asynchronously in the passing in callback interface.
3134      *
3135      * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
3136      * dialog. If this method is called on a device that has multiple active subscriptions, this
3137      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
3138      * default subscription is defined, the subscription ID associated with this message will be
3139      * INVALID, which will result in the operation being completed on the subscription associated
3140      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
3141      * operation is performed on the correct subscription.
3142      * </p>
3143      *
3144      * @param params the parameters to filter SMS messages returned.
3145      * @param executor the executor on which callback will be invoked.
3146      * @param callback a callback to receive CursorWindow with SMS messages.
3147      *
3148      */
3149     @RequiresPermission(android.Manifest.permission.SMS_FINANCIAL_TRANSACTIONS)
getSmsMessagesForFinancialApp( Bundle params, @NonNull @CallbackExecutor Executor executor, @NonNull FinancialSmsCallback callback)3150     public void getSmsMessagesForFinancialApp(
3151             Bundle params,
3152             @NonNull @CallbackExecutor Executor executor,
3153             @NonNull FinancialSmsCallback callback) {
3154         // This API is not functional and thus removed to avoid future confusion.
3155     }
3156 
3157     /**
3158      * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent).
3159      * The prefixes is a list of prefix {@code String} separated by this delimiter.
3160      * @hide
3161      */
3162     public static final String REGEX_PREFIX_DELIMITER = ",";
3163     /**
3164      * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent).
3165      * The success status to be added into the intent to be sent to the calling package.
3166      * @hide
3167      */
3168     public static final int RESULT_STATUS_SUCCESS = 0;
3169     /**
3170      * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent).
3171      * The timeout status to be added into the intent to be sent to the calling package.
3172      * @hide
3173      */
3174     public static final int RESULT_STATUS_TIMEOUT = 1;
3175     /**
3176      * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent).
3177      * Intent extra key of the retrieved SMS message as a {@code String}.
3178      * @hide
3179      */
3180     public static final String EXTRA_SMS_MESSAGE = "android.telephony.extra.SMS_MESSAGE";
3181     /**
3182      * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent).
3183      * Intent extra key of SMS retriever status, which indicates whether the request for the
3184      * coming SMS message is SUCCESS or TIMEOUT
3185      * @hide
3186      */
3187     public static final String EXTRA_STATUS = "android.telephony.extra.STATUS";
3188     /**
3189      * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent).
3190      * [Optional] Intent extra key of the retrieved Sim card subscription Id if any. {@code int}
3191      * @hide
3192      */
3193     public static final String EXTRA_SIM_SUBSCRIPTION_ID =
3194             "android.telephony.extra.SIM_SUBSCRIPTION_ID";
3195 
3196     /**
3197      * Create a single use app specific incoming SMS request for the calling package.
3198      *
3199      * This method returns a token that if included in a subsequent incoming SMS message, and the
3200      * SMS message has a prefix from the given prefixes list, the provided {@code intent} will be
3201      * sent with the SMS data to the calling package.
3202      *
3203      * The token is only good for one use within a reasonable amount of time. After an SMS has been
3204      * received containing the token all subsequent SMS messages with the token will be routed as
3205      * normal.
3206      *
3207      * An app can only have one request at a time, if the app already has a request pending it will
3208      * be replaced with a new request.
3209      *
3210      * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
3211      * dialog. If this method is called on a device that has multiple active subscriptions, this
3212      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
3213      * default subscription is defined, the subscription ID associated with this message will be
3214      * INVALID, which will result in the operation being completed on the subscription associated
3215      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
3216      * operation is performed on the correct subscription.
3217      * </p>
3218      *
3219      * @param prefixes this is a list of prefixes string separated by REGEX_PREFIX_DELIMITER. The
3220      *  matching SMS message should have at least one of the prefixes in the beginning of the
3221      *  message.
3222      * @param intent this intent is sent when the matching SMS message is received.
3223      * @return Token to include in an SMS message.
3224      */
3225     @Nullable
createAppSpecificSmsTokenWithPackageInfo( @ullable String prefixes, @NonNull PendingIntent intent)3226     public String createAppSpecificSmsTokenWithPackageInfo(
3227             @Nullable String prefixes, @NonNull PendingIntent intent) {
3228         try {
3229             ISms iccSms = getISmsServiceOrThrow();
3230             return iccSms.createAppSpecificSmsTokenWithPackageInfo(getSubscriptionId(),
3231                     null, prefixes, intent);
3232 
3233         } catch (RemoteException ex) {
3234             ex.rethrowFromSystemServer();
3235             return null;
3236         }
3237     }
3238 
3239     /**
3240      * Set Storage Availability in SmsStorageMonitor
3241      * @param storageAvailable storage availability to be set true or false
3242      * @hide
3243      */
3244     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3245     @TestApi
setStorageMonitorMemoryStatusOverride(boolean storageAvailable)3246     public void setStorageMonitorMemoryStatusOverride(boolean storageAvailable) {
3247         try {
3248             ISms iccISms = getISmsServiceOrThrow();
3249             if (iccISms != null) {
3250                 iccISms.setStorageMonitorMemoryStatusOverride(getSubscriptionId(),
3251                                                                 storageAvailable);
3252             }
3253         } catch (RemoteException ex) {
3254             ex.rethrowFromSystemServer();
3255         }
3256     }
3257 
3258     /**
3259      * Clear the memory status override set by
3260      * {@link #setStorageMonitorMemoryStatusOverride(boolean)}
3261      * @hide
3262      */
3263     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3264     @TestApi
clearStorageMonitorMemoryStatusOverride()3265     public void clearStorageMonitorMemoryStatusOverride() {
3266         try {
3267             ISms iccISms = getISmsServiceOrThrow();
3268             if (iccISms != null) {
3269                 iccISms.clearStorageMonitorMemoryStatusOverride(getSubscriptionId());
3270             }
3271         } catch (RemoteException ex) {
3272             ex.rethrowFromSystemServer();
3273         }
3274     }
3275 
3276     /** @hide */
3277     @Retention(RetentionPolicy.SOURCE)
3278     @IntDef(prefix = {"SMS_CATEGORY_"},
3279             value = {
3280                     SmsManager.SMS_CATEGORY_NOT_SHORT_CODE,
3281                     SmsManager.SMS_CATEGORY_FREE_SHORT_CODE,
3282                     SmsManager.SMS_CATEGORY_STANDARD_SHORT_CODE,
3283                     SmsManager.SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE,
3284                     SmsManager.SMS_CATEGORY_PREMIUM_SHORT_CODE})
3285     public @interface SmsShortCodeCategory {}
3286 
3287     /**
3288      * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for regular
3289      * phone numbers.
3290      * @hide
3291      */
3292     @TestApi
3293     public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0;
3294     /**
3295      * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for free
3296      * (no cost) short codes.
3297      * @hide
3298      */
3299     @TestApi
3300     public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1;
3301     /**
3302      * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for
3303      * standard rate (non-premium)
3304      * short codes.
3305      * @hide
3306      */
3307     @TestApi
3308     public static final int SMS_CATEGORY_STANDARD_SHORT_CODE = 2;
3309     /**
3310      * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for possible
3311      * premium short codes.
3312      * @hide
3313      */
3314     @TestApi
3315     public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3;
3316     /**
3317      * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for
3318      * premium short codes.
3319      * @hide
3320      */
3321     @TestApi
3322     public static final int SMS_CATEGORY_PREMIUM_SHORT_CODE = 4;
3323 
3324     /**
3325      * Check if the destination address is a possible premium short code.
3326      * NOTE: the caller is expected to strip non-digits from the destination number with
3327      * {@link PhoneNumberUtils#extractNetworkPortion} before calling this method.
3328      *
3329      * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
3330      * applications or the Telephony framework and will never trigger an SMS disambiguation
3331      * dialog. If this method is called on a device that has multiple active subscriptions, this
3332      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
3333      * default subscription is defined, the subscription ID associated with this message will be
3334      * INVALID, which will result in the operation being completed on the subscription associated
3335      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
3336      * operation is performed on the correct subscription.
3337      * </p>
3338      *
3339      * @param destAddress the destination address to test for possible short code
3340      * @param countryIso the ISO country code
3341      *
3342      * @return
3343      * {@link SmsManager#SMS_CATEGORY_NOT_SHORT_CODE},
3344      * {@link SmsManager#SMS_CATEGORY_FREE_SHORT_CODE},
3345      * {@link SmsManager#SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE},
3346      * {@link SmsManager#SMS_CATEGORY_PREMIUM_SHORT_CODE}, or
3347      * {@link SmsManager#SMS_CATEGORY_STANDARD_SHORT_CODE}
3348      *
3349      * @hide
3350      */
3351     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
3352     @TestApi
checkSmsShortCodeDestination( String destAddress, String countryIso)3353     public @SmsShortCodeCategory int checkSmsShortCodeDestination(
3354             String destAddress, String countryIso) {
3355         try {
3356             ISms iccISms = getISmsServiceOrThrow();
3357             if (iccISms != null) {
3358                 return iccISms.checkSmsShortCodeDestination(getSubscriptionId(),
3359                         null, null, destAddress, countryIso);
3360             }
3361         } catch (RemoteException e) {
3362             Log.e(TAG, "checkSmsShortCodeDestination() RemoteException", e);
3363         }
3364         return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
3365     }
3366 
3367     /**
3368      * Gets the SMSC address from (U)SIM.
3369      *
3370      * <p class="note"><strong>Note:</strong> Using this method requires that your app is the
3371      * default SMS application, or READ_PRIVILEGED_PHONE_STATE permission, or has the carrier
3372      * privileges.</p>
3373      *
3374      * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
3375      * dialog. If this method is called on a device that has multiple active subscriptions, this
3376      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
3377      * default subscription is defined, the subscription ID associated with this method will be
3378      * INVALID, which will result in the operation being completed on the subscription associated
3379      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation
3380      * is performed on the correct subscription.
3381      * </p>
3382      *
3383      * @return the SMSC address string, null if failed.
3384      */
3385     @SuppressAutoDoc // for carrier privileges and default SMS application.
3386     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3387     @Nullable
getSmscAddress()3388     public String getSmscAddress() {
3389         String smsc = null;
3390 
3391         try {
3392             ISms iSms = getISmsService();
3393             if (iSms != null) {
3394                 smsc = iSms.getSmscAddressFromIccEfForSubscriber(
3395                         getSubscriptionId(), null);
3396             }
3397         } catch (RemoteException ex) {
3398             throw new RuntimeException(ex);
3399         }
3400         return smsc;
3401     }
3402 
3403     /**
3404      * Sets the SMSC address on (U)SIM.
3405      *
3406      * <p class="note"><strong>Note:</strong> Using this method requires that your app is the
3407      * default SMS application, or has {@link android.Manifest.permission#MODIFY_PHONE_STATE}
3408      * permission, or has the carrier privileges.</p>
3409      *
3410      * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
3411      * dialog. If this method is called on a device that has multiple active subscriptions, this
3412      * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
3413      * default subscription is defined, the subscription ID associated with this method will be
3414      * INVALID, which will result in the operation being completed on the subscription associated
3415      * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation
3416      * is performed on the correct subscription.
3417      * </p>
3418      *
3419      * @param smsc the SMSC address string.
3420      * @return true for success, false otherwise. Failure can be due modem returning an error.
3421      */
3422     @SuppressAutoDoc // for carrier privileges and default SMS application.
3423     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setSmscAddress(@onNull String smsc)3424     public boolean setSmscAddress(@NonNull String smsc) {
3425         try {
3426             ISms iSms = getISmsService();
3427             if (iSms != null) {
3428                 return iSms.setSmscAddressOnIccEfForSubscriber(
3429                         smsc, getSubscriptionId(), null);
3430             }
3431         } catch (RemoteException ex) {
3432             throw new RuntimeException(ex);
3433         }
3434         return false;
3435     }
3436 
3437     /**
3438      * Gets the premium SMS permission for the specified package. If the package has never
3439      * been seen before, the default {@link SmsManager#PREMIUM_SMS_CONSENT_UNKNOWN}
3440      * will be returned.
3441      * @param packageName the name of the package to query permission
3442      * @return one of {@link SmsManager#PREMIUM_SMS_CONSENT_UNKNOWN},
3443      *  {@link SmsManager#PREMIUM_SMS_CONSENT_ASK_USER},
3444      *  {@link SmsManager#PREMIUM_SMS_CONSENT_NEVER_ALLOW}, or
3445      *  {@link SmsManager#PREMIUM_SMS_CONSENT_ALWAYS_ALLOW}
3446      * @hide
3447      */
3448     @SystemApi
3449     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getPremiumSmsConsent(@onNull String packageName)3450     public @PremiumSmsConsent int getPremiumSmsConsent(@NonNull String packageName) {
3451         int permission = 0;
3452         try {
3453             ISms iSms = getISmsService();
3454             if (iSms != null) {
3455                 permission = iSms.getPremiumSmsPermission(packageName);
3456             }
3457         } catch (RemoteException e) {
3458             Log.e(TAG, "getPremiumSmsPermission() RemoteException", e);
3459         }
3460         return permission;
3461     }
3462 
3463     /**
3464      * Sets the premium SMS permission for the specified package and save the value asynchronously
3465      * to persistent storage.
3466      * @param packageName the name of the package to set permission
3467      * @param permission one of {@link SmsManager#PREMIUM_SMS_CONSENT_ASK_USER},
3468      *  {@link SmsManager#PREMIUM_SMS_CONSENT_NEVER_ALLOW}, or
3469      *  {@link SmsManager#PREMIUM_SMS_CONSENT_ALWAYS_ALLOW}
3470      * @hide
3471      */
3472     @SystemApi
3473     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setPremiumSmsConsent( @onNull String packageName, @PremiumSmsConsent int permission)3474     public void setPremiumSmsConsent(
3475             @NonNull String packageName, @PremiumSmsConsent int permission) {
3476         try {
3477             ISms iSms = getISmsService();
3478             if (iSms != null) {
3479                 iSms.setPremiumSmsPermission(packageName, permission);
3480             }
3481         } catch (RemoteException e) {
3482             Log.e(TAG, "setPremiumSmsPermission() RemoteException", e);
3483         }
3484     }
3485 
3486     /**
3487      * Reset all cell broadcast ranges. Previously enabled ranges will become invalid after this.
3488      * @deprecated Use {@link TelephonyManager#setCellBroadcastIdRanges} with empty list instead
3489      * @hide
3490      */
3491     @Deprecated
3492     @SystemApi
3493     @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
resetAllCellBroadcastRanges()3494     public void resetAllCellBroadcastRanges() {
3495         try {
3496             ISms iSms = getISmsService();
3497             if (iSms != null) {
3498                 // If getSubscriptionId() returns INVALID or an inactive subscription, we will use
3499                 // the default phone internally.
3500                 iSms.resetAllCellBroadcastRanges(getSubscriptionId());
3501             }
3502         } catch (RemoteException ex) {
3503             ex.rethrowFromSystemServer();
3504         }
3505     }
3506 
formatCrossStackMessageId(long id)3507     private static String formatCrossStackMessageId(long id) {
3508         return "{x-message-id:" + id + "}";
3509     }
3510 
3511     /**
3512      * Fetches the EF_PSISMSC value from the UICC that contains the Public Service Identity of
3513      * the SM-SC (either a SIP URI or tel URI). The EF_PSISMSC of ISIM and USIM can be found in
3514      * DF_TELECOM.
3515      * The EF_PSISMSC value is used by the ME to submit SMS over IP as defined in 24.341 [55].
3516      *
3517      * @return Uri : Public Service Identity of SM-SC from the ISIM or USIM if the ISIM is not
3518      * available.
3519      * @throws SecurityException if the caller does not have the required permission/privileges.
3520      * @throws IllegalStateException in case of telephony service is not available.
3521      * @hide
3522      */
3523     @NonNull
3524     @SystemApi
3525     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3526     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
getSmscIdentity()3527     public Uri getSmscIdentity() {
3528         Uri smscUri = Uri.EMPTY;
3529         try {
3530             IPhoneSubInfo info = TelephonyManager.getSubscriberInfoService();
3531             if (info == null) {
3532                 Rlog.e(TAG, "getSmscIdentity(): IPhoneSubInfo instance is NULL");
3533                 throw new IllegalStateException("Telephony service is not available");
3534             }
3535             /** Fetches the SIM EF_PSISMSC value based on subId and appType */
3536             smscUri = info.getSmscIdentity(getSubscriptionId(), TelephonyManager.APPTYPE_ISIM);
3537             if (Uri.EMPTY.equals(smscUri)) {
3538                 /** Fallback in case where ISIM is not available */
3539                 smscUri = info.getSmscIdentity(getSubscriptionId(), TelephonyManager.APPTYPE_USIM);
3540             }
3541         } catch (RemoteException ex) {
3542             Rlog.e(TAG, "getSmscIdentity(): Exception : " + ex);
3543             ex.rethrowAsRuntimeException();
3544         }
3545         return smscUri;
3546     }
3547 }
3548