blob: 60cc9c7f73cf0c2db775d8d07f49e282d5100ab4 [file] [log] [blame]
Dan Willemsen4980bf42017-02-14 14:17:12 -08001/*
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
17package android.telephony;
18
changbettyd5093c712019-11-21 11:07:14 +080019import android.Manifest;
Hongming Jin08496b02019-01-25 13:41:52 -080020import android.annotation.CallbackExecutor;
Thomas Nguyencf166c22023-11-01 11:02:15 -070021import android.annotation.FlaggedApi;
chen xu9c7fad92019-03-25 10:43:28 -070022import android.annotation.IntDef;
Amit Mahajand6653312021-03-16 16:01:46 -070023import android.annotation.IntRange;
Hongming Jin46edf152019-01-17 12:11:59 -080024import android.annotation.NonNull;
25import android.annotation.Nullable;
Hui Wangc47df7f2021-12-14 20:37:47 +000026import android.annotation.RequiresFeature;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060027import android.annotation.RequiresPermission;
Jeff Davidsona4a4c8a2018-03-15 17:10:58 -070028import android.annotation.SuppressAutoDoc;
Abhijith Shastry448c12c2017-02-14 13:02:59 -080029import android.annotation.SystemApi;
chen xu9c7fad92019-03-25 10:43:28 -070030import android.annotation.TestApi;
Dan Willemsen4980bf42017-02-14 14:17:12 -080031import android.app.PendingIntent;
Shuo Qian24fded62020-01-14 14:48:27 -080032import android.compat.Compatibility;
33import android.compat.annotation.ChangeId;
34import android.compat.annotation.EnabledAfter;
Artur Satayev74cb7192019-12-10 17:47:56 +000035import android.compat.annotation.UnsupportedAppUsage;
Dan Willemsen4980bf42017-02-14 14:17:12 -080036import android.content.Context;
Hui Wangc47df7f2021-12-14 20:37:47 +000037import android.content.pm.PackageManager;
Hongming Jin08496b02019-01-25 13:41:52 -080038import android.database.CursorWindow;
Dan Willemsen4980bf42017-02-14 14:17:12 -080039import android.net.Uri;
Mathew Inwood55418ea2018-12-20 15:30:45 +000040import android.os.Build;
Dan Willemsen4980bf42017-02-14 14:17:12 -080041import android.os.Bundle;
42import android.os.RemoteException;
Dan Willemsen4980bf42017-02-14 14:17:12 -080043import android.text.TextUtils;
44import android.util.ArrayMap;
45import android.util.Log;
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -070046import android.util.Pair;
Dan Willemsen4980bf42017-02-14 14:17:12 -080047
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -070048import com.android.internal.annotations.GuardedBy;
Brad Ebinger360415a2019-04-30 11:37:27 -070049import com.android.internal.telephony.IIntegerConsumer;
arunvodduac108782022-11-28 15:46:22 +000050import com.android.internal.telephony.IPhoneSubInfo;
Dan Willemsen4980bf42017-02-14 14:17:12 -080051import com.android.internal.telephony.ISms;
Brad Ebinger360415a2019-04-30 11:37:27 -070052import com.android.internal.telephony.ITelephony;
Dan Willemsen4980bf42017-02-14 14:17:12 -080053import com.android.internal.telephony.SmsRawData;
Thomas Nguyencf166c22023-11-01 11:02:15 -070054import com.android.internal.telephony.flags.Flags;
Nazanindf808782020-08-11 15:42:54 -070055import com.android.telephony.Rlog;
Dan Willemsen4980bf42017-02-14 14:17:12 -080056
chen xu9c7fad92019-03-25 10:43:28 -070057import java.lang.annotation.Retention;
58import java.lang.annotation.RetentionPolicy;
Dan Willemsen4980bf42017-02-14 14:17:12 -080059import java.util.ArrayList;
Dan Willemsen4980bf42017-02-14 14:17:12 -080060import java.util.List;
61import java.util.Map;
Hongming Jin08496b02019-01-25 13:41:52 -080062import java.util.concurrent.Executor;
Dan Willemsen4980bf42017-02-14 14:17:12 -080063
64/*
65 * TODO(code review): Curious question... Why are a lot of these
66 * methods not declared as static, since they do not seem to require
67 * any local object state? Presumably this cannot be changed without
68 * interfering with the API...
69 */
70
71/**
72 * Manages SMS operations such as sending data, text, and pdu SMS messages.
Brad Ebingerfa82ddd2019-04-30 11:34:14 -070073 * Get this object by calling the static method {@link #getDefault()}. To create an instance of
74 * {@link SmsManager} associated with a specific subscription ID, call
75 * {@link #getSmsManagerForSubscriptionId(int)}. This is typically used for devices that support
76 * multiple active subscriptions at once.
Dan Willemsen4980bf42017-02-14 14:17:12 -080077 *
78 * <p>For information about how to behave as the default SMS app on Android 4.4 (API level 19)
79 * and higher, see {@link android.provider.Telephony}.
Brad Ebingerfa82ddd2019-04-30 11:34:14 -070080 *
81 * @see SubscriptionManager#getActiveSubscriptionInfoList()
Dan Willemsen4980bf42017-02-14 14:17:12 -080082 */
Hui Wangc47df7f2021-12-14 20:37:47 +000083@RequiresFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)
Dan Willemsen4980bf42017-02-14 14:17:12 -080084public final class SmsManager {
85 private static final String TAG = "SmsManager";
Vasu Noriaea03912018-09-04 11:19:59 -070086
Dan Willemsen4980bf42017-02-14 14:17:12 -080087 private static final Object sLockObject = new Object();
88
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -070089 @GuardedBy("sLockObject")
90 private static final Map<Pair<Context, Integer>, SmsManager> sSubInstances =
91 new ArrayMap<>();
92
93 /** Singleton object constructed during class initialization. */
94 private static final SmsManager DEFAULT_INSTANCE = getSmsManagerForContextAndSubscriptionId(
95 null, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
96
Nathan Harolde97d1c62016-12-13 19:03:09 -080097 /** SMS record length from TS 51.011 10.5.3
98 * @hide
99 */
100 public static final int SMS_RECORD_LENGTH = 176;
101
102 /** SMS record length from C.S0023 3.4.27
103 * @hide
104 */
105 public static final int CDMA_SMS_RECORD_LENGTH = 255;
106
Dan Willemsen4980bf42017-02-14 14:17:12 -0800107 /** A concrete subscription id, or the pseudo DEFAULT_SUBSCRIPTION_ID */
Mathew Inwood55418ea2018-12-20 15:30:45 +0000108 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dan Willemsen4980bf42017-02-14 14:17:12 -0800109 private int mSubId;
110
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -0700111 /**
112 * Context this SmsManager is for. Can be {@code null} in the case the manager was created via
113 * legacy APIs
114 */
115 private final @Nullable Context mContext;
116
Dan Willemsen4980bf42017-02-14 14:17:12 -0800117 /*
118 * Key for the various carrier-dependent configuration values.
119 * Some of the values are used by the system in processing SMS or MMS messages. Others
120 * are provided for the convenience of SMS applications.
121 */
122
123 /**
124 * Whether to append transaction id to MMS WAP Push M-Notification.ind's content location URI
125 * when constructing the download URL of a new MMS (boolean type)
126 */
127 public static final String MMS_CONFIG_APPEND_TRANSACTION_ID =
128 CarrierConfigManager.KEY_MMS_APPEND_TRANSACTION_ID_BOOL;
129 /**
130 * Whether MMS is enabled for the current carrier (boolean type)
131 */
132 public static final String
Brad Ebinger360415a2019-04-30 11:37:27 -0700133 MMS_CONFIG_MMS_ENABLED = CarrierConfigManager.KEY_MMS_MMS_ENABLED_BOOL;
Dan Willemsen4980bf42017-02-14 14:17:12 -0800134 /**
135 * Whether group MMS is enabled for the current carrier (boolean type)
136 */
137 public static final String
138 MMS_CONFIG_GROUP_MMS_ENABLED = CarrierConfigManager.KEY_MMS_GROUP_MMS_ENABLED_BOOL;
139 /**
140 * If this is enabled, M-NotifyResp.ind should be sent to the WAP Push content location instead
141 * of the default MMSC (boolean type)
142 */
143 public static final String MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED =
144 CarrierConfigManager.KEY_MMS_NOTIFY_WAP_MMSC_ENABLED_BOOL;
145 /**
146 * Whether alias is enabled (boolean type)
147 */
148 public static final String
149 MMS_CONFIG_ALIAS_ENABLED = CarrierConfigManager.KEY_MMS_ALIAS_ENABLED_BOOL;
150 /**
151 * Whether audio is allowed to be attached for MMS messages (boolean type)
152 */
153 public static final String
154 MMS_CONFIG_ALLOW_ATTACH_AUDIO = CarrierConfigManager.KEY_MMS_ALLOW_ATTACH_AUDIO_BOOL;
155 /**
156 * Whether multipart SMS is enabled (boolean type)
157 */
158 public static final String MMS_CONFIG_MULTIPART_SMS_ENABLED =
159 CarrierConfigManager.KEY_MMS_MULTIPART_SMS_ENABLED_BOOL;
160 /**
161 * Whether SMS delivery report is enabled (boolean type)
162 */
163 public static final String MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED =
164 CarrierConfigManager.KEY_MMS_SMS_DELIVERY_REPORT_ENABLED_BOOL;
165 /**
166 * Whether content-disposition field should be expected in an MMS PDU (boolean type)
167 */
168 public static final String MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION =
169 CarrierConfigManager.KEY_MMS_SUPPORT_MMS_CONTENT_DISPOSITION_BOOL;
170 /**
171 * Whether multipart SMS should be sent as separate messages
172 */
173 public static final String MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES =
174 CarrierConfigManager.KEY_MMS_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES_BOOL;
175 /**
176 * Whether MMS read report is enabled (boolean type)
177 */
178 public static final String MMS_CONFIG_MMS_READ_REPORT_ENABLED =
179 CarrierConfigManager.KEY_MMS_MMS_READ_REPORT_ENABLED_BOOL;
180 /**
181 * Whether MMS delivery report is enabled (boolean type)
182 */
183 public static final String MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED =
184 CarrierConfigManager.KEY_MMS_MMS_DELIVERY_REPORT_ENABLED_BOOL;
185 /**
186 * Max MMS message size in bytes (int type)
187 */
188 public static final String
189 MMS_CONFIG_MAX_MESSAGE_SIZE = CarrierConfigManager.KEY_MMS_MAX_MESSAGE_SIZE_INT;
190 /**
191 * Max MMS image width (int type)
192 */
193 public static final String
194 MMS_CONFIG_MAX_IMAGE_WIDTH = CarrierConfigManager.KEY_MMS_MAX_IMAGE_WIDTH_INT;
195 /**
196 * Max MMS image height (int type)
197 */
198 public static final String
199 MMS_CONFIG_MAX_IMAGE_HEIGHT = CarrierConfigManager.KEY_MMS_MAX_IMAGE_HEIGHT_INT;
200 /**
201 * Limit of recipients of MMS messages (int type)
202 */
203 public static final String
204 MMS_CONFIG_RECIPIENT_LIMIT = CarrierConfigManager.KEY_MMS_RECIPIENT_LIMIT_INT;
205 /**
206 * Min alias character count (int type)
207 */
208 public static final String
209 MMS_CONFIG_ALIAS_MIN_CHARS = CarrierConfigManager.KEY_MMS_ALIAS_MIN_CHARS_INT;
210 /**
211 * Max alias character count (int type)
212 */
213 public static final String
214 MMS_CONFIG_ALIAS_MAX_CHARS = CarrierConfigManager.KEY_MMS_ALIAS_MAX_CHARS_INT;
215 /**
216 * When the number of parts of a multipart SMS reaches this threshold, it should be converted
217 * into an MMS (int type)
218 */
219 public static final String MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD =
220 CarrierConfigManager.KEY_MMS_SMS_TO_MMS_TEXT_THRESHOLD_INT;
221 /**
222 * Some carriers require SMS to be converted into MMS when text length reaches this threshold
223 * (int type)
224 */
225 public static final String MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD =
226 CarrierConfigManager.KEY_MMS_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD_INT;
227 /**
228 * Max message text size (int type)
229 */
230 public static final String MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE =
231 CarrierConfigManager.KEY_MMS_MESSAGE_TEXT_MAX_SIZE_INT;
232 /**
233 * Max message subject length (int type)
234 */
235 public static final String
236 MMS_CONFIG_SUBJECT_MAX_LENGTH = CarrierConfigManager.KEY_MMS_SUBJECT_MAX_LENGTH_INT;
237 /**
238 * MMS HTTP socket timeout in milliseconds (int type)
239 */
240 public static final String
241 MMS_CONFIG_HTTP_SOCKET_TIMEOUT = CarrierConfigManager.KEY_MMS_HTTP_SOCKET_TIMEOUT_INT;
242 /**
243 * The name of the UA Prof URL HTTP header for MMS HTTP request (String type)
244 */
245 public static final String
246 MMS_CONFIG_UA_PROF_TAG_NAME = CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING;
247 /**
248 * The User-Agent header value for MMS HTTP request (String type)
249 */
250 public static final String
251 MMS_CONFIG_USER_AGENT = CarrierConfigManager.KEY_MMS_USER_AGENT_STRING;
252 /**
253 * The UA Profile URL header value for MMS HTTP request (String type)
254 */
255 public static final String
256 MMS_CONFIG_UA_PROF_URL = CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING;
257 /**
258 * A list of HTTP headers to add to MMS HTTP request, separated by "|" (String type)
259 */
260 public static final String
261 MMS_CONFIG_HTTP_PARAMS = CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING;
262 /**
263 * Email gateway number (String type)
264 */
265 public static final String MMS_CONFIG_EMAIL_GATEWAY_NUMBER =
266 CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING;
267 /**
268 * The suffix to append to the NAI header value for MMS HTTP request (String type)
269 */
270 public static final String
271 MMS_CONFIG_NAI_SUFFIX = CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING;
272 /**
273 * If true, show the cell broadcast (amber alert) in the SMS settings. Some carriers don't want
274 * this shown. (Boolean type)
275 */
276 public static final String MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS =
277 CarrierConfigManager.KEY_MMS_SHOW_CELL_BROADCAST_APP_LINKS_BOOL;
278 /**
279 * Whether the carrier MMSC supports charset field in Content-Type header. If this is false,
280 * then we don't add "charset" to "Content-Type"
281 */
282 public static final String MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER =
283 CarrierConfigManager.KEY_MMS_SUPPORT_HTTP_CHARSET_HEADER_BOOL;
284 /**
285 * If true, add "Connection: close" header to MMS HTTP requests so the connection
286 * is immediately closed (disabling keep-alive). (Boolean type)
287 * @hide
288 */
289 public static final String MMS_CONFIG_CLOSE_CONNECTION =
290 CarrierConfigManager.KEY_MMS_CLOSE_CONNECTION_BOOL;
291
Dan Willemsen4980bf42017-02-14 14:17:12 -0800292 /**
Mengjun Leng353bed12018-07-30 15:28:31 +0800293 * 3gpp2 SMS priority is not specified
294 * @hide
295 */
296 public static final int SMS_MESSAGE_PRIORITY_NOT_SPECIFIED = -1;
297 /**
298 * 3gpp SMS period is not specified
299 * @hide
300 */
301 public static final int SMS_MESSAGE_PERIOD_NOT_SPECIFIED = -1;
302
Megha Patil3f6b9c12022-12-08 07:00:57 +0000303 // RP-Cause Values For MO SMS as per TS 124 011, table 8.4.
304
305 /** @hide */
306 @IntDef(prefix = { "SMS_RP_CAUSE" }, value = {
307 SmsManager.SMS_RP_CAUSE_UNALLOCATED_NUMBER,
308 SmsManager.SMS_RP_CAUSE_OPERATOR_DETERMINED_BARRING,
309 SmsManager.SMS_RP_CAUSE_CALL_BARRING,
310 SmsManager.SMS_RP_CAUSE_RESERVED,
311 SmsManager.SMS_RP_CAUSE_SHORT_MESSAGE_TRANSFER_REJECTED,
312 SmsManager.SMS_RP_CAUSE_DESTINATION_OUT_OF_ORDER,
313 SmsManager.SMS_RP_CAUSE_UNIDENTIFIED_SUBSCRIBER,
314 SmsManager.SMS_RP_CAUSE_FACILITY_REJECTED,
315 SmsManager.SMS_RP_CAUSE_UNKNOWN_SUBSCRIBER,
316 SmsManager.SMS_RP_CAUSE_NETWORK_OUT_OF_ORDER,
317 SmsManager.SMS_RP_CAUSE_TEMPORARY_FAILURE,
318 SmsManager.SMS_RP_CAUSE_CONGESTION,
319 SmsManager.SMS_RP_CAUSE_RESOURCES_UNAVAILABLE,
320 SmsManager.SMS_RP_CAUSE_FACILITY_NOT_SUBSCRIBED,
321 SmsManager.SMS_RP_CAUSE_FACILITY_NOT_IMPLEMENTED,
322 SmsManager.SMS_RP_CAUSE_INVALID_MESSAGE_REFERENCE_VALUE,
323 SmsManager.SMS_RP_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE,
324 SmsManager.SMS_RP_CAUSE_INVALID_MANDATORY_INFORMATION,
325 SmsManager.SMS_RP_CAUSE_MESSAGE_TYPE_NON_EXISTENT,
326 SmsManager.SMS_RP_CAUSE_MESSAGE_INCOMPATIBLE_WITH_PROTOCOL_STATE,
327 SmsManager.SMS_RP_CAUSE_INFORMATION_ELEMENT_NON_EXISTENT,
328 SmsManager.SMS_RP_CAUSE_PROTOCOL_ERROR,
329 SmsManager.SMS_RP_CAUSE_INTERWORKING_UNSPECIFIED
330 })
331 @Retention(RetentionPolicy.SOURCE)
332 public @interface SMS_RP_CAUSE {}
333
334 /** Unallocated Number Cause */
335 public static final int SMS_RP_CAUSE_UNALLOCATED_NUMBER = 1;
336
337 /** RP-Cause for Operator Barring */
338 public static final int SMS_RP_CAUSE_OPERATOR_DETERMINED_BARRING = 8;
339
340 /** RP-Cause Value for Call Barring */
341 public static final int SMS_RP_CAUSE_CALL_BARRING = 10;
342
343 /** RP-Cause value for Reserved Number */
344 public static final int SMS_RP_CAUSE_RESERVED = 11;
345
346 /** RP-Cause Value for Message Transfer Rejected by Network */
347 public static final int SMS_RP_CAUSE_SHORT_MESSAGE_TRANSFER_REJECTED = 21;
348
349 /** RP-Cause Value for Destination is Out of Order */
350 public static final int SMS_RP_CAUSE_DESTINATION_OUT_OF_ORDER = 27;
351
352 /** RP-Cause Value when Subscriber is not Identified */
353 public static final int SMS_RP_CAUSE_UNIDENTIFIED_SUBSCRIBER = 28;
354
355 /** RP-Cause Value when SMS Facility if Rejected by Operator */
356 public static final int SMS_RP_CAUSE_FACILITY_REJECTED = 29;
357
358 /** RP-Cause Value when Subscriber is not Identified */
359 public static final int SMS_RP_CAUSE_UNKNOWN_SUBSCRIBER = 30;
360
361 /** RP-Cause Value when network is out of order*/
362 public static final int SMS_RP_CAUSE_NETWORK_OUT_OF_ORDER = 38;
363
364 /** RP-Cause Value For Temporary failure*/
365 public static final int SMS_RP_CAUSE_TEMPORARY_FAILURE = 41;
366
367 /** RP-Cause Value for SMS Failure due to Congestion in network*/
368 public static final int SMS_RP_CAUSE_CONGESTION = 42;
369
370 /** RP-Cause Value when Network Resources are unavailable */
371 public static final int SMS_RP_CAUSE_RESOURCES_UNAVAILABLE = 47;
372
373 /** RP-Cause Value when SMS Facilty is not subscribed by Reote device */
374 public static final int SMS_RP_CAUSE_FACILITY_NOT_SUBSCRIBED = 50;
375
376 /** RP-Cause Value when network does not provide the received service */
377 public static final int SMS_RP_CAUSE_FACILITY_NOT_IMPLEMENTED = 69;
378
379 /** RP-Cause Value when RP-MessageRefere */
380 public static final int SMS_RP_CAUSE_INVALID_MESSAGE_REFERENCE_VALUE = 81;
381
382 /** RP-Cause Value when network does not provide the received service */
383 public static final int SMS_RP_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE = 95;
384
385 /** RP-Cause Value when network does not provide the received service */
386 public static final int SMS_RP_CAUSE_INVALID_MANDATORY_INFORMATION = 96;
387
388 /** RP-Cause Value when network does not provide the received service */
389 public static final int SMS_RP_CAUSE_MESSAGE_TYPE_NON_EXISTENT = 97;
390
391 /** RP-Cause Value when network does not provide the received service */
392 public static final int SMS_RP_CAUSE_MESSAGE_INCOMPATIBLE_WITH_PROTOCOL_STATE = 98;
393
394 /** RP-Cause Value when network does not provide the received service */
395 public static final int SMS_RP_CAUSE_INFORMATION_ELEMENT_NON_EXISTENT = 99;
396
397 /** RP-Cause Value when network does not provide the received service */
398 public static final int SMS_RP_CAUSE_PROTOCOL_ERROR = 111;
399
400 /** RP-Cause Value when network does not provide the received service */
401 public static final int SMS_RP_CAUSE_INTERWORKING_UNSPECIFIED = 127;
402
changbetty9dc2ca02019-12-26 19:57:35 +0800403 /** @hide */
404 @IntDef(prefix = { "PREMIUM_SMS_CONSENT" }, value = {
405 SmsManager.PREMIUM_SMS_CONSENT_UNKNOWN,
406 SmsManager.PREMIUM_SMS_CONSENT_ASK_USER,
407 SmsManager.PREMIUM_SMS_CONSENT_NEVER_ALLOW,
408 SmsManager.PREMIUM_SMS_CONSENT_ALWAYS_ALLOW
409 })
410 @Retention(RetentionPolicy.SOURCE)
411 public @interface PremiumSmsConsent {}
412
413 /** Premium SMS Consent for the package is unknown. This indicates that the user
414 * has not set a permission for this package, because this package has never tried
415 * to send a premium SMS.
416 * @hide
417 */
418 @SystemApi
419 public static final int PREMIUM_SMS_CONSENT_UNKNOWN = 0;
420
421 /** Default premium SMS Consent (ask user for each premium SMS sent).
422 * @hide
423 */
424 @SystemApi
425 public static final int PREMIUM_SMS_CONSENT_ASK_USER = 1;
426
427 /** Premium SMS Consent when the owner has denied the app from sending premium SMS.
428 * @hide
429 */
430 @SystemApi
431 public static final int PREMIUM_SMS_CONSENT_NEVER_ALLOW = 2;
432
433 /** Premium SMS Consent when the owner has allowed the app to send premium SMS.
434 * @hide
435 */
436 @SystemApi
437 public static final int PREMIUM_SMS_CONSENT_ALWAYS_ALLOW = 3;
438
Brad Ebinger360415a2019-04-30 11:37:27 -0700439 // result of asking the user for a subscription to perform an operation.
440 private interface SubscriptionResolverResult {
441 void onSuccess(int subId);
442 void onFailure();
443 }
444
445 /**
Chan Kimaa893962023-08-18 22:34:04 +0000446 * Get {@link Context#getOpPackageName()} if this manager has a context, otherwise a placeholder
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -0700447 * value.
448 *
449 * @return The package name to be used for app-ops checks
450 */
451 private @Nullable String getOpPackageName() {
452 if (mContext == null) {
453 return null;
454 } else {
455 return mContext.getOpPackageName();
456 }
457 }
458
459 /**
460 * Get {@link Context#getAttributionTag()} ()} if this manager has a context, otherwise get the
461 * default attribution tag.
462 *
463 * @return The attribution tag to be used for app-ops checks
464 */
465 private @Nullable String getAttributionTag() {
466 if (mContext == null) {
467 return null;
468 } else {
469 return mContext.getAttributionTag();
470 }
471 }
472
473 /**
Dan Willemsen4980bf42017-02-14 14:17:12 -0800474 * Send a text based SMS.
475 *
476 * <p class="note"><strong>Note:</strong> Using this method requires that your app has the
477 * {@link android.Manifest.permission#SEND_SMS} permission.</p>
478 *
479 * <p class="note"><strong>Note:</strong> Beginning with Android 4.4 (API level 19), if
480 * <em>and only if</em> an app is not selected as the default SMS app, the system automatically
481 * writes messages sent using this method to the SMS Provider (the default SMS app is always
482 * responsible for writing its sent messages to the SMS Provider). For information about
483 * how to behave as the default SMS app, see {@link android.provider.Telephony}.</p>
484 *
Brad Ebinger360415a2019-04-30 11:37:27 -0700485 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
486 * manager on a multi-SIM device, this operation may fail sending the SMS message because no
487 * suitable default subscription could be found. In this case, if {@code sentIntent} is
488 * non-null, then the {@link PendingIntent} will be sent with an error code
489 * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the
490 * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions
491 * where this operation may fail.
492 * </p>
493 *
Dan Willemsen4980bf42017-02-14 14:17:12 -0800494 * @param destinationAddress the address to send the message to
495 * @param scAddress is the service center address or null to use
496 * the current default SMSC
497 * @param text the body of the message to send
498 * @param sentIntent if not NULL this <code>PendingIntent</code> is
499 * broadcast when the message is successfully sent, or failed.
500 * The result code will be <code>Activity.RESULT_OK</code> for success,
501 * or one of these errors:<br>
502 * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
503 * <code>RESULT_ERROR_RADIO_OFF</code><br>
504 * <code>RESULT_ERROR_NULL_PDU</code><br>
Brad Ebingere6de81f2019-03-06 14:32:28 -0800505 * <code>RESULT_ERROR_NO_SERVICE</code><br>
Tom Taylorf43f4f02019-10-08 16:34:04 -0700506 * <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br>
507 * <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
508 * <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
509 * <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
510 * <code>RESULT_RADIO_NOT_AVAILABLE</code><br>
511 * <code>RESULT_NETWORK_REJECT</code><br>
512 * <code>RESULT_INVALID_ARGUMENTS</code><br>
513 * <code>RESULT_INVALID_STATE</code><br>
514 * <code>RESULT_NO_MEMORY</code><br>
515 * <code>RESULT_INVALID_SMS_FORMAT</code><br>
516 * <code>RESULT_SYSTEM_ERROR</code><br>
517 * <code>RESULT_MODEM_ERROR</code><br>
518 * <code>RESULT_NETWORK_ERROR</code><br>
519 * <code>RESULT_ENCODING_ERROR</code><br>
520 * <code>RESULT_INVALID_SMSC_ADDRESS</code><br>
521 * <code>RESULT_OPERATION_NOT_ALLOWED</code><br>
522 * <code>RESULT_INTERNAL_ERROR</code><br>
523 * <code>RESULT_NO_RESOURCES</code><br>
524 * <code>RESULT_CANCELLED</code><br>
525 * <code>RESULT_REQUEST_NOT_SUPPORTED</code><br>
526 * <code>RESULT_NO_BLUETOOTH_SERVICE</code><br>
527 * <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
528 * <code>RESULT_BLUETOOTH_DISCONNECTED</code><br>
529 * <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
530 * <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
531 * <code>RESULT_SMS_SEND_RETRY_FAILED</code><br>
532 * <code>RESULT_REMOTE_EXCEPTION</code><br>
533 * <code>RESULT_NO_DEFAULT_SMS_APP</code><br>
534 * <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
535 * <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
536 * <code>RESULT_RIL_NETWORK_REJECT</code><br>
537 * <code>RESULT_RIL_INVALID_STATE</code><br>
538 * <code>RESULT_RIL_INVALID_ARGUMENTS</code><br>
539 * <code>RESULT_RIL_NO_MEMORY</code><br>
540 * <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
541 * <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br>
542 * <code>RESULT_RIL_SYSTEM_ERR</code><br>
543 * <code>RESULT_RIL_ENCODING_ERR</code><br>
544 * <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
545 * <code>RESULT_RIL_MODEM_ERR</code><br>
546 * <code>RESULT_RIL_NETWORK_ERR</code><br>
547 * <code>RESULT_RIL_INTERNAL_ERR</code><br>
548 * <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
549 * <code>RESULT_RIL_INVALID_MODEM_STATE</code><br>
550 * <code>RESULT_RIL_NETWORK_NOT_READY</code><br>
551 * <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
552 * <code>RESULT_RIL_NO_RESOURCES</code><br>
553 * <code>RESULT_RIL_CANCELLED</code><br>
554 * <code>RESULT_RIL_SIM_ABSENT</code><br>
allenwtsua2c5de52020-11-18 13:49:58 +0800555 * <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
556 * <code>RESULT_RIL_ACCESS_BARRED</code><br>
557 * <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
Tom Taylorf43f4f02019-10-08 16:34:04 -0700558 * For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
559 * the sentIntent may include the extra "errorCode" containing a radio technology specific
560 * value, generally only useful for troubleshooting.<br>
Dan Willemsen4980bf42017-02-14 14:17:12 -0800561 * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
562 * broadcast when the message is delivered to the recipient. The
563 * raw pdu of the status report is in the extended data ("pdu").
564 *
565 * @throws IllegalArgumentException if destinationAddress or text are empty
566 */
567 public void sendTextMessage(
568 String destinationAddress, String scAddress, String text,
569 PendingIntent sentIntent, PendingIntent deliveryIntent) {
Abhijith Shastry448c12c2017-02-14 13:02:59 -0800570 sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -0700571 true /* persistMessage*/, getOpPackageName(), getAttributionTag(),
572 0L /* messageId */);
Tom Taylor66afc8f2019-11-20 15:39:12 -0800573 }
574
575
576 /**
577 * Send a text based SMS. Same as {@link #sendTextMessage( String destinationAddress,
578 * String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)}, but
579 * adds an optional messageId.
580 * @param messageId An id that uniquely identifies the message requested to be sent.
581 * Used for logging and diagnostics purposes. The id may be 0.
582 *
583 * @throws IllegalArgumentException if destinationAddress or text are empty
584 *
585 */
586 public void sendTextMessage(
587 @NonNull String destinationAddress, @Nullable String scAddress, @NonNull String text,
588 @Nullable PendingIntent sentIntent, @Nullable PendingIntent deliveryIntent,
589 long messageId) {
590 sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -0700591 true /* persistMessage*/, getOpPackageName(), getAttributionTag(),
592 messageId);
Dan Willemsen4980bf42017-02-14 14:17:12 -0800593 }
594
Amit Mahajan24c01a22019-09-20 11:13:05 -0700595 /**
596 * Send a text based SMS with messaging options.
597 *
598 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
599 * manager on a multi-SIM device, this operation may fail sending the SMS message because no
600 * suitable default subscription could be found. In this case, if {@code sentIntent} is
601 * non-null, then the {@link PendingIntent} will be sent with an error code
602 * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the
603 * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions
604 * where this operation may fail.
605 * </p>
606 *
607 * @param destinationAddress the address to send the message to
608 * @param scAddress is the service center address or null to use
609 * the current default SMSC
610 * @param text the body of the message to send
611 * @param sentIntent if not NULL this <code>PendingIntent</code> is
612 * broadcast when the message is successfully sent, or failed.
613 * The result code will be <code>Activity.RESULT_OK</code> for success,
614 * or one of these errors:<br>
615 * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
616 * <code>RESULT_ERROR_RADIO_OFF</code><br>
617 * <code>RESULT_ERROR_NULL_PDU</code><br>
Tom Taylorf43f4f02019-10-08 16:34:04 -0700618 * <code>RESULT_ERROR_NO_SERVICE</code><br>
Tom Taylorf43f4f02019-10-08 16:34:04 -0700619 * <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br>
620 * <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
621 * <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
622 * <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
623 * <code>RESULT_RADIO_NOT_AVAILABLE</code><br>
624 * <code>RESULT_NETWORK_REJECT</code><br>
625 * <code>RESULT_INVALID_ARGUMENTS</code><br>
626 * <code>RESULT_INVALID_STATE</code><br>
627 * <code>RESULT_NO_MEMORY</code><br>
628 * <code>RESULT_INVALID_SMS_FORMAT</code><br>
629 * <code>RESULT_SYSTEM_ERROR</code><br>
630 * <code>RESULT_MODEM_ERROR</code><br>
631 * <code>RESULT_NETWORK_ERROR</code><br>
632 * <code>RESULT_ENCODING_ERROR</code><br>
633 * <code>RESULT_INVALID_SMSC_ADDRESS</code><br>
634 * <code>RESULT_OPERATION_NOT_ALLOWED</code><br>
635 * <code>RESULT_INTERNAL_ERROR</code><br>
636 * <code>RESULT_NO_RESOURCES</code><br>
637 * <code>RESULT_CANCELLED</code><br>
638 * <code>RESULT_REQUEST_NOT_SUPPORTED</code><br>
639 * <code>RESULT_NO_BLUETOOTH_SERVICE</code><br>
640 * <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
641 * <code>RESULT_BLUETOOTH_DISCONNECTED</code><br>
642 * <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
643 * <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
644 * <code>RESULT_SMS_SEND_RETRY_FAILED</code><br>
645 * <code>RESULT_REMOTE_EXCEPTION</code><br>
646 * <code>RESULT_NO_DEFAULT_SMS_APP</code><br>
647 * <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
648 * <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
649 * <code>RESULT_RIL_NETWORK_REJECT</code><br>
650 * <code>RESULT_RIL_INVALID_STATE</code><br>
651 * <code>RESULT_RIL_INVALID_ARGUMENTS</code><br>
652 * <code>RESULT_RIL_NO_MEMORY</code><br>
653 * <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
654 * <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br>
655 * <code>RESULT_RIL_SYSTEM_ERR</code><br>
656 * <code>RESULT_RIL_ENCODING_ERR</code><br>
657 * <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
658 * <code>RESULT_RIL_MODEM_ERR</code><br>
659 * <code>RESULT_RIL_NETWORK_ERR</code><br>
660 * <code>RESULT_RIL_INTERNAL_ERR</code><br>
661 * <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
662 * <code>RESULT_RIL_INVALID_MODEM_STATE</code><br>
663 * <code>RESULT_RIL_NETWORK_NOT_READY</code><br>
664 * <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
665 * <code>RESULT_RIL_NO_RESOURCES</code><br>
666 * <code>RESULT_RIL_CANCELLED</code><br>
667 * <code>RESULT_RIL_SIM_ABSENT</code><br>
allenwtsua2c5de52020-11-18 13:49:58 +0800668 * <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
669 * <code>RESULT_RIL_ACCESS_BARRED</code><br>
670 * <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
Tom Taylorf43f4f02019-10-08 16:34:04 -0700671 * For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
672 * the sentIntent may include the extra "errorCode" containing a radio technology specific
673 * value, generally only useful for troubleshooting.<br>
Amit Mahajan24c01a22019-09-20 11:13:05 -0700674 * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
675 * broadcast when the message is delivered to the recipient. The
676 * raw pdu of the status report is in the extended data ("pdu").
677 * @param priority Priority level of the message
678 * Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
679 * ---------------------------------
680 * PRIORITY | Level of Priority
681 * ---------------------------------
682 * '00' | Normal
683 * '01' | Interactive
684 * '10' | Urgent
685 * '11' | Emergency
686 * ----------------------------------
687 * Any Other values included Negative considered as Invalid Priority Indicator of the message.
688 * @param expectMore is a boolean to indicate the sending messages through same link or not.
689 * @param validityPeriod Validity Period of the message in mins.
690 * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
691 * Validity Period(Minimum) -> 5 mins
692 * Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
693 * Any Other values included Negative considered as Invalid Validity Period of the message.
694 *
695 * @throws IllegalArgumentException if destinationAddress or text are empty
696 * {@hide}
697 */
Mathew Inwood8e742f92020-10-27 11:47:29 +0000698 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
Amit Mahajan24c01a22019-09-20 11:13:05 -0700699 public void sendTextMessage(
700 String destinationAddress, String scAddress, String text,
701 PendingIntent sentIntent, PendingIntent deliveryIntent,
702 int priority, boolean expectMore, int validityPeriod) {
703 sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
704 true /* persistMessage*/, priority, expectMore, validityPeriod);
705 }
706
Dan Willemsen4980bf42017-02-14 14:17:12 -0800707 private void sendTextMessageInternal(String destinationAddress, String scAddress,
708 String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
Philip P. Moltmann83083302020-03-19 17:27:39 -0700709 boolean persistMessage, String packageName, String attributionTag, long messageId) {
Dan Willemsen4980bf42017-02-14 14:17:12 -0800710 if (TextUtils.isEmpty(destinationAddress)) {
711 throw new IllegalArgumentException("Invalid destinationAddress");
712 }
713
714 if (TextUtils.isEmpty(text)) {
715 throw new IllegalArgumentException("Invalid message body");
716 }
717
Brad Ebinger360415a2019-04-30 11:37:27 -0700718 // We will only show the SMS disambiguation dialog in the case that the message is being
719 // persisted. This is for two reasons:
720 // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific
721 // subscription and require special permissions. These messages are usually not sent by
722 // the device user and should not have an SMS disambiguation dialog associated with them
723 // because the device user did not trigger them.
724 // 2) The SMS disambiguation dialog ONLY checks to make sure that the user has the SEND_SMS
725 // permission. If we call resolveSubscriptionForOperation from a carrier/OEM app that has
726 // the correct MODIFY_PHONE_STATE or carrier permissions, but no SEND_SMS, it will throw
727 // an incorrect SecurityException.
728 if (persistMessage) {
729 resolveSubscriptionForOperation(new SubscriptionResolverResult() {
730 @Override
731 public void onSuccess(int subId) {
732 ISms iSms = getISmsServiceOrThrow();
733 try {
Philip P. Moltmann83083302020-03-19 17:27:39 -0700734 iSms.sendTextForSubscriber(subId, packageName, attributionTag,
Brad Ebinger360415a2019-04-30 11:37:27 -0700735 destinationAddress, scAddress, text, sentIntent, deliveryIntent,
Tom Taylor66afc8f2019-11-20 15:39:12 -0800736 persistMessage, messageId);
Brad Ebinger360415a2019-04-30 11:37:27 -0700737 } catch (RemoteException e) {
738 Log.e(TAG, "sendTextMessageInternal: Couldn't send SMS, exception - "
Tom Taylor1befe1a2020-12-22 15:12:51 -0800739 + e.getMessage() + " " + formatCrossStackMessageId(messageId));
Tom Taylorf43f4f02019-10-08 16:34:04 -0700740 notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
Brad Ebinger360415a2019-04-30 11:37:27 -0700741 }
742 }
743
744 @Override
745 public void onFailure() {
Tom Taylorf43f4f02019-10-08 16:34:04 -0700746 notifySmsError(sentIntent, RESULT_NO_DEFAULT_SMS_APP);
Brad Ebinger360415a2019-04-30 11:37:27 -0700747 }
748 });
749 } else {
750 // Not persisting the message, used by sendTextMessageWithoutPersisting() and is not
751 // visible to the user.
Hayden Gomes7a3d8a42019-03-21 18:30:41 -0700752 ISms iSms = getISmsServiceOrThrow();
Brad Ebinger360415a2019-04-30 11:37:27 -0700753 try {
Philip P. Moltmann83083302020-03-19 17:27:39 -0700754 iSms.sendTextForSubscriber(getSubscriptionId(), packageName, attributionTag,
Brad Ebinger360415a2019-04-30 11:37:27 -0700755 destinationAddress, scAddress, text, sentIntent, deliveryIntent,
Tom Taylor66afc8f2019-11-20 15:39:12 -0800756 persistMessage, messageId);
Brad Ebinger360415a2019-04-30 11:37:27 -0700757 } catch (RemoteException e) {
758 Log.e(TAG, "sendTextMessageInternal (no persist): Couldn't send SMS, exception - "
Tom Taylor1befe1a2020-12-22 15:12:51 -0800759 + e.getMessage() + " " + formatCrossStackMessageId(messageId));
Tom Taylorf43f4f02019-10-08 16:34:04 -0700760 notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
Brad Ebinger360415a2019-04-30 11:37:27 -0700761 }
Dan Willemsen4980bf42017-02-14 14:17:12 -0800762 }
763 }
764
765 /**
766 * Send a text based SMS without writing it into the SMS Provider.
767 *
goneildcf5c042017-10-24 18:05:19 -0700768 * <p>
769 * The message will be sent directly over the network and will not be visible in SMS
770 * applications. Intended for internal carrier use only.
771 * </p>
772 *
Jeff Davidsona4a4c8a2018-03-15 17:10:58 -0700773 * <p>Requires Permission: Both {@link android.Manifest.permission#SEND_SMS} and
774 * {@link android.Manifest.permission#MODIFY_PHONE_STATE}, or that the calling app has carrier
775 * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), or that the calling app is
776 * the default IMS app (see
777 * {@link CarrierConfigManager#KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING}).
Brad Ebinger360415a2019-04-30 11:37:27 -0700778 * </p>
779 *
780 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
781 * applications or the Telephony framework and will never trigger an SMS disambiguation
782 * dialog. If this method is called on a device that has multiple active subscriptions, this
783 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
784 * default subscription is defined, the subscription ID associated with this message will be
785 * INVALID, which will result in the SMS being sent on the subscription associated with logical
786 * slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the
787 * correct subscription.
788 * </p>
Dan Willemsen4980bf42017-02-14 14:17:12 -0800789 *
790 * @see #sendTextMessage(String, String, String, PendingIntent, PendingIntent)
Dan Willemsen4980bf42017-02-14 14:17:12 -0800791 */
Jeff Davidsona4a4c8a2018-03-15 17:10:58 -0700792 @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
goneil52f3d192017-12-13 16:20:35 -0800793 @RequiresPermission(allOf = {
794 android.Manifest.permission.MODIFY_PHONE_STATE,
795 android.Manifest.permission.SEND_SMS
796 })
Dan Willemsen4980bf42017-02-14 14:17:12 -0800797 public void sendTextMessageWithoutPersisting(
798 String destinationAddress, String scAddress, String text,
799 PendingIntent sentIntent, PendingIntent deliveryIntent) {
Abhijith Shastry448c12c2017-02-14 13:02:59 -0800800 sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent,
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -0700801 false /* persistMessage */, getOpPackageName(),
802 getAttributionTag(), 0L /* messageId */);
Dan Willemsen4980bf42017-02-14 14:17:12 -0800803 }
804
Mengjun Lengb379ce92017-03-13 17:08:26 +0800805 private void sendTextMessageInternal(
806 String destinationAddress, String scAddress, String text,
807 PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage,
808 int priority, boolean expectMore, int validityPeriod) {
809 if (TextUtils.isEmpty(destinationAddress)) {
810 throw new IllegalArgumentException("Invalid destinationAddress");
811 }
812
813 if (TextUtils.isEmpty(text)) {
814 throw new IllegalArgumentException("Invalid message body");
815 }
816
817 if (priority < 0x00 || priority > 0x03) {
Taesu Lee1ec60182020-05-18 20:08:58 +0900818 Log.e(TAG, "Invalid Priority " + priority);
Mengjun Leng353bed12018-07-30 15:28:31 +0800819 priority = SMS_MESSAGE_PRIORITY_NOT_SPECIFIED;
Mengjun Lengb379ce92017-03-13 17:08:26 +0800820 }
821
822 if (validityPeriod < 0x05 || validityPeriod > 0x09b0a0) {
Taesu Lee1ec60182020-05-18 20:08:58 +0900823 Log.e(TAG, "Invalid Validity Period " + validityPeriod);
Mengjun Leng353bed12018-07-30 15:28:31 +0800824 validityPeriod = SMS_MESSAGE_PERIOD_NOT_SPECIFIED;
Mengjun Lengb379ce92017-03-13 17:08:26 +0800825 }
826
Brad Ebinger360415a2019-04-30 11:37:27 -0700827 final int finalPriority = priority;
828 final int finalValidity = validityPeriod;
Brad Ebinger360415a2019-04-30 11:37:27 -0700829 // We will only show the SMS disambiguation dialog in the case that the message is being
830 // persisted. This is for two reasons:
831 // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific
832 // subscription and require special permissions. These messages are usually not sent by
833 // the device user and should not have an SMS disambiguation dialog associated with them
834 // because the device user did not trigger them.
835 // 2) The SMS disambiguation dialog ONLY checks to make sure that the user has the SEND_SMS
836 // permission. If we call resolveSubscriptionForOperation from a carrier/OEM app that has
837 // the correct MODIFY_PHONE_STATE or carrier permissions, but no SEND_SMS, it will throw
838 // an incorrect SecurityException.
839 if (persistMessage) {
840 resolveSubscriptionForOperation(new SubscriptionResolverResult() {
841 @Override
842 public void onSuccess(int subId) {
843 try {
844 ISms iSms = getISmsServiceOrThrow();
845 if (iSms != null) {
846 iSms.sendTextForSubscriberWithOptions(subId,
Thomas Nguyena1bf6ae2023-08-22 12:00:01 -0700847 null, getAttributionTag(), destinationAddress,
Brad Ebinger360415a2019-04-30 11:37:27 -0700848 scAddress,
849 text, sentIntent, deliveryIntent, persistMessage, finalPriority,
850 expectMore, finalValidity);
851 }
852 } catch (RemoteException e) {
853 Log.e(TAG, "sendTextMessageInternal: Couldn't send SMS, exception - "
854 + e.getMessage());
Tom Taylorf43f4f02019-10-08 16:34:04 -0700855 notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
Brad Ebinger360415a2019-04-30 11:37:27 -0700856 }
857 }
858
859 @Override
860 public void onFailure() {
Tom Taylorf43f4f02019-10-08 16:34:04 -0700861 notifySmsError(sentIntent, RESULT_NO_DEFAULT_SMS_APP);
Brad Ebinger360415a2019-04-30 11:37:27 -0700862 }
863 });
864 } else {
865 try {
866 ISms iSms = getISmsServiceOrThrow();
867 if (iSms != null) {
868 iSms.sendTextForSubscriberWithOptions(getSubscriptionId(),
Thomas Nguyena1bf6ae2023-08-22 12:00:01 -0700869 null, getAttributionTag(), destinationAddress,
Brad Ebinger360415a2019-04-30 11:37:27 -0700870 scAddress,
871 text, sentIntent, deliveryIntent, persistMessage, finalPriority,
872 expectMore, finalValidity);
873 }
874 } catch (RemoteException e) {
875 Log.e(TAG, "sendTextMessageInternal(no persist): Couldn't send SMS, exception - "
876 + e.getMessage());
Tom Taylorf43f4f02019-10-08 16:34:04 -0700877 notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
Mengjun Lengb379ce92017-03-13 17:08:26 +0800878 }
Mengjun Lengb379ce92017-03-13 17:08:26 +0800879 }
880 }
881
882 /**
Mengjun Lengb379ce92017-03-13 17:08:26 +0800883 *
Dan Willemsen4980bf42017-02-14 14:17:12 -0800884 * Inject an SMS PDU into the android application framework.
885 *
Abhijith Shastrybc1a6e62017-03-29 10:54:53 -0700886 * <p>Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} or carrier
Jeff Davidsonbeb90fd2017-10-13 11:23:28 -0700887 * privileges per {@link android.telephony.TelephonyManager#hasCarrierPrivileges}.
Dan Willemsen4980bf42017-02-14 14:17:12 -0800888 *
Brad Ebinger360415a2019-04-30 11:37:27 -0700889 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
890 * applications or the Telephony framework and will never trigger an SMS disambiguation
891 * dialog. If this method is called on a device that has multiple active subscriptions, this
892 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
893 * default subscription is defined, the subscription ID associated with this message will be
894 * INVALID, which will result in the SMS being injected on the subscription associated with
895 * logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is
896 * delivered to the correct subscription.
897 * </p>
898 *
Dan Willemsen4980bf42017-02-14 14:17:12 -0800899 * @param pdu is the byte array of pdu to be injected into android application framework
Jeff Davidsonbeb90fd2017-10-13 11:23:28 -0700900 * @param format is the format of SMS pdu ({@link SmsMessage#FORMAT_3GPP} or
901 * {@link SmsMessage#FORMAT_3GPP2})
Dan Willemsen4980bf42017-02-14 14:17:12 -0800902 * @param receivedIntent if not NULL this <code>PendingIntent</code> is
903 * broadcast when the message is successfully received by the
904 * android application framework, or failed. This intent is broadcasted at
905 * the same time an SMS received from radio is acknowledged back.
Jeff Davidsonbeb90fd2017-10-13 11:23:28 -0700906 * The result code will be {@link android.provider.Telephony.Sms.Intents#RESULT_SMS_HANDLED}
Tom Taylorccc1c3e2019-10-30 10:08:50 -0700907 * for success, or {@link android.provider.Telephony.Sms.Intents#RESULT_SMS_GENERIC_ERROR} or
908 * {@link #RESULT_REMOTE_EXCEPTION} for error.
Dan Willemsen4980bf42017-02-14 14:17:12 -0800909 *
Jeff Davidsonbeb90fd2017-10-13 11:23:28 -0700910 * @throws IllegalArgumentException if the format is invalid.
Dan Willemsen4980bf42017-02-14 14:17:12 -0800911 */
Jeff Davidsonbeb90fd2017-10-13 11:23:28 -0700912 public void injectSmsPdu(
913 byte[] pdu, @SmsMessage.Format String format, PendingIntent receivedIntent) {
Dan Willemsen4980bf42017-02-14 14:17:12 -0800914 if (!format.equals(SmsMessage.FORMAT_3GPP) && !format.equals(SmsMessage.FORMAT_3GPP2)) {
915 // Format must be either 3gpp or 3gpp2.
916 throw new IllegalArgumentException(
917 "Invalid pdu format. format must be either 3gpp or 3gpp2");
918 }
919 try {
Tim Murrayc73a2812019-10-22 11:39:05 -0700920 ISms iSms = TelephonyManager.getSmsService();
Hayden Gomes7a3d8a42019-03-21 18:30:41 -0700921 if (iSms != null) {
922 iSms.injectSmsPduForSubscriber(
Dan Willemsen4980bf42017-02-14 14:17:12 -0800923 getSubscriptionId(), pdu, format, receivedIntent);
924 }
925 } catch (RemoteException ex) {
Brad Ebinger360415a2019-04-30 11:37:27 -0700926 try {
927 if (receivedIntent != null) {
Tom Taylorf43f4f02019-10-08 16:34:04 -0700928 receivedIntent.send(RESULT_REMOTE_EXCEPTION);
Brad Ebinger360415a2019-04-30 11:37:27 -0700929 }
930 } catch (PendingIntent.CanceledException cx) {
931 // Don't worry about it, we do not need to notify the caller if this is the case.
932 }
Dan Willemsen4980bf42017-02-14 14:17:12 -0800933 }
934 }
935
936 /**
Taesu Lee98d41e62018-06-15 15:26:51 +0900937 * Divide a message text into several fragments, none bigger than the maximum SMS message size.
Dan Willemsen4980bf42017-02-14 14:17:12 -0800938 *
Taesu Lee98d41e62018-06-15 15:26:51 +0900939 * @param text the original message. Must not be null.
940 * @return an <code>ArrayList</code> of strings that, in order, comprise the original message.
941 * @throws IllegalArgumentException if text is null.
Dan Willemsen4980bf42017-02-14 14:17:12 -0800942 */
943 public ArrayList<String> divideMessage(String text) {
944 if (null == text) {
945 throw new IllegalArgumentException("text is null");
946 }
Taesu Lee98d41e62018-06-15 15:26:51 +0900947 return SmsMessage.fragmentText(text, getSubscriptionId());
Dan Willemsen4980bf42017-02-14 14:17:12 -0800948 }
949
950 /**
951 * Send a multi-part text based SMS. The callee should have already
952 * divided the message into correctly sized parts by calling
953 * <code>divideMessage</code>.
954 *
955 * <p class="note"><strong>Note:</strong> Using this method requires that your app has the
956 * {@link android.Manifest.permission#SEND_SMS} permission.</p>
957 *
958 * <p class="note"><strong>Note:</strong> Beginning with Android 4.4 (API level 19), if
959 * <em>and only if</em> an app is not selected as the default SMS app, the system automatically
960 * writes messages sent using this method to the SMS Provider (the default SMS app is always
961 * responsible for writing its sent messages to the SMS Provider). For information about
962 * how to behave as the default SMS app, see {@link android.provider.Telephony}.</p>
963 *
Brad Ebinger360415a2019-04-30 11:37:27 -0700964 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
965 * manager on a multi-SIM device, this operation may fail sending the SMS message because no
966 * suitable default subscription could be found. In this case, if {@code sentIntent} is
967 * non-null, then the {@link PendingIntent} will be sent with an error code
968 * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the
969 * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions
970 * where this operation may fail.
971 * </p>
972 *
Dan Willemsen4980bf42017-02-14 14:17:12 -0800973 * @param destinationAddress the address to send the message to
974 * @param scAddress is the service center address or null to use
Taesu Lee60c671c2019-11-11 13:26:27 +0900975 * the current default SMSC
Dan Willemsen4980bf42017-02-14 14:17:12 -0800976 * @param parts an <code>ArrayList</code> of strings that, in order,
Taesu Lee60c671c2019-11-11 13:26:27 +0900977 * comprise the original message
Dan Willemsen4980bf42017-02-14 14:17:12 -0800978 * @param sentIntents if not null, an <code>ArrayList</code> of
Taesu Lee60c671c2019-11-11 13:26:27 +0900979 * <code>PendingIntent</code>s (one for each message part) that is
980 * broadcast when the corresponding message part has been sent.
981 * The result code will be <code>Activity.RESULT_OK</code> for success,
982 * or one of these errors:<br>
Tom Taylorf43f4f02019-10-08 16:34:04 -0700983 * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
984 * <code>RESULT_ERROR_RADIO_OFF</code><br>
985 * <code>RESULT_ERROR_NULL_PDU</code><br>
986 * <code>RESULT_ERROR_NO_SERVICE</code><br>
Tom Taylorf43f4f02019-10-08 16:34:04 -0700987 * <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br>
988 * <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
989 * <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
990 * <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
991 * <code>RESULT_RADIO_NOT_AVAILABLE</code><br>
992 * <code>RESULT_NETWORK_REJECT</code><br>
993 * <code>RESULT_INVALID_ARGUMENTS</code><br>
994 * <code>RESULT_INVALID_STATE</code><br>
995 * <code>RESULT_NO_MEMORY</code><br>
996 * <code>RESULT_INVALID_SMS_FORMAT</code><br>
997 * <code>RESULT_SYSTEM_ERROR</code><br>
998 * <code>RESULT_MODEM_ERROR</code><br>
999 * <code>RESULT_NETWORK_ERROR</code><br>
1000 * <code>RESULT_ENCODING_ERROR</code><br>
1001 * <code>RESULT_INVALID_SMSC_ADDRESS</code><br>
1002 * <code>RESULT_OPERATION_NOT_ALLOWED</code><br>
1003 * <code>RESULT_INTERNAL_ERROR</code><br>
1004 * <code>RESULT_NO_RESOURCES</code><br>
1005 * <code>RESULT_CANCELLED</code><br>
1006 * <code>RESULT_REQUEST_NOT_SUPPORTED</code><br>
1007 * <code>RESULT_NO_BLUETOOTH_SERVICE</code><br>
1008 * <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
1009 * <code>RESULT_BLUETOOTH_DISCONNECTED</code><br>
1010 * <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
1011 * <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
1012 * <code>RESULT_SMS_SEND_RETRY_FAILED</code><br>
1013 * <code>RESULT_REMOTE_EXCEPTION</code><br>
1014 * <code>RESULT_NO_DEFAULT_SMS_APP</code><br>
1015 * <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
1016 * <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
1017 * <code>RESULT_RIL_NETWORK_REJECT</code><br>
1018 * <code>RESULT_RIL_INVALID_STATE</code><br>
1019 * <code>RESULT_RIL_INVALID_ARGUMENTS</code><br>
1020 * <code>RESULT_RIL_NO_MEMORY</code><br>
1021 * <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
1022 * <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br>
1023 * <code>RESULT_RIL_SYSTEM_ERR</code><br>
1024 * <code>RESULT_RIL_ENCODING_ERR</code><br>
1025 * <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
1026 * <code>RESULT_RIL_MODEM_ERR</code><br>
1027 * <code>RESULT_RIL_NETWORK_ERR</code><br>
1028 * <code>RESULT_RIL_INTERNAL_ERR</code><br>
1029 * <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
1030 * <code>RESULT_RIL_INVALID_MODEM_STATE</code><br>
1031 * <code>RESULT_RIL_NETWORK_NOT_READY</code><br>
1032 * <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
1033 * <code>RESULT_RIL_NO_RESOURCES</code><br>
1034 * <code>RESULT_RIL_CANCELLED</code><br>
1035 * <code>RESULT_RIL_SIM_ABSENT</code><br>
allenwtsua2c5de52020-11-18 13:49:58 +08001036 * <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
1037 * <code>RESULT_RIL_ACCESS_BARRED</code><br>
1038 * <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
Tom Taylorf43f4f02019-10-08 16:34:04 -07001039 * For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
1040 * the sentIntent may include the extra "errorCode" containing a radio technology specific
1041 * value, generally only useful for troubleshooting.<br>
Dan Willemsen4980bf42017-02-14 14:17:12 -08001042 * @param deliveryIntents if not null, an <code>ArrayList</code> of
Taesu Lee60c671c2019-11-11 13:26:27 +09001043 * <code>PendingIntent</code>s (one for each message part) that is
1044 * broadcast when the corresponding message part has been delivered
1045 * to the recipient. The raw pdu of the status report is in the
1046 * extended data ("pdu").
Dan Willemsen4980bf42017-02-14 14:17:12 -08001047 *
1048 * @throws IllegalArgumentException if destinationAddress or data are empty
1049 */
1050 public void sendMultipartTextMessage(
1051 String destinationAddress, String scAddress, ArrayList<String> parts,
1052 ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
Abhijith Shastry448c12c2017-02-14 13:02:59 -08001053 sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -07001054 deliveryIntents, true /* persistMessage*/, getOpPackageName(),
1055 getAttributionTag(), 0L /* messageId */);
Tom Taylor66afc8f2019-11-20 15:39:12 -08001056 }
1057
1058 /**
1059 * Send a multi-part text based SMS. Same as #sendMultipartTextMessage(String, String,
1060 * ArrayList, ArrayList, ArrayList), but adds an optional messageId.
1061 * @param messageId An id that uniquely identifies the message requested to be sent.
1062 * Used for logging and diagnostics purposes. The id may be 0.
1063 *
1064 * @throws IllegalArgumentException if destinationAddress or data are empty
1065 *
1066 */
1067 public void sendMultipartTextMessage(
1068 @NonNull String destinationAddress, @Nullable String scAddress,
1069 @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
1070 @Nullable List<PendingIntent> deliveryIntents, long messageId) {
1071 sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -07001072 deliveryIntents, true /* persistMessage*/, getOpPackageName(),
1073 getAttributionTag(), messageId);
Youming Ye35c84882019-04-30 10:35:08 -07001074 }
1075
1076 /**
Youming Ye35c84882019-04-30 10:35:08 -07001077 * Similar method as #sendMultipartTextMessage(String, String, ArrayList, ArrayList, ArrayList)
Brad Ebinger360415a2019-04-30 11:37:27 -07001078 * With an additional argument.
1079 *
1080 * <p class="note"><strong>Note:</strong> This method is intended for internal use the Telephony
1081 * framework and will never trigger an SMS disambiguation dialog. If this method is called on a
1082 * device that has multiple active subscriptions, this {@link SmsManager} instance has been
1083 * created with {@link #getDefault()}, and no user-defined default subscription is defined, the
1084 * subscription ID associated with this message will be INVALID, which will result in the SMS
1085 * being sent on the subscription associated with logical slot 0. Use
1086 * {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent on the correct
1087 * subscription.
1088 * </p>
1089 *
Shuo Qian24fded62020-01-14 14:48:27 -08001090 * @param packageName serves as the default package name if the package name that is
1091 * associated with the user id is null.
Youming Ye35c84882019-04-30 10:35:08 -07001092 */
Hall Liue2f17aa2019-10-31 15:17:58 -07001093 public void sendMultipartTextMessage(
Tom Taylor66afc8f2019-11-20 15:39:12 -08001094 @NonNull String destinationAddress, @Nullable String scAddress,
Hall Liue2f17aa2019-10-31 15:17:58 -07001095 @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents,
Philip P. Moltmann83083302020-03-19 17:27:39 -07001096 @Nullable List<PendingIntent> deliveryIntents, @NonNull String packageName,
1097 @Nullable String attributionTag) {
Youming Ye35c84882019-04-30 10:35:08 -07001098 sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
Philip P. Moltmann83083302020-03-19 17:27:39 -07001099 deliveryIntents, true /* persistMessage*/, packageName, attributionTag,
1100 0L /* messageId */);
Dan Willemsen4980bf42017-02-14 14:17:12 -08001101 }
1102
1103 private void sendMultipartTextMessageInternal(
Abhijith Shastry448c12c2017-02-14 13:02:59 -08001104 String destinationAddress, String scAddress, List<String> parts,
1105 List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
Philip P. Moltmann83083302020-03-19 17:27:39 -07001106 boolean persistMessage, String packageName, @Nullable String attributionTag,
1107 long messageId) {
Dan Willemsen4980bf42017-02-14 14:17:12 -08001108 if (TextUtils.isEmpty(destinationAddress)) {
1109 throw new IllegalArgumentException("Invalid destinationAddress");
1110 }
1111 if (parts == null || parts.size() < 1) {
1112 throw new IllegalArgumentException("Invalid message body");
1113 }
1114
1115 if (parts.size() > 1) {
Brad Ebinger360415a2019-04-30 11:37:27 -07001116 // We will only show the SMS disambiguation dialog in the case that the message is being
1117 // persisted. This is for two reasons:
1118 // 1) Messages that are not persisted are sent by carrier/OEM apps for a specific
1119 // subscription and require special permissions. These messages are usually not sent
1120 // by the device user and should not have an SMS disambiguation dialog associated
1121 // with them because the device user did not trigger them.
1122 // 2) The SMS disambiguation dialog ONLY checks to make sure that the user has the
1123 // SEND_SMS permission. If we call resolveSubscriptionForOperation from a carrier/OEM
1124 // app that has the correct MODIFY_PHONE_STATE or carrier permissions, but no
1125 // SEND_SMS, it will throw an incorrect SecurityException.
1126 if (persistMessage) {
1127 resolveSubscriptionForOperation(new SubscriptionResolverResult() {
1128 @Override
1129 public void onSuccess(int subId) {
1130 try {
1131 ISms iSms = getISmsServiceOrThrow();
Philip P. Moltmann83083302020-03-19 17:27:39 -07001132 iSms.sendMultipartTextForSubscriber(subId, packageName, attributionTag,
Brad Ebinger360415a2019-04-30 11:37:27 -07001133 destinationAddress, scAddress, parts, sentIntents,
Tom Taylor66afc8f2019-11-20 15:39:12 -08001134 deliveryIntents, persistMessage, messageId);
Brad Ebinger360415a2019-04-30 11:37:27 -07001135 } catch (RemoteException e) {
1136 Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - "
Tom Taylor1befe1a2020-12-22 15:12:51 -08001137 + e.getMessage() + " " + formatCrossStackMessageId(messageId));
Tom Taylorf43f4f02019-10-08 16:34:04 -07001138 notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION);
Brad Ebinger360415a2019-04-30 11:37:27 -07001139 }
1140 }
1141
1142 @Override
1143 public void onFailure() {
Tom Taylorf43f4f02019-10-08 16:34:04 -07001144 notifySmsError(sentIntents, RESULT_NO_DEFAULT_SMS_APP);
Brad Ebinger360415a2019-04-30 11:37:27 -07001145 }
1146 });
1147 } else {
1148 // Called by apps that are not user facing, don't show disambiguation dialog.
1149 try {
1150 ISms iSms = getISmsServiceOrThrow();
1151 if (iSms != null) {
1152 iSms.sendMultipartTextForSubscriber(getSubscriptionId(), packageName,
Philip P. Moltmann83083302020-03-19 17:27:39 -07001153 attributionTag, destinationAddress, scAddress, parts, sentIntents,
1154 deliveryIntents, persistMessage, messageId);
Brad Ebinger360415a2019-04-30 11:37:27 -07001155 }
1156 } catch (RemoteException e) {
1157 Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - "
Tom Taylor1befe1a2020-12-22 15:12:51 -08001158 + e.getMessage() + " " + formatCrossStackMessageId(messageId));
Tom Taylorf43f4f02019-10-08 16:34:04 -07001159 notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION);
Brad Ebinger360415a2019-04-30 11:37:27 -07001160 }
Dan Willemsen4980bf42017-02-14 14:17:12 -08001161 }
1162 } else {
1163 PendingIntent sentIntent = null;
1164 PendingIntent deliveryIntent = null;
1165 if (sentIntents != null && sentIntents.size() > 0) {
1166 sentIntent = sentIntents.get(0);
1167 }
1168 if (deliveryIntents != null && deliveryIntents.size() > 0) {
1169 deliveryIntent = deliveryIntents.get(0);
1170 }
Youming Ye35c84882019-04-30 10:35:08 -07001171 sendTextMessageInternal(destinationAddress, scAddress, parts.get(0),
Philip P. Moltmann83083302020-03-19 17:27:39 -07001172 sentIntent, deliveryIntent, true, packageName, attributionTag, messageId);
Dan Willemsen4980bf42017-02-14 14:17:12 -08001173 }
1174 }
1175
1176 /**
1177 * Send a multi-part text based SMS without writing it into the SMS Provider.
1178 *
Brad Ebinger360415a2019-04-30 11:37:27 -07001179 * <p>
1180 * If this method is called on a device with multiple active subscriptions, this
1181 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
1182 * default subscription is defined, the subscription ID associated with this message will be
1183 * INVALID, which will result in the SMS sent on the subscription associated with slot
1184 * 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the SMS is sent using the
1185 * correct subscription.
1186 * </p>
1187 *
Abhijith Shastry448c12c2017-02-14 13:02:59 -08001188 * <p>Requires Permission:
1189 * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or the calling app has carrier
1190 * privileges.
1191 * </p>
Dan Willemsen4980bf42017-02-14 14:17:12 -08001192 *
1193 * @see #sendMultipartTextMessage(String, String, ArrayList, ArrayList, ArrayList)
1194 * @hide
1195 **/
Abhijith Shastry448c12c2017-02-14 13:02:59 -08001196 @SystemApi
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -06001197 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
Dan Willemsen4980bf42017-02-14 14:17:12 -08001198 public void sendMultipartTextMessageWithoutPersisting(
Abhijith Shastry448c12c2017-02-14 13:02:59 -08001199 String destinationAddress, String scAddress, List<String> parts,
1200 List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
1201 sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -07001202 deliveryIntents, false /* persistMessage*/, getOpPackageName(),
1203 getAttributionTag(), 0L /* messageId */);
Dan Willemsen4980bf42017-02-14 14:17:12 -08001204 }
1205
1206 /**
Mengjun Lengb379ce92017-03-13 17:08:26 +08001207 * Send a multi-part text based SMS with messaging options. The callee should have already
1208 * divided the message into correctly sized parts by calling
1209 * <code>divideMessage</code>.
1210 *
1211 * <p class="note"><strong>Note:</strong> Using this method requires that your app has the
1212 * {@link android.Manifest.permission#SEND_SMS} permission.</p>
1213 *
1214 * <p class="note"><strong>Note:</strong> Beginning with Android 4.4 (API level 19), if
1215 * <em>and only if</em> an app is not selected as the default SMS app, the system automatically
1216 * writes messages sent using this method to the SMS Provider (the default SMS app is always
1217 * responsible for writing its sent messages to the SMS Provider). For information about
1218 * how to behave as the default SMS app, see {@link android.provider.Telephony}.</p>
1219 *
Brad Ebinger360415a2019-04-30 11:37:27 -07001220 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
1221 * manager on a multi-SIM device, this operation may fail sending the SMS message because no
1222 * suitable default subscription could be found. In this case, if {@code sentIntent} is
1223 * non-null, then the {@link PendingIntent} will be sent with an error code
1224 * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the
1225 * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions
1226 * where this operation may fail.
1227 * </p>
Taesu Lee60c671c2019-11-11 13:26:27 +09001228 *
Mengjun Lengb379ce92017-03-13 17:08:26 +08001229 * @param destinationAddress the address to send the message to
1230 * @param scAddress is the service center address or null to use
Taesu Lee60c671c2019-11-11 13:26:27 +09001231 * the current default SMSC
Mengjun Lengb379ce92017-03-13 17:08:26 +08001232 * @param parts an <code>ArrayList</code> of strings that, in order,
Taesu Lee60c671c2019-11-11 13:26:27 +09001233 * comprise the original message
Mengjun Lengb379ce92017-03-13 17:08:26 +08001234 * @param sentIntents if not null, an <code>ArrayList</code> of
Taesu Lee60c671c2019-11-11 13:26:27 +09001235 * <code>PendingIntent</code>s (one for each message part) that is
1236 * broadcast when the corresponding message part has been sent.
1237 * The result code will be <code>Activity.RESULT_OK</code> for success,
1238 * or one of these errors:<br>
Tom Taylorf43f4f02019-10-08 16:34:04 -07001239 * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
1240 * <code>RESULT_ERROR_RADIO_OFF</code><br>
1241 * <code>RESULT_ERROR_NULL_PDU</code><br>
1242 * <code>RESULT_ERROR_NO_SERVICE</code><br>
Tom Taylorf43f4f02019-10-08 16:34:04 -07001243 * <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br>
1244 * <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
1245 * <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
1246 * <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
1247 * <code>RESULT_RADIO_NOT_AVAILABLE</code><br>
1248 * <code>RESULT_NETWORK_REJECT</code><br>
1249 * <code>RESULT_INVALID_ARGUMENTS</code><br>
1250 * <code>RESULT_INVALID_STATE</code><br>
1251 * <code>RESULT_NO_MEMORY</code><br>
1252 * <code>RESULT_INVALID_SMS_FORMAT</code><br>
1253 * <code>RESULT_SYSTEM_ERROR</code><br>
1254 * <code>RESULT_MODEM_ERROR</code><br>
1255 * <code>RESULT_NETWORK_ERROR</code><br>
1256 * <code>RESULT_ENCODING_ERROR</code><br>
1257 * <code>RESULT_INVALID_SMSC_ADDRESS</code><br>
1258 * <code>RESULT_OPERATION_NOT_ALLOWED</code><br>
1259 * <code>RESULT_INTERNAL_ERROR</code><br>
1260 * <code>RESULT_NO_RESOURCES</code><br>
1261 * <code>RESULT_CANCELLED</code><br>
1262 * <code>RESULT_REQUEST_NOT_SUPPORTED</code><br>
1263 * <code>RESULT_NO_BLUETOOTH_SERVICE</code><br>
1264 * <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
1265 * <code>RESULT_BLUETOOTH_DISCONNECTED</code><br>
1266 * <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
1267 * <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
1268 * <code>RESULT_SMS_SEND_RETRY_FAILED</code><br>
1269 * <code>RESULT_REMOTE_EXCEPTION</code><br>
1270 * <code>RESULT_NO_DEFAULT_SMS_APP</code><br>
1271 * <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
1272 * <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
1273 * <code>RESULT_RIL_NETWORK_REJECT</code><br>
1274 * <code>RESULT_RIL_INVALID_STATE</code><br>
1275 * <code>RESULT_RIL_INVALID_ARGUMENTS</code><br>
1276 * <code>RESULT_RIL_NO_MEMORY</code><br>
1277 * <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
1278 * <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br>
1279 * <code>RESULT_RIL_SYSTEM_ERR</code><br>
1280 * <code>RESULT_RIL_ENCODING_ERR</code><br>
1281 * <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
1282 * <code>RESULT_RIL_MODEM_ERR</code><br>
1283 * <code>RESULT_RIL_NETWORK_ERR</code><br>
1284 * <code>RESULT_RIL_INTERNAL_ERR</code><br>
1285 * <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
1286 * <code>RESULT_RIL_INVALID_MODEM_STATE</code><br>
1287 * <code>RESULT_RIL_NETWORK_NOT_READY</code><br>
1288 * <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
1289 * <code>RESULT_RIL_NO_RESOURCES</code><br>
1290 * <code>RESULT_RIL_CANCELLED</code><br>
1291 * <code>RESULT_RIL_SIM_ABSENT</code><br>
allenwtsua2c5de52020-11-18 13:49:58 +08001292 * <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
1293 * <code>RESULT_RIL_ACCESS_BARRED</code><br>
1294 * <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
Tom Taylorf43f4f02019-10-08 16:34:04 -07001295 * For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
1296 * the sentIntent may include the extra "errorCode" containing a radio technology specific
1297 * value, generally only useful for troubleshooting.<br>
Mengjun Lengb379ce92017-03-13 17:08:26 +08001298 * @param deliveryIntents if not null, an <code>ArrayList</code> of
Taesu Lee60c671c2019-11-11 13:26:27 +09001299 * <code>PendingIntent</code>s (one for each message part) that is
1300 * broadcast when the corresponding message part has been delivered
1301 * to the recipient. The raw pdu of the status report is in the
1302 * extended data ("pdu").
Mengjun Lengb379ce92017-03-13 17:08:26 +08001303 * @param priority Priority level of the message
1304 * Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
1305 * ---------------------------------
1306 * PRIORITY | Level of Priority
1307 * ---------------------------------
1308 * '00' | Normal
1309 * '01' | Interactive
1310 * '10' | Urgent
1311 * '11' | Emergency
1312 * ----------------------------------
1313 * Any Other values included Negative considered as Invalid Priority Indicator of the message.
1314 * @param expectMore is a boolean to indicate the sending messages through same link or not.
1315 * @param validityPeriod Validity Period of the message in mins.
1316 * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
1317 * Validity Period(Minimum) -> 5 mins
1318 * Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
1319 * Any Other values included Negative considered as Invalid Validity Period of the message.
1320 *
1321 * @throws IllegalArgumentException if destinationAddress or data are empty
1322 * {@hide}
1323 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001324 @UnsupportedAppUsage
Mengjun Lengb379ce92017-03-13 17:08:26 +08001325 public void sendMultipartTextMessage(
1326 String destinationAddress, String scAddress, ArrayList<String> parts,
1327 ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents,
1328 int priority, boolean expectMore, int validityPeriod) {
1329 sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents,
Mengjun Leng353bed12018-07-30 15:28:31 +08001330 deliveryIntents, true /* persistMessage*/, priority, expectMore,
1331 validityPeriod);
Mengjun Lengb379ce92017-03-13 17:08:26 +08001332 }
1333
1334 private void sendMultipartTextMessageInternal(
1335 String destinationAddress, String scAddress, List<String> parts,
1336 List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
1337 boolean persistMessage, int priority, boolean expectMore, int validityPeriod) {
1338 if (TextUtils.isEmpty(destinationAddress)) {
1339 throw new IllegalArgumentException("Invalid destinationAddress");
1340 }
1341 if (parts == null || parts.size() < 1) {
1342 throw new IllegalArgumentException("Invalid message body");
1343 }
1344
1345 if (priority < 0x00 || priority > 0x03) {
Taesu Lee1ec60182020-05-18 20:08:58 +09001346 Log.e(TAG, "Invalid Priority " + priority);
Brad Ebinger360415a2019-04-30 11:37:27 -07001347 priority = SMS_MESSAGE_PRIORITY_NOT_SPECIFIED;
Mengjun Lengb379ce92017-03-13 17:08:26 +08001348 }
1349
1350 if (validityPeriod < 0x05 || validityPeriod > 0x09b0a0) {
Taesu Lee1ec60182020-05-18 20:08:58 +09001351 Log.e(TAG, "Invalid Validity Period " + validityPeriod);
Brad Ebinger360415a2019-04-30 11:37:27 -07001352 validityPeriod = SMS_MESSAGE_PERIOD_NOT_SPECIFIED;
Mengjun Lengb379ce92017-03-13 17:08:26 +08001353 }
1354
1355 if (parts.size() > 1) {
Brad Ebinger360415a2019-04-30 11:37:27 -07001356 final int finalPriority = priority;
1357 final int finalValidity = validityPeriod;
Brad Ebinger360415a2019-04-30 11:37:27 -07001358 if (persistMessage) {
1359 resolveSubscriptionForOperation(new SubscriptionResolverResult() {
1360 @Override
1361 public void onSuccess(int subId) {
1362 try {
1363 ISms iSms = getISmsServiceOrThrow();
1364 if (iSms != null) {
1365 iSms.sendMultipartTextForSubscriberWithOptions(subId,
Philip P. Moltmann83083302020-03-19 17:27:39 -07001366 null, null, destinationAddress,
Brad Ebinger360415a2019-04-30 11:37:27 -07001367 scAddress, parts, sentIntents, deliveryIntents,
1368 persistMessage, finalPriority, expectMore, finalValidity);
1369 }
1370 } catch (RemoteException e) {
1371 Log.e(TAG, "sendMultipartTextMessageInternal: Couldn't send SMS - "
1372 + e.getMessage());
Tom Taylorf43f4f02019-10-08 16:34:04 -07001373 notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION);
Brad Ebinger360415a2019-04-30 11:37:27 -07001374 }
1375 }
1376
1377 @Override
1378 public void onFailure() {
Tom Taylorf43f4f02019-10-08 16:34:04 -07001379 notifySmsError(sentIntents, RESULT_NO_DEFAULT_SMS_APP);
Brad Ebinger360415a2019-04-30 11:37:27 -07001380 }
1381 });
1382 } else {
1383 // Sent by apps that are not user visible, so don't show SIM disambiguation dialog.
1384 try {
1385 ISms iSms = getISmsServiceOrThrow();
1386 if (iSms != null) {
1387 iSms.sendMultipartTextForSubscriberWithOptions(getSubscriptionId(),
Philip P. Moltmann83083302020-03-19 17:27:39 -07001388 null, null, destinationAddress,
Brad Ebinger360415a2019-04-30 11:37:27 -07001389 scAddress, parts, sentIntents, deliveryIntents,
1390 persistMessage, finalPriority, expectMore, finalValidity);
1391 }
1392 } catch (RemoteException e) {
1393 Log.e(TAG, "sendMultipartTextMessageInternal (no persist): Couldn't send SMS - "
1394 + e.getMessage());
Tom Taylorf43f4f02019-10-08 16:34:04 -07001395 notifySmsError(sentIntents, RESULT_REMOTE_EXCEPTION);
Mengjun Lengb379ce92017-03-13 17:08:26 +08001396 }
Mengjun Lengb379ce92017-03-13 17:08:26 +08001397 }
1398 } else {
1399 PendingIntent sentIntent = null;
1400 PendingIntent deliveryIntent = null;
1401 if (sentIntents != null && sentIntents.size() > 0) {
1402 sentIntent = sentIntents.get(0);
1403 }
1404 if (deliveryIntents != null && deliveryIntents.size() > 0) {
1405 deliveryIntent = deliveryIntents.get(0);
1406 }
1407 sendTextMessageInternal(destinationAddress, scAddress, parts.get(0),
1408 sentIntent, deliveryIntent, persistMessage, priority, expectMore,
1409 validityPeriod);
1410 }
1411 }
1412
1413 /**
Dan Willemsen4980bf42017-02-14 14:17:12 -08001414 * Send a data based SMS to a specific application port.
1415 *
1416 * <p class="note"><strong>Note:</strong> Using this method requires that your app has the
1417 * {@link android.Manifest.permission#SEND_SMS} permission.</p>
1418 *
Brad Ebinger360415a2019-04-30 11:37:27 -07001419 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
1420 * manager on a multi-SIM device, this operation may fail sending the SMS message because no
1421 * suitable default subscription could be found. In this case, if {@code sentIntent} is
1422 * non-null, then the {@link PendingIntent} will be sent with an error code
1423 * {@code RESULT_ERROR_GENERIC_FAILURE} and an extra string {@code "noDefault"} containing the
1424 * boolean value {@code true}. See {@link #getDefault()} for more information on the conditions
1425 * where this operation may fail.
1426 * </p>
1427 *
Dan Willemsen4980bf42017-02-14 14:17:12 -08001428 * @param destinationAddress the address to send the message to
1429 * @param scAddress is the service center address or null to use
1430 * the current default SMSC
1431 * @param destinationPort the port to deliver the message to
1432 * @param data the body of the message to send
1433 * @param sentIntent if not NULL this <code>PendingIntent</code> is
1434 * broadcast when the message is successfully sent, or failed.
1435 * The result code will be <code>Activity.RESULT_OK</code> for success,
1436 * or one of these errors:<br>
1437 * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
1438 * <code>RESULT_ERROR_RADIO_OFF</code><br>
1439 * <code>RESULT_ERROR_NULL_PDU</code><br>
Tom Taylorf43f4f02019-10-08 16:34:04 -07001440 * <code>RESULT_ERROR_NO_SERVICE</code><br>
Tom Taylorf43f4f02019-10-08 16:34:04 -07001441 * <code>RESULT_ERROR_LIMIT_EXCEEDED</code><br>
1442 * <code>RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
1443 * <code>RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
1444 * <code>RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
1445 * <code>RESULT_RADIO_NOT_AVAILABLE</code><br>
1446 * <code>RESULT_NETWORK_REJECT</code><br>
1447 * <code>RESULT_INVALID_ARGUMENTS</code><br>
1448 * <code>RESULT_INVALID_STATE</code><br>
1449 * <code>RESULT_NO_MEMORY</code><br>
1450 * <code>RESULT_INVALID_SMS_FORMAT</code><br>
1451 * <code>RESULT_SYSTEM_ERROR</code><br>
1452 * <code>RESULT_MODEM_ERROR</code><br>
1453 * <code>RESULT_NETWORK_ERROR</code><br>
1454 * <code>RESULT_ENCODING_ERROR</code><br>
1455 * <code>RESULT_INVALID_SMSC_ADDRESS</code><br>
1456 * <code>RESULT_OPERATION_NOT_ALLOWED</code><br>
1457 * <code>RESULT_INTERNAL_ERROR</code><br>
1458 * <code>RESULT_NO_RESOURCES</code><br>
1459 * <code>RESULT_CANCELLED</code><br>
1460 * <code>RESULT_REQUEST_NOT_SUPPORTED</code><br>
1461 * <code>RESULT_NO_BLUETOOTH_SERVICE</code><br>
1462 * <code>RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
1463 * <code>RESULT_BLUETOOTH_DISCONNECTED</code><br>
1464 * <code>RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
1465 * <code>RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
1466 * <code>RESULT_SMS_SEND_RETRY_FAILED</code><br>
1467 * <code>RESULT_REMOTE_EXCEPTION</code><br>
1468 * <code>RESULT_NO_DEFAULT_SMS_APP</code><br>
1469 * <code>RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
1470 * <code>RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
1471 * <code>RESULT_RIL_NETWORK_REJECT</code><br>
1472 * <code>RESULT_RIL_INVALID_STATE</code><br>
1473 * <code>RESULT_RIL_INVALID_ARGUMENTS</code><br>
1474 * <code>RESULT_RIL_NO_MEMORY</code><br>
1475 * <code>RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
1476 * <code>RESULT_RIL_INVALID_SMS_FORMAT</code><br>
1477 * <code>RESULT_RIL_SYSTEM_ERR</code><br>
1478 * <code>RESULT_RIL_ENCODING_ERR</code><br>
1479 * <code>RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
1480 * <code>RESULT_RIL_MODEM_ERR</code><br>
1481 * <code>RESULT_RIL_NETWORK_ERR</code><br>
1482 * <code>RESULT_RIL_INTERNAL_ERR</code><br>
1483 * <code>RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
1484 * <code>RESULT_RIL_INVALID_MODEM_STATE</code><br>
1485 * <code>RESULT_RIL_NETWORK_NOT_READY</code><br>
1486 * <code>RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
1487 * <code>RESULT_RIL_NO_RESOURCES</code><br>
1488 * <code>RESULT_RIL_CANCELLED</code><br>
1489 * <code>RESULT_RIL_SIM_ABSENT</code><br>
allenwtsua2c5de52020-11-18 13:49:58 +08001490 * <code>RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
1491 * <code>RESULT_RIL_ACCESS_BARRED</code><br>
1492 * <code>RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
Tom Taylorf43f4f02019-10-08 16:34:04 -07001493 * For <code>RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
1494 * the sentIntent may include the extra "errorCode" containing a radio technology specific
1495 * value, generally only useful for troubleshooting.<br>
Dan Willemsen4980bf42017-02-14 14:17:12 -08001496 * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
1497 * broadcast when the message is delivered to the recipient. The
1498 * raw pdu of the status report is in the extended data ("pdu").
1499 *
1500 * @throws IllegalArgumentException if destinationAddress or data are empty
1501 */
1502 public void sendDataMessage(
1503 String destinationAddress, String scAddress, short destinationPort,
1504 byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
1505 if (TextUtils.isEmpty(destinationAddress)) {
1506 throw new IllegalArgumentException("Invalid destinationAddress");
1507 }
1508
1509 if (data == null || data.length == 0) {
1510 throw new IllegalArgumentException("Invalid message data");
1511 }
1512
Brad Ebinger360415a2019-04-30 11:37:27 -07001513 resolveSubscriptionForOperation(new SubscriptionResolverResult() {
1514 @Override
1515 public void onSuccess(int subId) {
1516 try {
1517 ISms iSms = getISmsServiceOrThrow();
Thomas Nguyena1bf6ae2023-08-22 12:00:01 -07001518 iSms.sendDataForSubscriber(subId, null, getAttributionTag(), destinationAddress,
1519 scAddress, destinationPort & 0xFFFF, data, sentIntent, deliveryIntent);
Brad Ebinger360415a2019-04-30 11:37:27 -07001520 } catch (RemoteException e) {
1521 Log.e(TAG, "sendDataMessage: Couldn't send SMS - Exception: " + e.getMessage());
Tom Taylorf43f4f02019-10-08 16:34:04 -07001522 notifySmsError(sentIntent, RESULT_REMOTE_EXCEPTION);
Brad Ebinger360415a2019-04-30 11:37:27 -07001523 }
1524 }
1525 @Override
1526 public void onFailure() {
Tom Taylorf43f4f02019-10-08 16:34:04 -07001527 notifySmsError(sentIntent, RESULT_NO_DEFAULT_SMS_APP);
Brad Ebinger360415a2019-04-30 11:37:27 -07001528 }
1529 });
Dan Willemsen4980bf42017-02-14 14:17:12 -08001530 }
1531
1532 /**
Dan Willemsen4980bf42017-02-14 14:17:12 -08001533 * Get the SmsManager associated with the default subscription id. The instance will always be
Brad Ebingerfa82ddd2019-04-30 11:34:14 -07001534 * associated with the default subscription id, even if the default subscription id changes.
Dan Willemsen4980bf42017-02-14 14:17:12 -08001535 *
Brad Ebinger360415a2019-04-30 11:37:27 -07001536 * <p class="note"><strong>Note:</strong> For devices that support multiple active subscriptions
1537 * at a time, SmsManager will track the subscription set by the user as the default SMS
1538 * subscription. If the user has not set a default, {@link SmsManager} may
1539 * start an activity to kick off a subscription disambiguation dialog. Most operations will not
1540 * complete until the user has chosen the subscription that will be associated with the
1541 * operation. If the user cancels the dialog without choosing a subscription, one of the
1542 * following will happen, depending on the target SDK version of the application. For
1543 * compatibility purposes, if the target SDK level is <= 28, telephony will still send the SMS
1544 * over the first available subscription. If the target SDK level is > 28, the operation will
1545 * fail to complete.
1546 * </p>
1547 *
1548 * <p class="note"><strong>Note:</strong> If this method is used to perform an operation on a
1549 * device that has multiple active subscriptions, the user has not set a default SMS
1550 * subscription, and the operation is being performed while the application is not in the
1551 * foreground, the SMS disambiguation dialog will not be shown. The result of the operation will
1552 * conclude as if the user cancelled the disambiguation dialog and the operation will finish as
1553 * outlined above, depending on the target SDK version of the calling application. It is safer
1554 * to use {@link #getSmsManagerForSubscriptionId(int)} if the application will perform the
1555 * operation while in the background because this can cause unpredictable results, such as the
1556 * operation being sent over the wrong subscription or failing completely, depending on the
1557 * user's default SMS subscription setting.
1558 * </p>
1559 *
1560 * @return the {@link SmsManager} associated with the default subscription id.
1561 *
1562 * @see SubscriptionManager#getDefaultSmsSubscriptionId()
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -07001563 *
1564 * @deprecated Use {@link Context#getSystemService Context.getSystemService(SmsManager.class)}
1565 * instead
Dan Willemsen4980bf42017-02-14 14:17:12 -08001566 */
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -07001567 @Deprecated
Dan Willemsen4980bf42017-02-14 14:17:12 -08001568 public static SmsManager getDefault() {
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -07001569 return DEFAULT_INSTANCE;
1570 }
1571
1572 /**
1573 * Get the instance of the SmsManager associated with a particular context and subscription ID.
1574 *
1575 * @param context The context the manager belongs to
1576 * @param subId an SMS subscription ID, typically accessed using {@link SubscriptionManager}
1577 *
1578 * @return the instance of the SmsManager associated with subscription
1579 *
1580 * @hide
1581 */
1582 public static @NonNull SmsManager getSmsManagerForContextAndSubscriptionId(
1583 @Nullable Context context, int subId) {
1584 synchronized(sLockObject) {
1585 Pair<Context, Integer> key = new Pair<>(context, subId);
1586
1587 SmsManager smsManager = sSubInstances.get(key);
1588 if (smsManager == null) {
1589 smsManager = new SmsManager(context, subId);
1590 sSubInstances.put(key, smsManager);
1591 }
1592 return smsManager;
1593 }
1594 }
1595
1596 /**
1597 * Get the instance of the SmsManager associated with a particular subscription ID.
1598 *
1599 * <p class="note"><strong>Note:</strong> Constructing an {@link SmsManager} in this manner will
1600 * never cause an SMS disambiguation dialog to appear, unlike {@link #getDefault()}.
1601 * </p>
1602 *
1603 * @param subId an SMS subscription ID, typically accessed using {@link SubscriptionManager}
1604 * @return the instance of the SmsManager associated with subscription
1605 *
1606 * @see SubscriptionManager#getActiveSubscriptionInfoList()
1607 * @see SubscriptionManager#getDefaultSmsSubscriptionId()
1608 * @deprecated Use {@link Context#getSystemService Context.getSystemService(SmsManager.class)}
1609 * .{@link #createForSubscriptionId createForSubscriptionId(subId)} instead
1610 */
1611 @Deprecated
1612 public static SmsManager getSmsManagerForSubscriptionId(int subId) {
1613 return getSmsManagerForContextAndSubscriptionId(null, subId);
Dan Willemsen4980bf42017-02-14 14:17:12 -08001614 }
1615
1616 /**
Brad Ebinger360415a2019-04-30 11:37:27 -07001617 * Get the instance of the SmsManager associated with a particular subscription ID.
Dan Willemsen4980bf42017-02-14 14:17:12 -08001618 *
Brad Ebinger360415a2019-04-30 11:37:27 -07001619 * <p class="note"><strong>Note:</strong> Constructing an {@link SmsManager} in this manner will
1620 * never cause an SMS disambiguation dialog to appear, unlike {@link #getDefault()}.
1621 * </p>
Brad Ebingerfa82ddd2019-04-30 11:34:14 -07001622 *
1623 * @param subId an SMS subscription ID, typically accessed using {@link SubscriptionManager}
1624 * @return the instance of the SmsManager associated with subscription
1625 *
1626 * @see SubscriptionManager#getActiveSubscriptionInfoList()
1627 * @see SubscriptionManager#getDefaultSmsSubscriptionId()
Dan Willemsen4980bf42017-02-14 14:17:12 -08001628 */
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -07001629 public @NonNull SmsManager createForSubscriptionId(int subId) {
1630 return getSmsManagerForContextAndSubscriptionId(mContext, subId);
Dan Willemsen4980bf42017-02-14 14:17:12 -08001631 }
1632
Philip P. Moltmann7ebd5592020-07-16 14:37:30 -07001633 private SmsManager(@Nullable Context context, int subId) {
1634 mContext = context;
Dan Willemsen4980bf42017-02-14 14:17:12 -08001635 mSubId = subId;
1636 }
1637
1638 /**
1639 * Get the associated subscription id. If the instance was returned by {@link #getDefault()},
1640 * then this method may return different values at different points in time (if the user
Brad Ebingerfa82ddd2019-04-30 11:34:14 -07001641 * changes the default subscription id).
Dan Willemsen4980bf42017-02-14 14:17:12 -08001642 *
Brad Ebinger360415a2019-04-30 11:37:27 -07001643 * <p class="note"><strong>Note:</strong> This method used to display a disambiguation dialog to
1644 * the user asking them to choose a default subscription to send SMS messages over if they
1645 * haven't chosen yet. Starting in API level 29, we allow the user to not have a default set as
1646 * a valid option for the default SMS subscription on multi-SIM devices. We no longer show the
1647 * disambiguation dialog and return {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if the
1648 * device has multiple active subscriptions and no default is set.
1649 * </p>
Dan Willemsen4980bf42017-02-14 14:17:12 -08001650 *
Brad Ebingerfa82ddd2019-04-30 11:34:14 -07001651 * @return associated subscription ID or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if
Brad Ebinger360415a2019-04-30 11:37:27 -07001652 * the default subscription id cannot be determined or the device has multiple active
Brad Ebingerfa82ddd2019-04-30 11:34:14 -07001653 * subscriptions and and no default is set ("ask every time") by the user.
Dan Willemsen4980bf42017-02-14 14:17:12 -08001654 */
1655 public int getSubscriptionId() {
Brad Ebinger360415a2019-04-30 11:37:27 -07001656 try {
1657 return (mSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)
1658 ? getISmsServiceOrThrow().getPreferredSmsSubscription() : mSubId;
1659 } catch (RemoteException e) {
1660 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1661 }
1662 }
1663
1664 /**
1665 * Resolves the subscription id to use for the associated operation if
1666 * {@link #getSubscriptionId()} returns {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
1667 *
1668 * If app targets API level 28 or below and they are either sending the SMS from the background
1669 * or the device has more than one active subscription available and no default is set, we will
1670 * use the first logical slot to send the SMS and possibly fail later in the SMS sending
1671 * process.
1672 *
1673 * Regardless of the API level, if the app is the foreground app, then we will show the SMS
1674 * disambiguation dialog. If the app is in the background and tries to perform an operation, we
1675 * will not show the disambiguation dialog.
1676 *
1677 * See {@link #getDefault()} for a detailed explanation of how this method operates.
1678 *
1679 * @param resolverResult The callback that will be called when the subscription is resolved or
1680 * fails to be resolved.
1681 */
1682 private void resolveSubscriptionForOperation(SubscriptionResolverResult resolverResult) {
1683 int subId = getSubscriptionId();
1684 boolean isSmsSimPickActivityNeeded = false;
Brad Ebinger360415a2019-04-30 11:37:27 -07001685 try {
1686 ISms iSms = getISmsService();
1687 if (iSms != null) {
1688 // Determines if the SMS SIM pick activity should be shown. This is only shown if:
1689 // 1) The device has multiple active subscriptions and an SMS default subscription
1690 // hasn't been set, and
1691 // 2) SmsManager is being called from the foreground app.
1692 // Android does not allow background activity starts, so we need to block this.
1693 // if Q+, do not perform requested operation if these two operations are not set. If
1694 // <P, perform these operations on phone 0 (for compatibility purposes, since we
1695 // used to not wait for the result of this activity).
1696 isSmsSimPickActivityNeeded = iSms.isSmsSimPickActivityNeeded(subId);
1697 }
1698 } catch (RemoteException ex) {
1699 Log.e(TAG, "resolveSubscriptionForOperation", ex);
1700 }
1701 if (!isSmsSimPickActivityNeeded) {
1702 sendResolverResult(resolverResult, subId, false /*pickActivityShown*/);
1703 return;
1704 }
1705 // We need to ask the user pick an appropriate subid for the operation.
Shuo Qian24fded62020-01-14 14:48:27 -08001706 Log.d(TAG, "resolveSubscriptionForOperation isSmsSimPickActivityNeeded is true for calling"
1707 + " package. ");
Brad Ebinger360415a2019-04-30 11:37:27 -07001708 try {
1709 // Create the SMS pick activity and call back once the activity is complete. Can't do
1710 // it here because we do not have access to the activity context that is performing this
1711 // operation.
1712 // Requires that the calling process has the SEND_SMS permission.
Philip P. Moltmann83083302020-03-19 17:27:39 -07001713 getITelephony().enqueueSmsPickResult(null, null,
Brad Ebinger360415a2019-04-30 11:37:27 -07001714 new IIntegerConsumer.Stub() {
1715 @Override
1716 public void accept(int subId) {
1717 // Runs on binder thread attached to this app's process.
1718 sendResolverResult(resolverResult, subId, true /*pickActivityShown*/);
1719 }
1720 });
1721 } catch (RemoteException ex) {
1722 Log.e(TAG, "Unable to launch activity", ex);
1723 // pickActivityShown is true here because we want to call sendResolverResult and always
1724 // have this operation fail. This is because we received a RemoteException here, which
1725 // means that telephony is not available and the next operation to Telephony will fail
1726 // as well anyways, so we might as well shortcut fail here first.
1727 sendResolverResult(resolverResult, subId, true /*pickActivityShown*/);
1728 }
1729 }
1730
Shuo Qian24fded62020-01-14 14:48:27 -08001731 /**
1732 * To check the SDK version for SmsManager.sendResolverResult method.
1733 */
1734 @ChangeId
1735 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.P)
1736 private static final long GET_TARGET_SDK_VERSION_CODE_CHANGE = 145147528L;
1737
Brad Ebinger360415a2019-04-30 11:37:27 -07001738 private void sendResolverResult(SubscriptionResolverResult resolverResult, int subId,
1739 boolean pickActivityShown) {
1740 if (SubscriptionManager.isValidSubscriptionId(subId)) {
1741 resolverResult.onSuccess(subId);
1742 return;
1743 }
1744
Shuo Qian24fded62020-01-14 14:48:27 -08001745 if (!Compatibility.isChangeEnabled(GET_TARGET_SDK_VERSION_CODE_CHANGE)
1746 && !pickActivityShown) {
Brad Ebinger360415a2019-04-30 11:37:27 -07001747 // Do not fail, return a success with an INVALID subid for apps targeting P or below
1748 // that tried to perform an operation and the SMS disambiguation dialog was never shown,
1749 // as these applications may not have been written to handle the failure case properly.
1750 // This will resolve to performing the operation on phone 0 in telephony.
1751 resolverResult.onSuccess(subId);
1752 } else {
1753 // Fail if the app targets Q or above or it targets P and below and the disambiguation
1754 // dialog was shown and the user clicked out of it.
1755 resolverResult.onFailure();
1756 }
1757 }
1758
Brad Ebinger360415a2019-04-30 11:37:27 -07001759 private static ITelephony getITelephony() {
1760 ITelephony binder = ITelephony.Stub.asInterface(
Peter Wangd9eebca2019-12-30 16:14:01 -08001761 TelephonyFrameworkInitializer
1762 .getTelephonyServiceManager()
1763 .getTelephonyServiceRegisterer()
1764 .get());
Brad Ebinger360415a2019-04-30 11:37:27 -07001765 if (binder == null) {
1766 throw new RuntimeException("Could not find Telephony Service.");
1767 }
1768 return binder;
1769 }
1770
Tom Taylorf43f4f02019-10-08 16:34:04 -07001771 private static void notifySmsError(PendingIntent pendingIntent, int error) {
Brad Ebinger360415a2019-04-30 11:37:27 -07001772 if (pendingIntent != null) {
Brad Ebinger360415a2019-04-30 11:37:27 -07001773 try {
Tom Taylorf43f4f02019-10-08 16:34:04 -07001774 pendingIntent.send(error);
Brad Ebinger360415a2019-04-30 11:37:27 -07001775 } catch (PendingIntent.CanceledException e) {
1776 // Don't worry about it, we do not need to notify the caller if this is the case.
1777 }
1778 }
1779 }
1780
Tom Taylorf43f4f02019-10-08 16:34:04 -07001781 private static void notifySmsError(List<PendingIntent> pendingIntents, int error) {
Brad Ebinger360415a2019-04-30 11:37:27 -07001782 if (pendingIntents != null) {
1783 for (PendingIntent pendingIntent : pendingIntents) {
Tom Taylorf43f4f02019-10-08 16:34:04 -07001784 notifySmsError(pendingIntent, error);
Brad Ebinger360415a2019-04-30 11:37:27 -07001785 }
1786 }
Brad Ebinger099d9852019-03-28 15:46:50 -07001787 }
1788
1789 /**
Dan Willemsen4980bf42017-02-14 14:17:12 -08001790 * Returns the ISms service, or throws an UnsupportedOperationException if
1791 * the service does not exist.
1792 */
1793 private static ISms getISmsServiceOrThrow() {
Tim Murrayc73a2812019-10-22 11:39:05 -07001794 ISms iSms = TelephonyManager.getSmsService();
Hayden Gomes7a3d8a42019-03-21 18:30:41 -07001795 if (iSms == null) {
Dan Willemsen4980bf42017-02-14 14:17:12 -08001796 throw new UnsupportedOperationException("Sms is not supported");
1797 }
Hayden Gomes7a3d8a42019-03-21 18:30:41 -07001798 return iSms;
Dan Willemsen4980bf42017-02-14 14:17:12 -08001799 }
1800
1801 private static ISms getISmsService() {
Tim Murrayc73a2812019-10-22 11:39:05 -07001802 return TelephonyManager.getSmsService();
Dan Willemsen4980bf42017-02-14 14:17:12 -08001803 }
1804
1805 /**
Taesu Lee27e67c22019-12-11 10:10:49 +09001806 * Copies a raw SMS PDU to the ICC.
Dan Willemsen4980bf42017-02-14 14:17:12 -08001807 * ICC (Integrated Circuit Card) is the card of the device.
1808 * For example, this can be the SIM or USIM for GSM.
1809 *
Brad Ebinger360415a2019-04-30 11:37:27 -07001810 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
1811 * applications or the Telephony framework and will never trigger an SMS disambiguation
1812 * dialog. If this method is called on a device that has multiple active subscriptions, this
1813 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
1814 * default subscription is defined, the subscription ID associated with this message will be
1815 * INVALID, which will result in the operation being completed on the subscription associated
1816 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
1817 * operation is performed on the correct subscription.
1818 * </p>
1819 *
Taesu Lee27e67c22019-12-11 10:10:49 +09001820 * @param smsc the SMSC for this messag or null for the default SMSC.
1821 * @param pdu the raw PDU to store.
1822 * @param status message status. One of these status:
1823 * <code>STATUS_ON_ICC_READ</code>
1824 * <code>STATUS_ON_ICC_UNREAD</code>
1825 * <code>STATUS_ON_ICC_SENT</code>
1826 * <code>STATUS_ON_ICC_UNSENT</code>
1827 * @return true for success. Otherwise false.
Dan Willemsen4980bf42017-02-14 14:17:12 -08001828 *
Taesu Lee27e67c22019-12-11 10:10:49 +09001829 * @throws IllegalArgumentException if pdu is null.
1830 * @hide
Dan Willemsen4980bf42017-02-14 14:17:12 -08001831 */
Taesu Lee27e67c22019-12-11 10:10:49 +09001832 @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC)
1833 public boolean copyMessageToIcc(
1834 @Nullable byte[] smsc, @NonNull byte[] pdu, @StatusOnIcc int status) {
Dan Willemsen4980bf42017-02-14 14:17:12 -08001835 boolean success = false;
1836
Taesu Lee27e67c22019-12-11 10:10:49 +09001837 if (pdu == null) {
1838 throw new IllegalArgumentException("pdu is null");
Dan Willemsen4980bf42017-02-14 14:17:12 -08001839 }
1840 try {
Hayden Gomes7a3d8a42019-03-21 18:30:41 -07001841 ISms iSms = getISmsService();
1842 if (iSms != null) {
1843 success = iSms.copyMessageToIccEfForSubscriber(getSubscriptionId(),
Shuo Qian24fded62020-01-14 14:48:27 -08001844 null,
Dan Willemsen4980bf42017-02-14 14:17:12 -08001845 status, pdu, smsc);
1846 }
1847 } catch (RemoteException ex) {
1848 // ignore it
1849 }
1850
1851 return success;
1852 }
1853
1854 /**
Taesu Leeade283c2019-12-03 17:29:20 +09001855 * Deletes the specified message from the ICC.
Dan Willemsen4980bf42017-02-14 14:17:12 -08001856 * ICC (Integrated Circuit Card) is the card of the device.
1857 * For example, this can be the SIM or USIM for GSM.
1858 *
Brad Ebinger360415a2019-04-30 11:37:27 -07001859 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
1860 * applications or the Telephony framework and will never trigger an SMS disambiguation
1861 * dialog. If this method is called on a device that has multiple active subscriptions, this
1862 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
1863 * default subscription is defined, the subscription ID associated with this message will be
1864 * INVALID, which will result in the operation being completed on the subscription associated
1865 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
1866 * operation is performed on the correct subscription.
1867 * </p>
1868 *
Taesu Lee24115e82020-07-17 12:18:11 +09001869 * @param messageIndex the message index of the message in the ICC (1-based index).
changbettyd5093c712019-11-21 11:07:14 +08001870 * @return true for success, false if the operation fails. Failure can be due to IPC failure,
1871 * RIL/modem error which results in SMS failed to be deleted on SIM
Dan Willemsen4980bf42017-02-14 14:17:12 -08001872 *
1873 * {@hide}
1874 */
Amit Mahajan1530a592020-10-21 12:32:59 -07001875 @UnsupportedAppUsage
changbettyd5093c712019-11-21 11:07:14 +08001876 @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC)
1877 public boolean deleteMessageFromIcc(int messageIndex) {
Dan Willemsen4980bf42017-02-14 14:17:12 -08001878 boolean success = false;
Dan Willemsen4980bf42017-02-14 14:17:12 -08001879
1880 try {
Hayden Gomes7a3d8a42019-03-21 18:30:41 -07001881 ISms iSms = getISmsService();
1882 if (iSms != null) {
1883 success = iSms.updateMessageOnIccEfForSubscriber(getSubscriptionId(),
Shuo Qian24fded62020-01-14 14:48:27 -08001884 null,
Taesu Lee265dc5b2019-07-15 12:27:08 +09001885 messageIndex, STATUS_ON_ICC_FREE, null /* pdu */);
Dan Willemsen4980bf42017-02-14 14:17:12 -08001886 }
1887 } catch (RemoteException ex) {
1888 // ignore it
1889 }
1890
1891 return success;
1892 }
1893
1894 /**
1895 * Update the specified message on the ICC.
1896 * ICC (Integrated Circuit Card) is the card of the device.
1897 * For example, this can be the SIM or USIM for GSM.
1898 *
Brad Ebinger360415a2019-04-30 11:37:27 -07001899 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
1900 * applications or the Telephony framework and will never trigger an SMS disambiguation
1901 * dialog. If this method is called on a device that has multiple active subscriptions, this
1902 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
1903 * default subscription is defined, the subscription ID associated with this message will be
1904 * INVALID, which will result in the operation being completed on the subscription associated
1905 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
1906 * operation is performed on the correct subscription.
1907 * </p>
1908 *
Dan Willemsen4980bf42017-02-14 14:17:12 -08001909 * @param messageIndex record index of message to update
1910 * @param newStatus new message status (STATUS_ON_ICC_READ,
1911 * STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
1912 * STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
1913 * @param pdu the raw PDU to store
1914 * @return true for success
1915 *
1916 * {@hide}
1917 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001918 @UnsupportedAppUsage
changbettyd5093c712019-11-21 11:07:14 +08001919 @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC)
Dan Willemsen4980bf42017-02-14 14:17:12 -08001920 public boolean updateMessageOnIcc(int messageIndex, int newStatus, byte[] pdu) {
1921 boolean success = false;
1922
1923 try {
Hayden Gomes7a3d8a42019-03-21 18:30:41 -07001924 ISms iSms = getISmsService();
1925 if (iSms != null) {
1926 success = iSms.updateMessageOnIccEfForSubscriber(getSubscriptionId(),
Shuo Qian24fded62020-01-14 14:48:27 -08001927 null,
Dan Willemsen4980bf42017-02-14 14:17:12 -08001928 messageIndex, newStatus, pdu);
1929 }
1930 } catch (RemoteException ex) {
1931 // ignore it
1932 }
1933
1934 return success;
1935 }
1936
1937 /**
Taesu Leeade283c2019-12-03 17:29:20 +09001938 * Retrieves all messages currently stored on the ICC.
Dan Willemsen4980bf42017-02-14 14:17:12 -08001939 * ICC (Integrated Circuit Card) is the card of the device.
1940 * For example, this can be the SIM or USIM for GSM.
1941 *
Brad Ebinger360415a2019-04-30 11:37:27 -07001942 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
1943 * applications or the Telephony framework and will never trigger an SMS disambiguation
1944 * dialog. If this method is called on a device that has multiple active subscriptions, this
1945 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
1946 * default subscription is defined, the subscription ID associated with this message will be
1947 * INVALID, which will result in the operation being completed on the subscription associated
1948 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
1949 * operation is performed on the correct subscription.
1950 * </p>
1951 *
Taesu Lee24115e82020-07-17 12:18:11 +09001952 * @return <code>List</code> of <code>SmsMessage</code> objects for valid records only.
changbettyd5093c712019-11-21 11:07:14 +08001953 *
1954 * {@hide}
1955 */
changbettyd5093c712019-11-21 11:07:14 +08001956 @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC)
1957 public @NonNull List<SmsMessage> getMessagesFromIcc() {
1958 return getAllMessagesFromIcc();
1959 }
1960
1961 /**
Dan Willemsen4980bf42017-02-14 14:17:12 -08001962 * @return <code>ArrayList</code> of <code>SmsMessage</code> objects
1963 *
changbettyd5093c712019-11-21 11:07:14 +08001964 * This is similar to {@link #getMessagesFromIcc} except that it will return ArrayList.
1965 * Suggested to use {@link #getMessagesFromIcc} instead.
1966 *
Dan Willemsen4980bf42017-02-14 14:17:12 -08001967 * {@hide}
1968 */
Mathew Inwooda8382062018-08-16 17:01:12 +01001969 @UnsupportedAppUsage
Dan Willemsen4980bf42017-02-14 14:17:12 -08001970 public ArrayList<SmsMessage> getAllMessagesFromIcc() {
1971 List<SmsRawData> records = null;
1972
1973 try {
Hayden Gomes7a3d8a42019-03-21 18:30:41 -07001974 ISms iSms = getISmsService();
1975 if (iSms != null) {
1976 records = iSms.getAllMessagesFromIccEfForSubscriber(
Dan Willemsen4980bf42017-02-14 14:17:12 -08001977 getSubscriptionId(),
Shuo Qian24fded62020-01-14 14:48:27 -08001978 null);
Dan Willemsen4980bf42017-02-14 14:17:12 -08001979 }
1980 } catch (RemoteException ex) {
1981 // ignore it
1982 }
1983
1984 return createMessageListFromRawRecords(records);
1985 }
1986
1987 /**
1988 * Enable reception of cell broadcast (SMS-CB) messages with the given
Jordan Liu657ef5a2019-08-16 14:07:03 -07001989 * message identifier range and RAN type. The RAN type specifies if this message ID
1990 * belongs to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients enable
Dan Willemsen4980bf42017-02-14 14:17:12 -08001991 * the same message identifier, they must both disable it for the device to stop
1992 * receiving those messages. All received messages will be broadcast in an
1993 * intent with the action "android.provider.Telephony.SMS_CB_RECEIVED".
1994 * Note: This call is blocking, callers may want to avoid calling it from
1995 * the main thread of an application.
1996 *
Brad Ebinger360415a2019-04-30 11:37:27 -07001997 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
1998 * applications or the Telephony framework and will never trigger an SMS disambiguation
1999 * dialog. If this method is called on a device that has multiple active subscriptions, this
2000 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
2001 * default subscription is defined, the subscription ID associated with this message will be
Jordan Liu657ef5a2019-08-16 14:07:03 -07002002 * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}, which will result in the operation
2003 * being completed on the subscription associated with logical slot 0. Use
2004 * {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation is performed on the
2005 * correct subscription.
Brad Ebinger360415a2019-04-30 11:37:27 -07002006 * </p>
2007 *
Jordan Liu657ef5a2019-08-16 14:07:03 -07002008 * <p>Requires {@link android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST}</p>
2009 *
Dan Willemsen4980bf42017-02-14 14:17:12 -08002010 * @param startMessageId first message identifier as specified in TS 23.041 (3GPP)
2011 * or C.R1001-G (3GPP2)
2012 * @param endMessageId last message identifier as specified in TS 23.041 (3GPP)
2013 * or C.R1001-G (3GPP2)
Jordan Liu657ef5a2019-08-16 14:07:03 -07002014 * @param ranType the message format as defined in {@link SmsCbMessage}
2015 * @return true if successful, false if the modem reports a failure (e.g. the given range or
2016 * RAN type is invalid).
Dan Willemsen4980bf42017-02-14 14:17:12 -08002017 * @see #disableCellBroadcastRange(int, int, int)
2018 *
2019 * @throws IllegalArgumentException if endMessageId < startMessageId
Hui Wang1ebbd4c2023-01-03 23:10:45 +00002020 * @deprecated Use {@link TelephonyManager#setCellBroadcastIdRanges} instead.
Dan Willemsen4980bf42017-02-14 14:17:12 -08002021 * {@hide}
2022 */
Hui Wang473ed522022-12-05 14:58:27 -06002023 @Deprecated
Jordan Liu657ef5a2019-08-16 14:07:03 -07002024 @SystemApi
2025 public boolean enableCellBroadcastRange(int startMessageId, int endMessageId,
2026 @android.telephony.SmsCbMessage.MessageFormat int ranType) {
Dan Willemsen4980bf42017-02-14 14:17:12 -08002027 boolean success = false;
Dan Willemsen4980bf42017-02-14 14:17:12 -08002028 if (endMessageId < startMessageId) {
2029 throw new IllegalArgumentException("endMessageId < startMessageId");
2030 }
2031 try {
Hayden Gomes7a3d8a42019-03-21 18:30:41 -07002032 ISms iSms = getISmsService();
2033 if (iSms != null) {
Brad Ebingerfa82ddd2019-04-30 11:34:14 -07002034 // If getSubscriptionId() returns INVALID or an inactive subscription, we will use
2035 // the default phone internally.
Nazanindf808782020-08-11 15:42:54 -07002036 int subId = getSubscriptionId();
2037 success = iSms.enableCellBroadcastRangeForSubscriber(subId,
Dan Willemsen4980bf42017-02-14 14:17:12 -08002038 startMessageId, endMessageId, ranType);
Nazanindf808782020-08-11 15:42:54 -07002039 Rlog.d(TAG, "enableCellBroadcastRange: " + (success ? "succeeded" : "failed")
2040 + " at calling enableCellBroadcastRangeForSubscriber. subId = " + subId);
Dan Willemsen4980bf42017-02-14 14:17:12 -08002041 }
2042 } catch (RemoteException ex) {
Cole Faust584140c2022-08-15 15:03:05 -07002043 Rlog.d(TAG, "enableCellBroadcastRange: ", ex);
Dan Willemsen4980bf42017-02-14 14:17:12 -08002044 // ignore it
2045 }
2046
2047 return success;
2048 }
2049
2050 /**
2051 * Disable reception of cell broadcast (SMS-CB) messages with the given
2052 * message identifier range and RAN type. The RAN type specify this message
2053 * ID range belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different
2054 * clients enable the same message identifier, they must both disable it for
2055 * the device to stop receiving those messages.
2056 * Note: This call is blocking, callers may want to avoid calling it from
2057 * the main thread of an application.
2058 *
Brad Ebinger360415a2019-04-30 11:37:27 -07002059 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
2060 * applications or the Telephony framework and will never trigger an SMS disambiguation
2061 * dialog. If this method is called on a device that has multiple active subscriptions, this
2062 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
2063 * default subscription is defined, the subscription ID associated with this message will be
2064 * INVALID, which will result in the operation being completed on the subscription associated
2065 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
2066 * operation is performed on the correct subscription.
2067 * </p>
2068 *
Jordan Liu657ef5a2019-08-16 14:07:03 -07002069 * <p>Requires {@link android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST}</p>
2070 *
Dan Willemsen4980bf42017-02-14 14:17:12 -08002071 * @param startMessageId first message identifier as specified in TS 23.041 (3GPP)
2072 * or C.R1001-G (3GPP2)
2073 * @param endMessageId last message identifier as specified in TS 23.041 (3GPP)
2074 * or C.R1001-G (3GPP2)
Jordan Liu657ef5a2019-08-16 14:07:03 -07002075 * @param ranType the message format as defined in {@link SmsCbMessage}
2076 * @return true if successful, false if the modem reports a failure (e.g. the given range or
2077 * RAN type is invalid).
Dan Willemsen4980bf42017-02-14 14:17:12 -08002078 *
2079 * @see #enableCellBroadcastRange(int, int, int)
2080 *
2081 * @throws IllegalArgumentException if endMessageId < startMessageId
Hui Wang1ebbd4c2023-01-03 23:10:45 +00002082 * @deprecated Use {@link TelephonyManager#setCellBroadcastIdRanges} instead.
Dan Willemsen4980bf42017-02-14 14:17:12 -08002083 * {@hide}
2084 */
Hui Wang473ed522022-12-05 14:58:27 -06002085 @Deprecated
Jordan Liu657ef5a2019-08-16 14:07:03 -07002086 @SystemApi
2087 public boolean disableCellBroadcastRange(int startMessageId, int endMessageId,
2088 @android.telephony.SmsCbMessage.MessageFormat int ranType) {
Dan Willemsen4980bf42017-02-14 14:17:12 -08002089 boolean success = false;
2090
2091 if (endMessageId < startMessageId) {
2092 throw new IllegalArgumentException("endMessageId < startMessageId");
2093 }
2094 try {
Hayden Gomes7a3d8a42019-03-21 18:30:41 -07002095 ISms iSms = getISmsService();
2096 if (iSms != null) {
Brad Ebingerfa82ddd2019-04-30 11:34:14 -07002097 // If getSubscriptionId() returns INVALID or an inactive subscription, we will use
2098 // the default phone internally.
Nazanindf808782020-08-11 15:42:54 -07002099 int subId = getSubscriptionId();
2100 success = iSms.disableCellBroadcastRangeForSubscriber(subId,
Dan Willemsen4980bf42017-02-14 14:17:12 -08002101 startMessageId, endMessageId, ranType);
Nazanindf808782020-08-11 15:42:54 -07002102 Rlog.d(TAG, "disableCellBroadcastRange: " + (success ? "succeeded" : "failed")
2103 + " at calling disableCellBroadcastRangeForSubscriber. subId = " + subId);
Dan Willemsen4980bf42017-02-14 14:17:12 -08002104 }
2105 } catch (RemoteException ex) {
Cole Faust584140c2022-08-15 15:03:05 -07002106 Rlog.d(TAG, "disableCellBroadcastRange: ", ex);
Dan Willemsen4980bf42017-02-14 14:17:12 -08002107 // ignore it
2108 }
2109
2110 return success;
2111 }
2112
2113 /**
Taesu Leeade283c2019-12-03 17:29:20 +09002114 * Creates a list of <code>SmsMessage</code>s from a list of SmsRawData records.
Dan Willemsen4980bf42017-02-14 14:17:12 -08002115 *
Brad Ebinger360415a2019-04-30 11:37:27 -07002116 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
2117 * applications or the Telephony framework and will never trigger an SMS disambiguation
2118 * dialog. If this method is called on a device that has multiple active subscriptions, this
2119 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
2120 * default subscription is defined, the subscription ID associated with this message will be
2121 * INVALID, which will result in the operation being completed on the subscription associated
2122 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
2123 * operation is performed on the correct subscription.
2124 * </p>
2125 *
Taesu Leeade283c2019-12-03 17:29:20 +09002126 * @param records SMS EF records.
Dan Willemsen4980bf42017-02-14 14:17:12 -08002127 * @return <code>ArrayList</code> of <code>SmsMessage</code> objects.
2128 */
Mengjun Lengb379ce92017-03-13 17:08:26 +08002129 private ArrayList<SmsMessage> createMessageListFromRawRecords(List<SmsRawData> records) {
Dan Willemsen4980bf42017-02-14 14:17:12 -08002130 ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>();
2131 if (records != null) {
2132 int count = records.size();
2133 for (int i = 0; i < count; i++) {
2134 SmsRawData data = records.get(i);
2135 // List contains all records, including "free" records (null)
2136 if (data != null) {
Taesu Leeade283c2019-12-03 17:29:20 +09002137 SmsMessage sms = SmsMessage.createFromEfRecord(i + 1, data.getBytes(),
Mengjun Lengb379ce92017-03-13 17:08:26 +08002138 getSubscriptionId());
Dan Willemsen4980bf42017-02-14 14:17:12 -08002139 if (sms != null) {
2140 messages.add(sms);
2141 }
2142 }
2143 }
2144 }
2145 return messages;
2146 }
2147
2148 /**
2149 * SMS over IMS is supported if IMS is registered and SMS is supported
2150 * on IMS.
2151 *
Brad Ebinger360415a2019-04-30 11:37:27 -07002152 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
2153 * applications or the Telephony framework and will never trigger an SMS disambiguation
2154 * dialog. If this method is called on a device that has multiple active subscriptions, this
2155 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
2156 * default subscription is defined, the subscription ID associated with this message will be
2157 * INVALID, which will result in the operation being completed on the subscription associated
2158 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
2159 * operation is performed on the correct subscription.
2160 * </p>
2161 *
Dan Willemsen4980bf42017-02-14 14:17:12 -08002162 * @return true if SMS over IMS is supported, false otherwise
2163 *
2164 * @see #getImsSmsFormat()
2165 *
2166 * @hide
2167 */
2168 public boolean isImsSmsSupported() {
2169 boolean boSupported = false;
2170 try {
Hayden Gomes7a3d8a42019-03-21 18:30:41 -07002171 ISms iSms = getISmsService();
2172 if (iSms != null) {
2173 boSupported = iSms.isImsSmsSupportedForSubscriber(getSubscriptionId());
Dan Willemsen4980bf42017-02-14 14:17:12 -08002174 }
2175 } catch (RemoteException ex) {
2176 // ignore it
2177 }
2178 return boSupported;
2179 }
2180
2181 /**
Brad Ebinger360415a2019-04-30 11:37:27 -07002182 * Gets SMS format supported on IMS. SMS over IMS format is either 3GPP or 3GPP2.
2183 *
2184 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
2185 * applications or the Telephony framework and will never trigger an SMS disambiguation
2186 * dialog. If this method is called on a device that has multiple active subscriptions, this
2187 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
2188 * default subscription is defined, the subscription ID associated with this message will be
2189 * INVALID, which will result in the operation being completed on the subscription associated
2190 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
2191 * operation is performed on the correct subscription.
2192 * </p>
Dan Willemsen4980bf42017-02-14 14:17:12 -08002193 *
2194 * @return SmsMessage.FORMAT_3GPP,
2195 * SmsMessage.FORMAT_3GPP2
2196 * or SmsMessage.FORMAT_UNKNOWN
2197 *
2198 * @see #isImsSmsSupported()
2199 *
2200 * @hide
2201 */
2202 public String getImsSmsFormat() {
2203 String format = com.android.internal.telephony.SmsConstants.FORMAT_UNKNOWN;
2204 try {
Hayden Gomes7a3d8a42019-03-21 18:30:41 -07002205 ISms iSms = getISmsService();
2206 if (iSms != null) {
2207 format = iSms.getImsSmsFormatForSubscriber(getSubscriptionId());
Dan Willemsen4980bf42017-02-14 14:17:12 -08002208 }
2209 } catch (RemoteException ex) {
2210 // ignore it
2211 }
2212 return format;
2213 }
2214
2215 /**
Amit Mahajan1c0a7a12019-05-17 10:48:00 -07002216 * Get default sms subscription id.
Dan Willemsen4980bf42017-02-14 14:17:12 -08002217 *
Amit Mahajan1c0a7a12019-05-17 10:48:00 -07002218 * <p class="note"><strong>Note:</strong>This returns a value different from
2219 * {@link SubscriptionManager#getDefaultSmsSubscriptionId} if the user has not chosen a default.
2220 * In this case it returns the active subscription id if there's only one active subscription
2221 * available.
2222 *
2223 * @return the user-defined default SMS subscription id, or the active subscription id if
2224 * there's only one active subscription available, otherwise
2225 * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
Dan Willemsen4980bf42017-02-14 14:17:12 -08002226 */
2227 public static int getDefaultSmsSubscriptionId() {
Dan Willemsen4980bf42017-02-14 14:17:12 -08002228 try {
Amit Mahajan900aad92019-06-07 10:40:09 -07002229 return getISmsService().getPreferredSmsSubscription();
Amit Mahajan1c0a7a12019-05-17 10:48:00 -07002230 } catch (RemoteException e) {
2231 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Amit Mahajan900aad92019-06-07 10:40:09 -07002232 } catch (NullPointerException e) {
2233 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Dan Willemsen4980bf42017-02-14 14:17:12 -08002234 }
2235 }
2236
2237 /**
2238 * Get SMS prompt property, enabled or not
2239 *
2240 * @return true if enabled, false otherwise
2241 * @hide
2242 */
Mathew Inwooda8382062018-08-16 17:01:12 +01002243 @UnsupportedAppUsage
Dan Willemsen4980bf42017-02-14 14:17:12 -08002244 public boolean isSMSPromptEnabled() {
Hayden Gomes7a3d8a42019-03-21 18:30:41 -07002245 ISms iSms = null;
Dan Willemsen4980bf42017-02-14 14:17:12 -08002246 try {
Tim Murrayc73a2812019-10-22 11:39:05 -07002247 iSms = TelephonyManager.getSmsService();
Hayden Gomes7a3d8a42019-03-21 18:30:41 -07002248 return iSms.isSMSPromptEnabled();
Dan Willemsen4980bf42017-02-14 14:17:12 -08002249 } catch (RemoteException ex) {
2250 return false;
2251 } catch (NullPointerException ex) {
2252 return false;
2253 }
2254 }
2255
Mengjun Lengdb152712019-11-21 10:38:03 +08002256 /**
Taesu Leed2ed15e2020-04-24 15:11:08 +09002257 * Gets the total capacity of SMS storage on the SIM card.
Mengjun Lengdb152712019-11-21 10:38:03 +08002258 *
Taesu Leed2ed15e2020-04-24 15:11:08 +09002259 * <p>
2260 * This is the number of 176 byte EF-SMS records which can be stored on the SIM card.
2261 * See 3GPP TS 31.102 - 4.2.25 - EF-SMS for more information.
2262 * </p>
2263 *
2264 * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
2265 * dialog. If this method is called on a device that has multiple active subscriptions, this
2266 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
2267 * default subscription is defined, the subscription ID associated with this method will be
2268 * INVALID, which will result in the operation being completed on the subscription associated
2269 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation
2270 * is performed on the correct subscription.
2271 * </p>
2272 *
2273 * @return the total number of SMS records which can be stored on the SIM card.
Mengjun Lengdb152712019-11-21 10:38:03 +08002274 */
Amit Mahajand6653312021-03-16 16:01:46 -07002275 @RequiresPermission(anyOf = {android.Manifest.permission.READ_PHONE_STATE,
2276 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE})
2277 @IntRange(from = 0)
Mengjun Lengdb152712019-11-21 10:38:03 +08002278 public int getSmsCapacityOnIcc() {
2279 int ret = 0;
2280 try {
2281 ISms iccISms = getISmsService();
2282 if (iccISms != null) {
2283 ret = iccISms.getSmsCapacityOnIccForSubscriber(getSubscriptionId());
2284 }
2285 } catch (RemoteException ex) {
Amit Mahajanc2f06b02021-03-17 15:35:37 -07002286 Log.e(TAG, "getSmsCapacityOnIcc() RemoteException", ex);
Mengjun Lengdb152712019-11-21 10:38:03 +08002287 }
2288 return ret;
2289 }
2290
Taesu Lee27e67c22019-12-11 10:10:49 +09002291 /** @hide */
2292 @IntDef(prefix = { "STATUS_ON_ICC_" }, value = {
2293 STATUS_ON_ICC_FREE,
2294 STATUS_ON_ICC_READ,
2295 STATUS_ON_ICC_UNREAD,
2296 STATUS_ON_ICC_SENT,
2297 STATUS_ON_ICC_UNSENT
2298 })
2299 @Retention(RetentionPolicy.SOURCE)
2300 public @interface StatusOnIcc {}
2301
Dan Willemsen4980bf42017-02-14 14:17:12 -08002302 // see SmsMessage.getStatusOnIcc
2303
2304 /** Free space (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002305 public static final int STATUS_ON_ICC_FREE = 0;
Dan Willemsen4980bf42017-02-14 14:17:12 -08002306
2307 /** Received and read (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002308 public static final int STATUS_ON_ICC_READ = 1;
Dan Willemsen4980bf42017-02-14 14:17:12 -08002309
2310 /** Received and unread (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002311 public static final int STATUS_ON_ICC_UNREAD = 3;
Dan Willemsen4980bf42017-02-14 14:17:12 -08002312
2313 /** Stored and sent (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002314 public static final int STATUS_ON_ICC_SENT = 5;
Dan Willemsen4980bf42017-02-14 14:17:12 -08002315
2316 /** Stored and unsent (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002317 public static final int STATUS_ON_ICC_UNSENT = 7;
Dan Willemsen4980bf42017-02-14 14:17:12 -08002318
2319 // SMS send failure result codes
2320
Brad Ebinger50c7b1b2019-09-24 18:11:02 -07002321 /** @hide */
2322 @IntDef(prefix = { "RESULT" }, value = {
2323 RESULT_ERROR_NONE,
2324 RESULT_ERROR_GENERIC_FAILURE,
2325 RESULT_ERROR_RADIO_OFF,
2326 RESULT_ERROR_NULL_PDU,
2327 RESULT_ERROR_NO_SERVICE,
2328 RESULT_ERROR_LIMIT_EXCEEDED,
2329 RESULT_ERROR_FDN_CHECK_FAILURE,
2330 RESULT_ERROR_SHORT_CODE_NOT_ALLOWED,
2331 RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED,
2332 RESULT_RADIO_NOT_AVAILABLE,
2333 RESULT_NETWORK_REJECT,
2334 RESULT_INVALID_ARGUMENTS,
2335 RESULT_INVALID_STATE,
2336 RESULT_NO_MEMORY,
2337 RESULT_INVALID_SMS_FORMAT,
2338 RESULT_SYSTEM_ERROR,
2339 RESULT_MODEM_ERROR,
2340 RESULT_NETWORK_ERROR,
2341 RESULT_INVALID_SMSC_ADDRESS,
2342 RESULT_OPERATION_NOT_ALLOWED,
2343 RESULT_INTERNAL_ERROR,
2344 RESULT_NO_RESOURCES,
2345 RESULT_CANCELLED,
Tom Taylorccc1c3e2019-10-30 10:08:50 -07002346 RESULT_REQUEST_NOT_SUPPORTED,
2347 RESULT_NO_BLUETOOTH_SERVICE,
2348 RESULT_INVALID_BLUETOOTH_ADDRESS,
2349 RESULT_BLUETOOTH_DISCONNECTED,
2350 RESULT_UNEXPECTED_EVENT_STOP_SENDING,
2351 RESULT_SMS_BLOCKED_DURING_EMERGENCY,
2352 RESULT_SMS_SEND_RETRY_FAILED,
2353 RESULT_REMOTE_EXCEPTION,
2354 RESULT_NO_DEFAULT_SMS_APP,
Aishwarya Mallampati425e7092022-12-02 18:55:07 +00002355 RESULT_USER_NOT_ALLOWED,
Tom Taylorccc1c3e2019-10-30 10:08:50 -07002356 RESULT_RIL_RADIO_NOT_AVAILABLE,
2357 RESULT_RIL_SMS_SEND_FAIL_RETRY,
2358 RESULT_RIL_NETWORK_REJECT,
2359 RESULT_RIL_INVALID_STATE,
2360 RESULT_RIL_INVALID_ARGUMENTS,
2361 RESULT_RIL_NO_MEMORY,
2362 RESULT_RIL_REQUEST_RATE_LIMITED,
2363 RESULT_RIL_INVALID_SMS_FORMAT,
2364 RESULT_RIL_SYSTEM_ERR,
2365 RESULT_RIL_ENCODING_ERR,
2366 RESULT_RIL_INVALID_SMSC_ADDRESS,
2367 RESULT_RIL_MODEM_ERR,
2368 RESULT_RIL_NETWORK_ERR,
2369 RESULT_RIL_INTERNAL_ERR,
2370 RESULT_RIL_REQUEST_NOT_SUPPORTED,
2371 RESULT_RIL_INVALID_MODEM_STATE,
2372 RESULT_RIL_NETWORK_NOT_READY,
2373 RESULT_RIL_OPERATION_NOT_ALLOWED,
2374 RESULT_RIL_NO_RESOURCES,
2375 RESULT_RIL_CANCELLED,
allenwtsua2c5de52020-11-18 13:49:58 +08002376 RESULT_RIL_SIM_ABSENT,
2377 RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED,
2378 RESULT_RIL_ACCESS_BARRED,
Thomas Nguyenefb9f492022-10-20 04:44:34 +00002379 RESULT_RIL_BLOCKED_DUE_TO_CALL,
2380 RESULT_RIL_GENERIC_ERROR,
2381 RESULT_RIL_INVALID_RESPONSE,
2382 RESULT_RIL_SIM_PIN2,
2383 RESULT_RIL_SIM_PUK2,
2384 RESULT_RIL_SUBSCRIPTION_NOT_AVAILABLE,
2385 RESULT_RIL_SIM_ERROR,
2386 RESULT_RIL_INVALID_SIM_STATE,
2387 RESULT_RIL_NO_SMS_TO_ACK,
2388 RESULT_RIL_SIM_BUSY,
2389 RESULT_RIL_SIM_FULL,
2390 RESULT_RIL_NO_SUBSCRIPTION,
2391 RESULT_RIL_NO_NETWORK_FOUND,
2392 RESULT_RIL_DEVICE_IN_USE,
2393 RESULT_RIL_ABORTED
Brad Ebinger50c7b1b2019-09-24 18:11:02 -07002394 })
2395 @Retention(RetentionPolicy.SOURCE)
2396 public @interface Result {}
2397
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002398 /**
2399 * No error.
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002400 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002401 public static final int RESULT_ERROR_NONE = 0;
2402
Dan Willemsen4980bf42017-02-14 14:17:12 -08002403 /** Generic failure cause */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002404 public static final int RESULT_ERROR_GENERIC_FAILURE = 1;
2405
Dan Willemsen4980bf42017-02-14 14:17:12 -08002406 /** Failed because radio was explicitly turned off */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002407 public static final int RESULT_ERROR_RADIO_OFF = 2;
2408
Dan Willemsen4980bf42017-02-14 14:17:12 -08002409 /** Failed because no pdu provided */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002410 public static final int RESULT_ERROR_NULL_PDU = 3;
2411
Dan Willemsen4980bf42017-02-14 14:17:12 -08002412 /** Failed because service is currently unavailable */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002413 public static final int RESULT_ERROR_NO_SERVICE = 4;
2414
sqian724f6212017-08-09 15:28:41 -07002415 /** Failed because we reached the sending queue limit. */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002416 public static final int RESULT_ERROR_LIMIT_EXCEEDED = 5;
2417
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002418 /**
2419 * Failed because FDN is enabled.
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002420 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002421 public static final int RESULT_ERROR_FDN_CHECK_FAILURE = 6;
2422
sqian724f6212017-08-09 15:28:41 -07002423 /** Failed because user denied the sending of this short code. */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002424 public static final int RESULT_ERROR_SHORT_CODE_NOT_ALLOWED = 7;
2425
sqian724f6212017-08-09 15:28:41 -07002426 /** Failed because the user has denied this app ever send premium short codes. */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002427 public static final int RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED = 8;
2428
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002429 /**
2430 * Failed because the radio was not available
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002431 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002432 public static final int RESULT_RADIO_NOT_AVAILABLE = 9;
2433
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002434 /**
2435 * Failed because of network rejection
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002436 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002437 public static final int RESULT_NETWORK_REJECT = 10;
2438
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002439 /**
2440 * Failed because of invalid arguments
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002441 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002442 public static final int RESULT_INVALID_ARGUMENTS = 11;
2443
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002444 /**
2445 * Failed because of an invalid state
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002446 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002447 public static final int RESULT_INVALID_STATE = 12;
2448
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002449 /**
2450 * Failed because there is no memory
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002451 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002452 public static final int RESULT_NO_MEMORY = 13;
2453
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002454 /**
2455 * Failed because the sms format is not valid
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002456 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002457 public static final int RESULT_INVALID_SMS_FORMAT = 14;
2458
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002459 /**
2460 * Failed because of a system error
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002461 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002462 public static final int RESULT_SYSTEM_ERROR = 15;
2463
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002464 /**
2465 * Failed because of a modem error
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002466 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002467 public static final int RESULT_MODEM_ERROR = 16;
2468
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002469 /**
2470 * Failed because of a network error
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002471 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002472 public static final int RESULT_NETWORK_ERROR = 17;
2473
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002474 /**
2475 * Failed because of an encoding error
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002476 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002477 public static final int RESULT_ENCODING_ERROR = 18;
2478
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002479 /**
2480 * Failed because of an invalid smsc address
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002481 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002482 public static final int RESULT_INVALID_SMSC_ADDRESS = 19;
2483
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002484 /**
2485 * Failed because the operation is not allowed
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002486 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002487 public static final int RESULT_OPERATION_NOT_ALLOWED = 20;
2488
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002489 /**
2490 * Failed because of an internal error
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002491 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002492 public static final int RESULT_INTERNAL_ERROR = 21;
2493
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002494 /**
2495 * Failed because there are no resources
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002496 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002497 public static final int RESULT_NO_RESOURCES = 22;
2498
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002499 /**
2500 * Failed because the operation was cancelled
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002501 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002502 public static final int RESULT_CANCELLED = 23;
2503
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002504 /**
2505 * Failed because the request is not supported
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002506 */
Tom Taylorf43f4f02019-10-08 16:34:04 -07002507 public static final int RESULT_REQUEST_NOT_SUPPORTED = 24;
2508
2509 /**
2510 * Failed sending via bluetooth because the bluetooth service is not available
2511 */
2512 public static final int RESULT_NO_BLUETOOTH_SERVICE = 25;
2513
2514 /**
2515 * Failed sending via bluetooth because the bluetooth device address is invalid
2516 */
2517 public static final int RESULT_INVALID_BLUETOOTH_ADDRESS = 26;
2518
2519 /**
2520 * Failed sending via bluetooth because bluetooth disconnected
2521 */
2522 public static final int RESULT_BLUETOOTH_DISCONNECTED = 27;
2523
2524 /**
2525 * Failed sending because the user denied or canceled the dialog displayed for a premium
2526 * shortcode sms or rate-limited sms.
2527 */
2528 public static final int RESULT_UNEXPECTED_EVENT_STOP_SENDING = 28;
2529
2530 /**
2531 * Failed sending during an emergency call
2532 */
2533 public static final int RESULT_SMS_BLOCKED_DURING_EMERGENCY = 29;
2534
2535 /**
2536 * Failed to send an sms retry
2537 */
2538 public static final int RESULT_SMS_SEND_RETRY_FAILED = 30;
2539
2540 /**
2541 * Set by BroadcastReceiver to indicate a remote exception while handling a message.
2542 */
2543 public static final int RESULT_REMOTE_EXCEPTION = 31;
2544
2545 /**
2546 * Set by BroadcastReceiver to indicate there's no default sms app.
2547 */
2548 public static final int RESULT_NO_DEFAULT_SMS_APP = 32;
2549
Aishwarya Mallampati425e7092022-12-02 18:55:07 +00002550 /**
2551 * User is not associated with the subscription.
Aishwarya Mallampati425e7092022-12-02 18:55:07 +00002552 */
2553 public static final int RESULT_USER_NOT_ALLOWED = 33;
2554
Tom Taylorf43f4f02019-10-08 16:34:04 -07002555 // Radio Error results
2556
2557 /**
2558 * The radio did not start or is resetting.
2559 */
2560 public static final int RESULT_RIL_RADIO_NOT_AVAILABLE = 100;
2561
2562 /**
2563 * The radio failed to send the sms and needs to retry.
2564 */
2565 public static final int RESULT_RIL_SMS_SEND_FAIL_RETRY = 101;
2566
2567 /**
2568 * The sms request was rejected by the network.
2569 */
2570 public static final int RESULT_RIL_NETWORK_REJECT = 102;
2571
2572 /**
2573 * The radio returned an unexpected request for the current state.
2574 */
2575 public static final int RESULT_RIL_INVALID_STATE = 103;
2576
2577 /**
2578 * The radio received invalid arguments in the request.
2579 */
2580 public static final int RESULT_RIL_INVALID_ARGUMENTS = 104;
2581
2582 /**
2583 * The radio didn't have sufficient memory to process the request.
2584 */
2585 public static final int RESULT_RIL_NO_MEMORY = 105;
2586
2587 /**
2588 * The radio denied the operation due to overly-frequent requests.
2589 */
2590 public static final int RESULT_RIL_REQUEST_RATE_LIMITED = 106;
2591
2592 /**
2593 * The radio returned an error indicating invalid sms format.
2594 */
2595 public static final int RESULT_RIL_INVALID_SMS_FORMAT = 107;
2596
2597 /**
2598 * The radio encountered a platform or system error.
2599 */
2600 public static final int RESULT_RIL_SYSTEM_ERR = 108;
2601
2602 /**
2603 * The SMS message was not encoded properly.
2604 */
2605 public static final int RESULT_RIL_ENCODING_ERR = 109;
2606
2607 /**
2608 * The specified SMSC address was invalid.
2609 */
2610 public static final int RESULT_RIL_INVALID_SMSC_ADDRESS = 110;
2611
2612 /**
2613 * The vendor RIL received an unexpected or incorrect response.
2614 */
2615 public static final int RESULT_RIL_MODEM_ERR = 111;
2616
2617 /**
2618 * The radio received an error from the network.
2619 */
2620 public static final int RESULT_RIL_NETWORK_ERR = 112;
2621
2622 /**
2623 * The modem encountered an unexpected error scenario while handling the request.
2624 */
2625 public static final int RESULT_RIL_INTERNAL_ERR = 113;
2626
2627 /**
2628 * The request was not supported by the radio.
2629 */
2630 public static final int RESULT_RIL_REQUEST_NOT_SUPPORTED = 114;
2631
2632 /**
2633 * The radio cannot process the request in the current modem state.
2634 */
2635 public static final int RESULT_RIL_INVALID_MODEM_STATE = 115;
2636
2637 /**
2638 * The network is not ready to perform the request.
2639 */
2640 public static final int RESULT_RIL_NETWORK_NOT_READY = 116;
2641
2642 /**
2643 * The radio reports the request is not allowed.
2644 */
2645 public static final int RESULT_RIL_OPERATION_NOT_ALLOWED = 117;
2646
2647 /**
Tom Taylorccc1c3e2019-10-30 10:08:50 -07002648 * There are insufficient resources to process the request.
Tom Taylorf43f4f02019-10-08 16:34:04 -07002649 */
2650 public static final int RESULT_RIL_NO_RESOURCES = 118;
2651
2652 /**
2653 * The request has been cancelled.
2654 */
2655 public static final int RESULT_RIL_CANCELLED = 119;
2656
2657 /**
2658 * The radio failed to set the location where the CDMA subscription
2659 * can be retrieved because the SIM or RUIM is absent.
2660 */
2661 public static final int RESULT_RIL_SIM_ABSENT = 120;
Mohamed Abdalkader9cb476b2018-01-23 09:56:31 -08002662
allenwtsua2c5de52020-11-18 13:49:58 +08002663 /**
Thomas Nguyenefb9f492022-10-20 04:44:34 +00002664 * 1X voice and SMS are not allowed simultaneously.
allenwtsua2c5de52020-11-18 13:49:58 +08002665 */
2666 public static final int RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED = 121;
2667
2668 /**
2669 * Access is barred.
2670 */
2671 public static final int RESULT_RIL_ACCESS_BARRED = 122;
2672
2673 /**
2674 * SMS is blocked due to call control, e.g., resource unavailable in the SMR entity.
2675 */
2676 public static final int RESULT_RIL_BLOCKED_DUE_TO_CALL = 123;
2677
Tom Taylor74f75dc2021-11-08 15:01:37 -08002678 /**
2679 * A RIL error occurred during the SMS send.
2680 */
2681 public static final int RESULT_RIL_GENERIC_ERROR = 124;
2682
Thomas Nguyenefb9f492022-10-20 04:44:34 +00002683 /**
2684 * A RIL internal error when one of the RIL layers receives an unrecognized response from a
2685 * lower layer.
2686 */
2687 public static final int RESULT_RIL_INVALID_RESPONSE = 125;
2688
2689 /**
2690 * Operation requires SIM PIN2 to be entered
2691 */
2692 public static final int RESULT_RIL_SIM_PIN2 = 126;
2693
2694 /**
2695 * Operation requires SIM PUK2 to be entered
2696 */
2697 public static final int RESULT_RIL_SIM_PUK2 = 127;
2698
2699 /**
2700 * Fail to find CDMA subscription from specified location
2701 */
2702 public static final int RESULT_RIL_SUBSCRIPTION_NOT_AVAILABLE = 128;
2703
2704 /**
2705 * Received error from SIM card
2706 */
2707 public static final int RESULT_RIL_SIM_ERROR = 129;
2708
2709 /**
2710 * Cannot process the request in current SIM state
2711 */
2712 public static final int RESULT_RIL_INVALID_SIM_STATE = 130;
2713
2714 /**
2715 * ACK received when there is no SMS to ack
2716 */
2717 public static final int RESULT_RIL_NO_SMS_TO_ACK = 131;
2718
2719 /**
2720 * SIM is busy
2721 */
2722 public static final int RESULT_RIL_SIM_BUSY = 132;
2723
2724 /**
2725 * The target EF is full
2726 */
2727 public static final int RESULT_RIL_SIM_FULL = 133;
2728
2729 /**
2730 * Device does not have subscription
2731 */
2732 public static final int RESULT_RIL_NO_SUBSCRIPTION = 134;
2733
2734 /**
2735 * Network cannot be found
2736 */
2737 public static final int RESULT_RIL_NO_NETWORK_FOUND = 135;
2738
2739 /**
2740 * Operation cannot be performed because the device is currently in use
2741 */
2742 public static final int RESULT_RIL_DEVICE_IN_USE = 136;
2743
2744 /**
2745 * Operation aborted
2746 */
2747 public static final int RESULT_RIL_ABORTED = 137;
2748
2749
Tom Taylorccc1c3e2019-10-30 10:08:50 -07002750 // SMS receiving results sent as a "result" extra in {@link Intents.SMS_REJECTED_ACTION}
2751
2752 /**
2753 * SMS receive dispatch failure.
2754 */
2755 public static final int RESULT_RECEIVE_DISPATCH_FAILURE = 500;
2756
2757 /**
2758 * SMS receive injected null PDU.
2759 */
2760 public static final int RESULT_RECEIVE_INJECTED_NULL_PDU = 501;
2761
2762 /**
2763 * SMS receive encountered runtime exception.
2764 */
2765 public static final int RESULT_RECEIVE_RUNTIME_EXCEPTION = 502;
2766
2767 /**
2768 * SMS received null message from the radio interface layer.
2769 */
2770 public static final int RESULT_RECEIVE_NULL_MESSAGE_FROM_RIL = 503;
2771
2772 /**
2773 * SMS short code received while the phone is in encrypted state.
2774 */
2775 public static final int RESULT_RECEIVE_WHILE_ENCRYPTED = 504;
2776
2777 /**
2778 * SMS receive encountered an SQL exception.
2779 */
2780 public static final int RESULT_RECEIVE_SQL_EXCEPTION = 505;
2781
2782 /**
2783 * SMS receive an exception parsing a uri.
2784 */
2785 public static final int RESULT_RECEIVE_URI_EXCEPTION = 506;
2786
2787
2788
Dan Willemsen4980bf42017-02-14 14:17:12 -08002789 /**
2790 * Send an MMS message
2791 *
Taesu Lee16bd38d2020-10-12 16:45:55 +09002792 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
2793 * manager on a multi-SIM device, this operation may fail sending the MMS message because no
2794 * suitable default subscription could be found. In this case, if {@code sentIntent} is
2795 * non-null, then the {@link PendingIntent} will be sent with an error code
2796 * {@code RESULT_NO_DEFAULT_SMS_APP}. See {@link #getDefault()} for more information on the
2797 * conditions where this operation may fail.
Brad Ebinger360415a2019-04-30 11:37:27 -07002798 * </p>
2799 *
Dan Willemsen4980bf42017-02-14 14:17:12 -08002800 * @param context application context
2801 * @param contentUri the content Uri from which the message pdu will be read
2802 * @param locationUrl the optional location url where message should be sent to
2803 * @param configOverrides the carrier-specific messaging configuration values to override for
2804 * sending the message.
2805 * @param sentIntent if not NULL this <code>PendingIntent</code> is
2806 * broadcast when the message is successfully sent, or failed
Tom Taylor88533af2021-06-17 10:15:00 -07002807 * The result code will be <code>Activity.RESULT_OK</code> for success
2808 * or one of these errors:<br>
2809 * <code>MMS_ERROR_UNSPECIFIED</code><br>
2810 * <code>MMS_ERROR_INVALID_APN</code><br>
2811 * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br>
2812 * <code>MMS_ERROR_HTTP_FAILURE</code><br>
2813 * <code>MMS_ERROR_IO_ERROR</code><br>
2814 * <code>MMS_ERROR_RETRY</code><br>
2815 * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br>
2816 * <code>MMS_ERROR_NO_DATA_NETWORK</code><br>
2817 * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br>
2818 * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br>
2819 * <code>MMS_ERROR_DATA_DISABLED</code><br>
Thomas Nguyencf166c22023-11-01 11:02:15 -07002820 * <code>MMS_ERROR_MMS_DISABLED_BY_CARRIER</code><br>
Dan Willemsen4980bf42017-02-14 14:17:12 -08002821 * @throws IllegalArgumentException if contentUri is empty
2822 */
2823 public void sendMultimediaMessage(Context context, Uri contentUri, String locationUrl,
2824 Bundle configOverrides, PendingIntent sentIntent) {
Tom Taylor7d998812020-11-24 14:49:00 -08002825 sendMultimediaMessage(context, contentUri, locationUrl, configOverrides, sentIntent,
2826 0L /* messageId */);
2827 }
2828
2829 /**
2830 * Send an MMS message
2831 *
2832 * Same as {@link #sendMultimediaMessage(Context context, Uri contentUri, String locationUrl,
2833 * Bundle configOverrides, PendingIntent sentIntent)}, but adds an optional messageId.
2834 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
2835 * manager on a multi-SIM device, this operation may fail sending the MMS message because no
2836 * suitable default subscription could be found. In this case, if {@code sentIntent} is
2837 * non-null, then the {@link PendingIntent} will be sent with an error code
2838 * {@code RESULT_NO_DEFAULT_SMS_APP}. See {@link #getDefault()} for more information on the
2839 * conditions where this operation may fail.
2840 * </p>
2841 *
2842 * @param context application context
2843 * @param contentUri the content Uri from which the message pdu will be read
2844 * @param locationUrl the optional location url where message should be sent to
2845 * @param configOverrides the carrier-specific messaging configuration values to override for
2846 * sending the message.
2847 * @param sentIntent if not NULL this <code>PendingIntent</code> is
2848 * broadcast when the message is successfully sent, or failed
Tom Taylor88533af2021-06-17 10:15:00 -07002849 * The result code will be <code>Activity.RESULT_OK</code> for success
2850 * or one of these errors:<br>
2851 * <code>MMS_ERROR_UNSPECIFIED</code><br>
2852 * <code>MMS_ERROR_INVALID_APN</code><br>
2853 * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br>
2854 * <code>MMS_ERROR_HTTP_FAILURE</code><br>
2855 * <code>MMS_ERROR_IO_ERROR</code><br>
2856 * <code>MMS_ERROR_RETRY</code><br>
2857 * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br>
2858 * <code>MMS_ERROR_NO_DATA_NETWORK</code><br>
2859 * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br>
2860 * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br>
2861 * <code>MMS_ERROR_DATA_DISABLED</code><br>
Thomas Nguyencf166c22023-11-01 11:02:15 -07002862 * <code>MMS_ERROR_MMS_DISABLED_BY_CARRIER</code><br>
Tom Taylor7d998812020-11-24 14:49:00 -08002863 * @param messageId an id that uniquely identifies the message requested to be sent.
2864 * Used for logging and diagnostics purposes. The id may be 0.
2865 * @throws IllegalArgumentException if contentUri is empty
2866 */
2867 public void sendMultimediaMessage(@NonNull Context context, @NonNull Uri contentUri,
Adrian Roosade22d02021-02-02 16:08:09 +01002868 @Nullable String locationUrl,
2869 @SuppressWarnings("NullableCollection") @Nullable Bundle configOverrides,
Tom Taylor7d998812020-11-24 14:49:00 -08002870 @Nullable PendingIntent sentIntent, long messageId) {
Dan Willemsen4980bf42017-02-14 14:17:12 -08002871 if (contentUri == null) {
2872 throw new IllegalArgumentException("Uri contentUri null");
2873 }
Sarah Chin4affb512020-01-10 16:09:11 -08002874 MmsManager m = (MmsManager) context.getSystemService(Context.MMS_SERVICE);
2875 if (m != null) {
Taesu Lee16bd38d2020-10-12 16:45:55 +09002876 resolveSubscriptionForOperation(new SubscriptionResolverResult() {
2877 @Override
2878 public void onSuccess(int subId) {
2879 m.sendMultimediaMessage(subId, contentUri, locationUrl, configOverrides,
Tom Taylor7d998812020-11-24 14:49:00 -08002880 sentIntent, messageId);
Taesu Lee16bd38d2020-10-12 16:45:55 +09002881 }
2882
2883 @Override
2884 public void onFailure() {
2885 notifySmsError(sentIntent, RESULT_NO_DEFAULT_SMS_APP);
2886 }
2887 });
Sarah Chin4affb512020-01-10 16:09:11 -08002888 }
Dan Willemsen4980bf42017-02-14 14:17:12 -08002889 }
2890
2891 /**
2892 * Download an MMS message from carrier by a given location URL
2893 *
Taesu Lee16bd38d2020-10-12 16:45:55 +09002894 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
2895 * manager on a multi-SIM device, this operation may fail downloading the MMS message because no
2896 * suitable default subscription could be found. In this case, if {@code downloadedIntent} is
2897 * non-null, then the {@link PendingIntent} will be sent with an error code
2898 * {@code RESULT_NO_DEFAULT_SMS_APP}. See {@link #getDefault()} for more information on the
2899 * conditions where this operation may fail.
Brad Ebinger360415a2019-04-30 11:37:27 -07002900 * </p>
2901 *
Dan Willemsen4980bf42017-02-14 14:17:12 -08002902 * @param context application context
2903 * @param locationUrl the location URL of the MMS message to be downloaded, usually obtained
2904 * from the MMS WAP push notification
2905 * @param contentUri the content uri to which the downloaded pdu will be written
2906 * @param configOverrides the carrier-specific messaging configuration values to override for
2907 * downloading the message.
2908 * @param downloadedIntent if not NULL this <code>PendingIntent</code> is
2909 * broadcast when the message is downloaded, or the download is failed
Tom Taylor88533af2021-06-17 10:15:00 -07002910 * The result code will be <code>Activity.RESULT_OK</code> for success
2911 * or one of these errors:<br>
2912 * <code>MMS_ERROR_UNSPECIFIED</code><br>
2913 * <code>MMS_ERROR_INVALID_APN</code><br>
2914 * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br>
2915 * <code>MMS_ERROR_HTTP_FAILURE</code><br>
2916 * <code>MMS_ERROR_IO_ERROR</code><br>
2917 * <code>MMS_ERROR_RETRY</code><br>
2918 * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br>
2919 * <code>MMS_ERROR_NO_DATA_NETWORK</code><br>
2920 * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br>
2921 * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br>
2922 * <code>MMS_ERROR_DATA_DISABLED</code><br>
Thomas Nguyencf166c22023-11-01 11:02:15 -07002923 * <code>MMS_ERROR_MMS_DISABLED_BY_CARRIER</code><br>
Dan Willemsen4980bf42017-02-14 14:17:12 -08002924 * @throws IllegalArgumentException if locationUrl or contentUri is empty
2925 */
2926 public void downloadMultimediaMessage(Context context, String locationUrl, Uri contentUri,
2927 Bundle configOverrides, PendingIntent downloadedIntent) {
Tom Taylor7d998812020-11-24 14:49:00 -08002928 downloadMultimediaMessage(context, locationUrl, contentUri, configOverrides,
2929 downloadedIntent, 0L /* messageId */);
2930 }
2931
2932 /**
2933 * Download an MMS message from carrier by a given location URL
2934 *
2935 * Same as {@link #downloadMultimediaMessage(Context context, String locationUrl,
2936 * Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent)},
2937 * but adds an optional messageId.
2938 * <p class="note"><strong>Note:</strong> If {@link #getDefault()} is used to instantiate this
2939 * manager on a multi-SIM device, this operation may fail downloading the MMS message because no
2940 * suitable default subscription could be found. In this case, if {@code downloadedIntent} is
2941 * non-null, then the {@link PendingIntent} will be sent with an error code
2942 * {@code RESULT_NO_DEFAULT_SMS_APP}. See {@link #getDefault()} for more information on the
2943 * conditions where this operation may fail.
2944 * </p>
2945 *
2946 * @param context application context
2947 * @param locationUrl the location URL of the MMS message to be downloaded, usually obtained
2948 * from the MMS WAP push notification
2949 * @param contentUri the content uri to which the downloaded pdu will be written
2950 * @param configOverrides the carrier-specific messaging configuration values to override for
2951 * downloading the message.
2952 * @param downloadedIntent if not NULL this <code>PendingIntent</code> is
2953 * broadcast when the message is downloaded, or the download is failed
Tom Taylor88533af2021-06-17 10:15:00 -07002954 * The result code will be <code>Activity.RESULT_OK</code> for success
2955 * or one of these errors:<br>
2956 * <code>MMS_ERROR_UNSPECIFIED</code><br>
2957 * <code>MMS_ERROR_INVALID_APN</code><br>
2958 * <code>MMS_ERROR_UNABLE_CONNECT_MMS</code><br>
2959 * <code>MMS_ERROR_HTTP_FAILURE</code><br>
2960 * <code>MMS_ERROR_IO_ERROR</code><br>
2961 * <code>MMS_ERROR_RETRY</code><br>
2962 * <code>MMS_ERROR_CONFIGURATION_ERROR</code><br>
2963 * <code>MMS_ERROR_NO_DATA_NETWORK</code><br>
2964 * <code>MMS_ERROR_INVALID_SUBSCRIPTION_ID</code><br>
2965 * <code>MMS_ERROR_INACTIVE_SUBSCRIPTION</code><br>
2966 * <code>MMS_ERROR_DATA_DISABLED</code><br>
Thomas Nguyencf166c22023-11-01 11:02:15 -07002967 * <code>MMS_ERROR_MMS_DISABLED_BY_CARRIER</code><br>
Tom Taylor7d998812020-11-24 14:49:00 -08002968 * @param messageId an id that uniquely identifies the message requested to be downloaded.
2969 * Used for logging and diagnostics purposes. The id may be 0.
2970 * @throws IllegalArgumentException if locationUrl or contentUri is empty
2971 */
2972 public void downloadMultimediaMessage(@NonNull Context context, @NonNull String locationUrl,
Adrian Roosade22d02021-02-02 16:08:09 +01002973 @NonNull Uri contentUri,
2974 @SuppressWarnings("NullableCollection") @Nullable Bundle configOverrides,
Tom Taylor7d998812020-11-24 14:49:00 -08002975 @Nullable PendingIntent downloadedIntent, long messageId) {
Dan Willemsen4980bf42017-02-14 14:17:12 -08002976 if (TextUtils.isEmpty(locationUrl)) {
2977 throw new IllegalArgumentException("Empty MMS location URL");
2978 }
2979 if (contentUri == null) {
2980 throw new IllegalArgumentException("Uri contentUri null");
2981 }
Sarah Chin4affb512020-01-10 16:09:11 -08002982 MmsManager m = (MmsManager) context.getSystemService(Context.MMS_SERVICE);
2983 if (m != null) {
Taesu Lee16bd38d2020-10-12 16:45:55 +09002984 resolveSubscriptionForOperation(new SubscriptionResolverResult() {
2985 @Override
2986 public void onSuccess(int subId) {
2987 m.downloadMultimediaMessage(subId, locationUrl, contentUri, configOverrides,
Tom Taylor7d998812020-11-24 14:49:00 -08002988 downloadedIntent, messageId);
Taesu Lee16bd38d2020-10-12 16:45:55 +09002989 }
2990
2991 @Override
2992 public void onFailure() {
2993 notifySmsError(downloadedIntent, RESULT_NO_DEFAULT_SMS_APP);
2994 }
2995 });
Sarah Chin4affb512020-01-10 16:09:11 -08002996 }
Dan Willemsen4980bf42017-02-14 14:17:12 -08002997 }
2998
2999 // MMS send/download failure result codes
Tom Taylor88533af2021-06-17 10:15:00 -07003000
3001 /**
3002 * Unspecific MMS error occurred during send/download.
3003 */
Dan Willemsen4980bf42017-02-14 14:17:12 -08003004 public static final int MMS_ERROR_UNSPECIFIED = 1;
Tom Taylor88533af2021-06-17 10:15:00 -07003005
3006 /**
3007 * ApnException occurred during MMS network setup.
3008 */
Dan Willemsen4980bf42017-02-14 14:17:12 -08003009 public static final int MMS_ERROR_INVALID_APN = 2;
Tom Taylor88533af2021-06-17 10:15:00 -07003010
3011 /**
3012 * An error occurred during the MMS connection setup.
3013 */
Dan Willemsen4980bf42017-02-14 14:17:12 -08003014 public static final int MMS_ERROR_UNABLE_CONNECT_MMS = 3;
Tom Taylor88533af2021-06-17 10:15:00 -07003015
3016 /**
3017 * An error occurred during the HTTP client setup.
3018 */
Dan Willemsen4980bf42017-02-14 14:17:12 -08003019 public static final int MMS_ERROR_HTTP_FAILURE = 4;
Tom Taylor88533af2021-06-17 10:15:00 -07003020
3021 /**
3022 * An I/O error occurred reading the PDU.
3023 */
Dan Willemsen4980bf42017-02-14 14:17:12 -08003024 public static final int MMS_ERROR_IO_ERROR = 5;
Tom Taylor88533af2021-06-17 10:15:00 -07003025
3026 /**
3027 * An error occurred while retrying sending/downloading the MMS.
3028 */
Dan Willemsen4980bf42017-02-14 14:17:12 -08003029 public static final int MMS_ERROR_RETRY = 6;
Tom Taylor88533af2021-06-17 10:15:00 -07003030
3031 /**
3032 * The carrier-dependent configuration values could not be loaded.
3033 */
Dan Willemsen4980bf42017-02-14 14:17:12 -08003034 public static final int MMS_ERROR_CONFIGURATION_ERROR = 7;
Tom Taylor88533af2021-06-17 10:15:00 -07003035
3036 /**
Thomas Nguyencf166c22023-11-01 11:02:15 -07003037 * There is neither Wi-Fi nor mobile data network.
Tom Taylor88533af2021-06-17 10:15:00 -07003038 */
Dan Willemsen4980bf42017-02-14 14:17:12 -08003039 public static final int MMS_ERROR_NO_DATA_NETWORK = 8;
3040
Tom Taylor88533af2021-06-17 10:15:00 -07003041 /**
3042 * The subscription id for the send/download is invalid.
3043 */
3044 public static final int MMS_ERROR_INVALID_SUBSCRIPTION_ID = 9;
3045
3046 /**
3047 * The subscription id for the send/download is inactive.
3048 */
3049 public static final int MMS_ERROR_INACTIVE_SUBSCRIPTION = 10;
3050
3051 /**
3052 * Data is disabled for the MMS APN.
3053 */
3054 public static final int MMS_ERROR_DATA_DISABLED = 11;
3055
Thomas Nguyencf166c22023-11-01 11:02:15 -07003056 /**
3057 * MMS is disabled by a carrier.
3058 */
3059 @FlaggedApi(Flags.FLAG_MMS_DISABLED_ERROR)
3060 public static final int MMS_ERROR_MMS_DISABLED_BY_CARRIER = 12;
3061
Dan Willemsen4980bf42017-02-14 14:17:12 -08003062 /** Intent extra name for MMS sending result data in byte array type */
3063 public static final String EXTRA_MMS_DATA = "android.telephony.extra.MMS_DATA";
3064 /** Intent extra name for HTTP status code for MMS HTTP failure in integer type */
3065 public static final String EXTRA_MMS_HTTP_STATUS = "android.telephony.extra.MMS_HTTP_STATUS";
3066
Dan Willemsen4980bf42017-02-14 14:17:12 -08003067 /**
Taesu Lee44fb1902019-11-15 16:16:08 +09003068 * Get carrier-dependent MMS configuration values.
Dan Willemsen4980bf42017-02-14 14:17:12 -08003069 *
Brad Ebinger360415a2019-04-30 11:37:27 -07003070 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
Taesu Lee44fb1902019-11-15 16:16:08 +09003071 * applications or the Telephony framework and will never trigger an SMS disambiguation dialog.
3072 * If this method is called on a device that has multiple active subscriptions, this {@link
3073 * SmsManager} instance has been created with {@link #getDefault()}, and no user-defined default
3074 * subscription is defined, the subscription ID associated with this message will be INVALID,
3075 * which will result in the operation being completed on the subscription associated with
3076 * logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation is
3077 * performed on the correct subscription.
Brad Ebinger360415a2019-04-30 11:37:27 -07003078 * </p>
3079 *
Taesu Lee44fb1902019-11-15 16:16:08 +09003080 * @return the bundle key/values pairs that contains MMS configuration values
Sarah Chin4affb512020-01-10 16:09:11 -08003081 * or an empty Bundle if they cannot be found.
Dan Willemsen4980bf42017-02-14 14:17:12 -08003082 */
Sarah Chin4affb512020-01-10 16:09:11 -08003083 @NonNull public Bundle getCarrierConfigValues() {
Taesu Lee44fb1902019-11-15 16:16:08 +09003084 try {
3085 ISms iSms = getISmsService();
3086 if (iSms != null) {
3087 return iSms.getCarrierConfigValuesForSubscriber(getSubscriptionId());
3088 }
3089 } catch (RemoteException ex) {
3090 // ignore it
3091 }
Sarah Chin4affb512020-01-10 16:09:11 -08003092 return new Bundle();
Dan Willemsen4980bf42017-02-14 14:17:12 -08003093 }
3094
3095 /**
Brad Ebinger360415a2019-04-30 11:37:27 -07003096 * Create a single use app specific incoming SMS request for the calling package.
Dan Willemsen4980bf42017-02-14 14:17:12 -08003097 *
3098 * This method returns a token that if included in a subsequent incoming SMS message will cause
3099 * {@code intent} to be sent with the SMS data.
3100 *
3101 * The token is only good for one use, after an SMS has been received containing the token all
3102 * subsequent SMS messages with the token will be routed as normal.
3103 *
3104 * An app can only have one request at a time, if the app already has a request pending it will
3105 * be replaced with a new request.
3106 *
Brad Ebinger360415a2019-04-30 11:37:27 -07003107 * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
3108 * dialog. If this method is called on a device that has multiple active subscriptions, this
3109 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
3110 * default subscription is defined, the subscription ID associated with this message will be
3111 * INVALID, which will result in the operation being completed on the subscription associated
3112 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
3113 * operation is performed on the correct subscription.
3114 * </p>
3115 *
Dan Willemsen4980bf42017-02-14 14:17:12 -08003116 * @return Token to include in an SMS message. The token will be 11 characters long.
3117 * @see android.provider.Telephony.Sms.Intents#getMessagesFromIntent
3118 */
3119 public String createAppSpecificSmsToken(PendingIntent intent) {
3120 try {
3121 ISms iccSms = getISmsServiceOrThrow();
3122 return iccSms.createAppSpecificSmsToken(getSubscriptionId(),
Shuo Qian24fded62020-01-14 14:48:27 -08003123 null, intent);
Dan Willemsen4980bf42017-02-14 14:17:12 -08003124
3125 } catch (RemoteException ex) {
3126 ex.rethrowFromSystemServer();
3127 return null;
3128 }
3129 }
3130
Chen Xud6b26732019-09-29 19:55:06 -07003131 /**
3132 * callback for providing asynchronous sms messages for financial app.
3133 */
Hongming Jin08496b02019-01-25 13:41:52 -08003134 public abstract static class FinancialSmsCallback {
3135 /**
3136 * Callback to send sms messages back to financial app asynchronously.
3137 *
3138 * @param msgs SMS messages.
3139 */
3140 public abstract void onFinancialSmsMessages(CursorWindow msgs);
3141 };
3142
3143 /**
3144 * Get SMS messages for the calling financial app.
3145 * The result will be delivered asynchronously in the passing in callback interface.
3146 *
Brad Ebinger360415a2019-04-30 11:37:27 -07003147 * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
3148 * dialog. If this method is called on a device that has multiple active subscriptions, this
3149 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
3150 * default subscription is defined, the subscription ID associated with this message will be
3151 * INVALID, which will result in the operation being completed on the subscription associated
3152 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
3153 * operation is performed on the correct subscription.
3154 * </p>
3155 *
Hongming Jin08496b02019-01-25 13:41:52 -08003156 * @param params the parameters to filter SMS messages returned.
3157 * @param executor the executor on which callback will be invoked.
3158 * @param callback a callback to receive CursorWindow with SMS messages.
Chen Xud6b26732019-09-29 19:55:06 -07003159 *
Hongming Jin08496b02019-01-25 13:41:52 -08003160 */
3161 @RequiresPermission(android.Manifest.permission.SMS_FINANCIAL_TRANSACTIONS)
3162 public void getSmsMessagesForFinancialApp(
3163 Bundle params,
3164 @NonNull @CallbackExecutor Executor executor,
3165 @NonNull FinancialSmsCallback callback) {
Chen Xud6b26732019-09-29 19:55:06 -07003166 // This API is not functional and thus removed to avoid future confusion.
Hongming Jin08496b02019-01-25 13:41:52 -08003167 }
3168
Dan Willemsen4980bf42017-02-14 14:17:12 -08003169 /**
Amit Mahajan24c01a22019-09-20 11:13:05 -07003170 * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent).
Hongming Jin46edf152019-01-17 12:11:59 -08003171 * The prefixes is a list of prefix {@code String} separated by this delimiter.
3172 * @hide
3173 */
3174 public static final String REGEX_PREFIX_DELIMITER = ",";
3175 /**
Amit Mahajan24c01a22019-09-20 11:13:05 -07003176 * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent).
Hongming Jin46edf152019-01-17 12:11:59 -08003177 * The success status to be added into the intent to be sent to the calling package.
3178 * @hide
3179 */
3180 public static final int RESULT_STATUS_SUCCESS = 0;
3181 /**
Amit Mahajan24c01a22019-09-20 11:13:05 -07003182 * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent).
Hongming Jin46edf152019-01-17 12:11:59 -08003183 * The timeout status to be added into the intent to be sent to the calling package.
3184 * @hide
3185 */
3186 public static final int RESULT_STATUS_TIMEOUT = 1;
3187 /**
Amit Mahajan24c01a22019-09-20 11:13:05 -07003188 * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent).
Hongming Jin46edf152019-01-17 12:11:59 -08003189 * Intent extra key of the retrieved SMS message as a {@code String}.
3190 * @hide
3191 */
3192 public static final String EXTRA_SMS_MESSAGE = "android.telephony.extra.SMS_MESSAGE";
3193 /**
Amit Mahajan24c01a22019-09-20 11:13:05 -07003194 * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent).
Hongming Jin46edf152019-01-17 12:11:59 -08003195 * Intent extra key of SMS retriever status, which indicates whether the request for the
3196 * coming SMS message is SUCCESS or TIMEOUT
3197 * @hide
3198 */
3199 public static final String EXTRA_STATUS = "android.telephony.extra.STATUS";
3200 /**
Amit Mahajan24c01a22019-09-20 11:13:05 -07003201 * @see #createAppSpecificSmsTokenWithPackageInfo(String, PendingIntent).
Hongming Jin46edf152019-01-17 12:11:59 -08003202 * [Optional] Intent extra key of the retrieved Sim card subscription Id if any. {@code int}
3203 * @hide
3204 */
3205 public static final String EXTRA_SIM_SUBSCRIPTION_ID =
3206 "android.telephony.extra.SIM_SUBSCRIPTION_ID";
3207
3208 /**
3209 * Create a single use app specific incoming SMS request for the calling package.
3210 *
3211 * This method returns a token that if included in a subsequent incoming SMS message, and the
3212 * SMS message has a prefix from the given prefixes list, the provided {@code intent} will be
3213 * sent with the SMS data to the calling package.
3214 *
3215 * The token is only good for one use within a reasonable amount of time. After an SMS has been
3216 * received containing the token all subsequent SMS messages with the token will be routed as
3217 * normal.
3218 *
3219 * An app can only have one request at a time, if the app already has a request pending it will
3220 * be replaced with a new request.
3221 *
Brad Ebinger360415a2019-04-30 11:37:27 -07003222 * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
3223 * dialog. If this method is called on a device that has multiple active subscriptions, this
3224 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
3225 * default subscription is defined, the subscription ID associated with this message will be
3226 * INVALID, which will result in the operation being completed on the subscription associated
3227 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
3228 * operation is performed on the correct subscription.
3229 * </p>
3230 *
Hongming Jin46edf152019-01-17 12:11:59 -08003231 * @param prefixes this is a list of prefixes string separated by REGEX_PREFIX_DELIMITER. The
3232 * matching SMS message should have at least one of the prefixes in the beginning of the
3233 * message.
3234 * @param intent this intent is sent when the matching SMS message is received.
3235 * @return Token to include in an SMS message.
3236 */
3237 @Nullable
3238 public String createAppSpecificSmsTokenWithPackageInfo(
3239 @Nullable String prefixes, @NonNull PendingIntent intent) {
3240 try {
3241 ISms iccSms = getISmsServiceOrThrow();
3242 return iccSms.createAppSpecificSmsTokenWithPackageInfo(getSubscriptionId(),
Shuo Qian24fded62020-01-14 14:48:27 -08003243 null, prefixes, intent);
Hongming Jin46edf152019-01-17 12:11:59 -08003244
3245 } catch (RemoteException ex) {
3246 ex.rethrowFromSystemServer();
3247 return null;
3248 }
3249 }
3250
Megha Patil9b206fc2022-11-10 06:37:37 +00003251 /**
3252 * Set Storage Availability in SmsStorageMonitor
3253 * @param storageAvailable storage availability to be set true or false
3254 * @hide
3255 */
3256 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3257 @TestApi
3258 public void setStorageMonitorMemoryStatusOverride(boolean storageAvailable) {
3259 try {
3260 ISms iccISms = getISmsServiceOrThrow();
3261 if (iccISms != null) {
3262 iccISms.setStorageMonitorMemoryStatusOverride(getSubscriptionId(),
3263 storageAvailable);
3264 }
3265 } catch (RemoteException ex) {
3266 ex.rethrowFromSystemServer();
3267 }
3268 }
3269
3270 /**
3271 * Clear the memory status override set by
3272 * {@link #setStorageMonitorMemoryStatusOverride(boolean)}
3273 * @hide
3274 */
3275 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3276 @TestApi
3277 public void clearStorageMonitorMemoryStatusOverride() {
3278 try {
3279 ISms iccISms = getISmsServiceOrThrow();
3280 if (iccISms != null) {
3281 iccISms.clearStorageMonitorMemoryStatusOverride(getSubscriptionId());
3282 }
3283 } catch (RemoteException ex) {
3284 ex.rethrowFromSystemServer();
3285 }
3286 }
3287
chen xu9c7fad92019-03-25 10:43:28 -07003288 /** @hide */
3289 @Retention(RetentionPolicy.SOURCE)
3290 @IntDef(prefix = {"SMS_CATEGORY_"},
3291 value = {
3292 SmsManager.SMS_CATEGORY_NOT_SHORT_CODE,
3293 SmsManager.SMS_CATEGORY_FREE_SHORT_CODE,
3294 SmsManager.SMS_CATEGORY_STANDARD_SHORT_CODE,
3295 SmsManager.SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE,
3296 SmsManager.SMS_CATEGORY_PREMIUM_SHORT_CODE})
3297 public @interface SmsShortCodeCategory {}
3298
3299 /**
3300 * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for regular
3301 * phone numbers.
3302 * @hide
3303 */
3304 @TestApi
3305 public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0;
3306 /**
3307 * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for free
3308 * (no cost) short codes.
3309 * @hide
3310 */
3311 @TestApi
3312 public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1;
3313 /**
3314 * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for
3315 * standard rate (non-premium)
3316 * short codes.
3317 * @hide
3318 */
3319 @TestApi
3320 public static final int SMS_CATEGORY_STANDARD_SHORT_CODE = 2;
3321 /**
3322 * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for possible
3323 * premium short codes.
3324 * @hide
3325 */
3326 @TestApi
3327 public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3;
3328 /**
3329 * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for
3330 * premium short codes.
3331 * @hide
3332 */
3333 @TestApi
3334 public static final int SMS_CATEGORY_PREMIUM_SHORT_CODE = 4;
3335
3336 /**
3337 * Check if the destination address is a possible premium short code.
3338 * NOTE: the caller is expected to strip non-digits from the destination number with
3339 * {@link PhoneNumberUtils#extractNetworkPortion} before calling this method.
3340 *
Brad Ebinger360415a2019-04-30 11:37:27 -07003341 * <p class="note"><strong>Note:</strong> This method is intended for internal use by carrier
3342 * applications or the Telephony framework and will never trigger an SMS disambiguation
3343 * dialog. If this method is called on a device that has multiple active subscriptions, this
3344 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
3345 * default subscription is defined, the subscription ID associated with this message will be
3346 * INVALID, which will result in the operation being completed on the subscription associated
3347 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the
3348 * operation is performed on the correct subscription.
3349 * </p>
3350 *
chen xu9c7fad92019-03-25 10:43:28 -07003351 * @param destAddress the destination address to test for possible short code
3352 * @param countryIso the ISO country code
3353 *
3354 * @return
3355 * {@link SmsManager#SMS_CATEGORY_NOT_SHORT_CODE},
3356 * {@link SmsManager#SMS_CATEGORY_FREE_SHORT_CODE},
3357 * {@link SmsManager#SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE},
3358 * {@link SmsManager#SMS_CATEGORY_PREMIUM_SHORT_CODE}, or
3359 * {@link SmsManager#SMS_CATEGORY_STANDARD_SHORT_CODE}
3360 *
3361 * @hide
3362 */
3363 @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
3364 @TestApi
3365 public @SmsShortCodeCategory int checkSmsShortCodeDestination(
3366 String destAddress, String countryIso) {
3367 try {
3368 ISms iccISms = getISmsServiceOrThrow();
3369 if (iccISms != null) {
3370 return iccISms.checkSmsShortCodeDestination(getSubscriptionId(),
Shuo Qian24fded62020-01-14 14:48:27 -08003371 null, null, destAddress, countryIso);
chen xu9c7fad92019-03-25 10:43:28 -07003372 }
3373 } catch (RemoteException e) {
3374 Log.e(TAG, "checkSmsShortCodeDestination() RemoteException", e);
3375 }
3376 return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
3377 }
Taesu Leef7488d02019-07-16 14:13:05 +09003378
3379 /**
3380 * Gets the SMSC address from (U)SIM.
3381 *
3382 * <p class="note"><strong>Note:</strong> Using this method requires that your app is the
3383 * default SMS application, or READ_PRIVILEGED_PHONE_STATE permission, or has the carrier
3384 * privileges.</p>
3385 *
3386 * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
3387 * dialog. If this method is called on a device that has multiple active subscriptions, this
3388 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
3389 * default subscription is defined, the subscription ID associated with this method will be
3390 * INVALID, which will result in the operation being completed on the subscription associated
3391 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation
3392 * is performed on the correct subscription.
3393 * </p>
3394 *
3395 * @return the SMSC address string, null if failed.
3396 */
3397 @SuppressAutoDoc // for carrier privileges and default SMS application.
3398 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3399 @Nullable
3400 public String getSmscAddress() {
3401 String smsc = null;
3402
3403 try {
3404 ISms iSms = getISmsService();
3405 if (iSms != null) {
3406 smsc = iSms.getSmscAddressFromIccEfForSubscriber(
Shuo Qian24fded62020-01-14 14:48:27 -08003407 getSubscriptionId(), null);
Taesu Leef7488d02019-07-16 14:13:05 +09003408 }
3409 } catch (RemoteException ex) {
Amit Mahajand42340b2020-03-03 15:49:58 -08003410 throw new RuntimeException(ex);
Taesu Leef7488d02019-07-16 14:13:05 +09003411 }
3412 return smsc;
3413 }
3414
3415 /**
3416 * Sets the SMSC address on (U)SIM.
3417 *
3418 * <p class="note"><strong>Note:</strong> Using this method requires that your app is the
3419 * default SMS application, or has {@link android.Manifest.permission#MODIFY_PHONE_STATE}
3420 * permission, or has the carrier privileges.</p>
3421 *
3422 * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
3423 * dialog. If this method is called on a device that has multiple active subscriptions, this
3424 * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
3425 * default subscription is defined, the subscription ID associated with this method will be
3426 * INVALID, which will result in the operation being completed on the subscription associated
3427 * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation
3428 * is performed on the correct subscription.
3429 * </p>
3430 *
3431 * @param smsc the SMSC address string.
Amit Mahajand42340b2020-03-03 15:49:58 -08003432 * @return true for success, false otherwise. Failure can be due modem returning an error.
Taesu Leef7488d02019-07-16 14:13:05 +09003433 */
3434 @SuppressAutoDoc // for carrier privileges and default SMS application.
3435 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3436 public boolean setSmscAddress(@NonNull String smsc) {
3437 try {
3438 ISms iSms = getISmsService();
3439 if (iSms != null) {
3440 return iSms.setSmscAddressOnIccEfForSubscriber(
Shuo Qian24fded62020-01-14 14:48:27 -08003441 smsc, getSubscriptionId(), null);
Taesu Leef7488d02019-07-16 14:13:05 +09003442 }
3443 } catch (RemoteException ex) {
Amit Mahajand42340b2020-03-03 15:49:58 -08003444 throw new RuntimeException(ex);
Taesu Leef7488d02019-07-16 14:13:05 +09003445 }
3446 return false;
3447 }
changbetty9dc2ca02019-12-26 19:57:35 +08003448
3449 /**
3450 * Gets the premium SMS permission for the specified package. If the package has never
changbettya3357582020-03-06 16:46:25 +08003451 * been seen before, the default {@link SmsManager#PREMIUM_SMS_CONSENT_UNKNOWN}
changbetty9dc2ca02019-12-26 19:57:35 +08003452 * will be returned.
3453 * @param packageName the name of the package to query permission
3454 * @return one of {@link SmsManager#PREMIUM_SMS_CONSENT_UNKNOWN},
3455 * {@link SmsManager#PREMIUM_SMS_CONSENT_ASK_USER},
3456 * {@link SmsManager#PREMIUM_SMS_CONSENT_NEVER_ALLOW}, or
3457 * {@link SmsManager#PREMIUM_SMS_CONSENT_ALWAYS_ALLOW}
3458 * @hide
3459 */
3460 @SystemApi
3461 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3462 public @PremiumSmsConsent int getPremiumSmsConsent(@NonNull String packageName) {
3463 int permission = 0;
3464 try {
3465 ISms iSms = getISmsService();
3466 if (iSms != null) {
3467 permission = iSms.getPremiumSmsPermission(packageName);
3468 }
3469 } catch (RemoteException e) {
3470 Log.e(TAG, "getPremiumSmsPermission() RemoteException", e);
3471 }
3472 return permission;
3473 }
3474
3475 /**
3476 * Sets the premium SMS permission for the specified package and save the value asynchronously
3477 * to persistent storage.
3478 * @param packageName the name of the package to set permission
3479 * @param permission one of {@link SmsManager#PREMIUM_SMS_CONSENT_ASK_USER},
3480 * {@link SmsManager#PREMIUM_SMS_CONSENT_NEVER_ALLOW}, or
3481 * {@link SmsManager#PREMIUM_SMS_CONSENT_ALWAYS_ALLOW}
3482 * @hide
3483 */
3484 @SystemApi
3485 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3486 public void setPremiumSmsConsent(
3487 @NonNull String packageName, @PremiumSmsConsent int permission) {
3488 try {
3489 ISms iSms = getISmsService();
3490 if (iSms != null) {
3491 iSms.setPremiumSmsPermission(packageName, permission);
3492 }
3493 } catch (RemoteException e) {
3494 Log.e(TAG, "setPremiumSmsPermission() RemoteException", e);
3495 }
3496 }
Jack Yue9c44272020-06-17 10:35:21 -07003497
3498 /**
3499 * Reset all cell broadcast ranges. Previously enabled ranges will become invalid after this.
Hui Wang1ebbd4c2023-01-03 23:10:45 +00003500 * @deprecated Use {@link TelephonyManager#setCellBroadcastIdRanges} with empty list instead
Jack Yue9c44272020-06-17 10:35:21 -07003501 * @hide
3502 */
Hui Wang473ed522022-12-05 14:58:27 -06003503 @Deprecated
Jordan Liud5b14982020-11-30 15:00:37 -08003504 @SystemApi
3505 @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
3506 public void resetAllCellBroadcastRanges() {
Jack Yue9c44272020-06-17 10:35:21 -07003507 try {
3508 ISms iSms = getISmsService();
3509 if (iSms != null) {
3510 // If getSubscriptionId() returns INVALID or an inactive subscription, we will use
3511 // the default phone internally.
Jordan Liud5b14982020-11-30 15:00:37 -08003512 iSms.resetAllCellBroadcastRanges(getSubscriptionId());
Jack Yue9c44272020-06-17 10:35:21 -07003513 }
3514 } catch (RemoteException ex) {
Jordan Liud5b14982020-11-30 15:00:37 -08003515 ex.rethrowFromSystemServer();
Jack Yue9c44272020-06-17 10:35:21 -07003516 }
Jack Yue9c44272020-06-17 10:35:21 -07003517 }
Tom Taylor1befe1a2020-12-22 15:12:51 -08003518
3519 private static String formatCrossStackMessageId(long id) {
3520 return "{x-message-id:" + id + "}";
3521 }
arunvodduac108782022-11-28 15:46:22 +00003522
3523 /**
3524 * Fetches the EF_PSISMSC value from the UICC that contains the Public Service Identity of
3525 * the SM-SC (either a SIP URI or tel URI). The EF_PSISMSC of ISIM and USIM can be found in
3526 * DF_TELECOM.
3527 * The EF_PSISMSC value is used by the ME to submit SMS over IP as defined in 24.341 [55].
3528 *
3529 * @return Uri : Public Service Identity of SM-SC from the ISIM or USIM if the ISIM is not
3530 * available.
3531 * @throws SecurityException if the caller does not have the required permission/privileges.
3532 * @throws IllegalStateException in case of telephony service is not available.
3533 * @hide
3534 */
3535 @NonNull
3536 @SystemApi
3537 @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
3538 @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
3539 public Uri getSmscIdentity() {
3540 Uri smscUri = Uri.EMPTY;
3541 try {
3542 IPhoneSubInfo info = TelephonyManager.getSubscriberInfoService();
3543 if (info == null) {
3544 Rlog.e(TAG, "getSmscIdentity(): IPhoneSubInfo instance is NULL");
3545 throw new IllegalStateException("Telephony service is not available");
3546 }
3547 /** Fetches the SIM EF_PSISMSC value based on subId and appType */
3548 smscUri = info.getSmscIdentity(getSubscriptionId(), TelephonyManager.APPTYPE_ISIM);
3549 if (Uri.EMPTY.equals(smscUri)) {
3550 /** Fallback in case where ISIM is not available */
3551 smscUri = info.getSmscIdentity(getSubscriptionId(), TelephonyManager.APPTYPE_USIM);
3552 }
3553 } catch (RemoteException ex) {
3554 Rlog.e(TAG, "getSmscIdentity(): Exception : " + ex);
3555 ex.rethrowAsRuntimeException();
3556 }
3557 return smscUri;
3558 }
Dan Willemsen4980bf42017-02-14 14:17:12 -08003559}