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