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