• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.telephony;
18 
19 import static android.Manifest.permission.SEND_SMS_NO_CONFIRMATION;
20 
21 import static com.android.internal.telephony.IccSmsInterfaceManager.SMS_MESSAGE_PERIOD_NOT_SPECIFIED;
22 import static com.android.internal.telephony.IccSmsInterfaceManager.SMS_MESSAGE_PRIORITY_NOT_SPECIFIED;
23 import static com.android.internal.telephony.SmsDispatchersController.PendingRequest;
24 import static com.android.internal.telephony.SmsResponse.NO_ERROR_CODE;
25 
26 import android.annotation.UserIdInt;
27 import android.app.Activity;
28 import android.app.AlertDialog;
29 import android.app.PendingIntent;
30 import android.app.PendingIntent.CanceledException;
31 import android.app.compat.CompatChanges;
32 import android.compat.annotation.ChangeId;
33 import android.compat.annotation.EnabledSince;
34 import android.compat.annotation.UnsupportedAppUsage;
35 import android.content.BroadcastReceiver;
36 import android.content.ContentResolver;
37 import android.content.ContentValues;
38 import android.content.Context;
39 import android.content.DialogInterface;
40 import android.content.Intent;
41 import android.content.IntentFilter;
42 import android.content.pm.ApplicationInfo;
43 import android.content.pm.PackageInfo;
44 import android.content.pm.PackageManager;
45 import android.content.res.Resources;
46 import android.content.res.Resources.NotFoundException;
47 import android.database.ContentObserver;
48 import android.net.Uri;
49 import android.os.AsyncResult;
50 import android.os.Binder;
51 import android.os.Build;
52 import android.os.Handler;
53 import android.os.Looper;
54 import android.os.Message;
55 import android.os.PersistableBundle;
56 import android.os.SystemClock;
57 import android.os.UserHandle;
58 import android.provider.Settings;
59 import android.provider.Telephony;
60 import android.provider.Telephony.Sms;
61 import android.service.carrier.CarrierMessagingService;
62 import android.service.carrier.CarrierMessagingServiceWrapper;
63 import android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback;
64 import android.telephony.AnomalyReporter;
65 import android.telephony.CarrierConfigManager;
66 import android.telephony.NetworkRegistrationInfo;
67 import android.telephony.PhoneNumberUtils;
68 import android.telephony.ServiceState;
69 import android.telephony.SmsManager;
70 import android.telephony.SubscriptionManager;
71 import android.telephony.TelephonyManager;
72 import android.text.Html;
73 import android.text.Spanned;
74 import android.text.TextUtils;
75 import android.util.EventLog;
76 import android.util.IndentingPrintWriter;
77 import android.util.LocalLog;
78 import android.view.LayoutInflater;
79 import android.view.View;
80 import android.view.ViewGroup;
81 import android.view.WindowManager;
82 import android.widget.Button;
83 import android.widget.CheckBox;
84 import android.widget.CompoundButton;
85 import android.widget.TextView;
86 
87 import com.android.internal.R;
88 import com.android.internal.annotations.VisibleForTesting;
89 import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
90 import com.android.internal.telephony.analytics.TelephonyAnalytics;
91 import com.android.internal.telephony.analytics.TelephonyAnalytics.SmsMmsAnalytics;
92 import com.android.internal.telephony.cdma.sms.UserData;
93 import com.android.internal.telephony.flags.Flags;
94 import com.android.internal.telephony.satellite.SatelliteController;
95 import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
96 import com.android.internal.telephony.subscription.SubscriptionManagerService;
97 import com.android.internal.telephony.uicc.IccRecords;
98 import com.android.internal.telephony.util.ArrayUtils;
99 import com.android.internal.telephony.util.TelephonyUtils;
100 import com.android.telephony.Rlog;
101 
102 import java.io.FileDescriptor;
103 import java.io.PrintWriter;
104 import java.util.ArrayList;
105 import java.util.Arrays;
106 import java.util.HashMap;
107 import java.util.List;
108 import java.util.Random;
109 import java.util.UUID;
110 import java.util.concurrent.atomic.AtomicBoolean;
111 import java.util.concurrent.atomic.AtomicInteger;
112 
113 public abstract class SMSDispatcher extends Handler {
114     static final String TAG = "SMSDispatcher";    // accessed from inner class
115     static final boolean DBG = false;
116     private static final String SEND_NEXT_MSG_EXTRA = "SendNextMsg";
117     private static final String MESSAGE_ID_EXTRA = "MessageId";
118     protected static final String MAP_KEY_PDU = "pdu";
119     protected static final String MAP_KEY_SMSC = "smsc";
120     protected static final String MAP_KEY_DEST_ADDR = "destAddr";
121     protected static final String MAP_KEY_SC_ADDR = "scAddr";
122     protected static final String MAP_KEY_DEST_PORT = "destPort";
123     protected static final String MAP_KEY_DATA = "data";
124     protected static final String MAP_KEY_TEXT = "text";
125 
126     private static final int PREMIUM_RULE_USE_SIM = 1;
127     private static final int PREMIUM_RULE_USE_NETWORK = 2;
128     private static final int PREMIUM_RULE_USE_BOTH = 3;
129     private final AtomicInteger mPremiumSmsRule = new AtomicInteger(PREMIUM_RULE_USE_SIM);
130     private final SettingsObserver mSettingsObserver;
131 
132     /** SMS send complete. */
133     protected static final int EVENT_SEND_SMS_COMPLETE = 2;
134 
135     /** Retry sending a previously failed SMS message */
136     protected static final int EVENT_SEND_RETRY = 3;
137 
138     /** Confirmation required for sending a large number of messages. */
139     private static final int EVENT_SEND_LIMIT_REACHED_CONFIRMATION = 4;
140 
141     /** Send the user confirmed SMS */
142     static final int EVENT_SEND_CONFIRMED_SMS = 5; // accessed from inner class
143 
144     /** Don't send SMS (user did not confirm). */
145     static final int EVENT_STOP_SENDING = 6; // accessed from inner class
146 
147     /** Don't send SMS for this app (User had already denied eariler.) */
148     static final int EVENT_SENDING_NOT_ALLOWED = 7;
149 
150     /** Confirmation required for third-party apps sending to an SMS short code. */
151     private static final int EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE = 8;
152 
153     /** Confirmation required for third-party apps sending to an SMS short code. */
154     private static final int EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE = 9;
155 
156     /** New status report received. */
157     protected static final int EVENT_NEW_SMS_STATUS_REPORT = 10;
158 
159     /** Retry Sending RP-SMMA Notification */
160     protected static final int EVENT_RETRY_SMMA = 11;
161     // other
162     protected static final int EVENT_NEW_ICC_SMS = 14;
163     protected static final int EVENT_ICC_CHANGED = 15;
164     protected static final int EVENT_GET_IMS_SERVICE = 16;
165 
166     /** Last TP - Message Reference value update to SIM */
167     private static final int EVENT_TPMR_SIM_UPDATE_RESPONSE = 17;
168 
169     /** Handle SIM loaded  */
170     private static final int EVENT_SIM_LOADED = 18;
171 
172     /**
173      * When this change is enabled, more specific values of SMS sending error code
174      * {@link SmsManager#Result} will be returned to the SMS Apps.
175      *
176      * Refer to {@link SMSDispatcher#rilErrorToSmsManagerResult} fore more details of the new values
177      * of SMS sending error code that will be returned.
178      */
179     @ChangeId
180     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
181     static final long ADD_MORE_SMS_SENDING_ERROR_CODES = 250017070L;
182 
183     @UnsupportedAppUsage
184     protected Phone mPhone;
185     @UnsupportedAppUsage
186     protected final Context mContext;
187     @UnsupportedAppUsage
188     protected final ContentResolver mResolver;
189     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
190     protected final CommandsInterface mCi;
191     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
192     protected final TelephonyManager mTelephonyManager;
193     protected final LocalLog mLocalLog = new LocalLog(16);
194     protected final LocalLog mSmsOutgoingErrorCodes = new LocalLog(10);
195 
196     /** Maximum number of times to retry sending a failed SMS. */
197     protected static final int MAX_SEND_RETRIES = 3;
198 
199     /** Retransmitted Flag as specified in section 6.3.1.2 in TS 124011
200      * true:  RP-SMMA Retried once and no more transmissions are permitted
201      * false: not retried at all and at least another transmission of the RP-SMMA message
202      * is currently permitted
203      */
204     protected boolean mRPSmmaRetried = false;
205 
206     /** Delay before next send attempt on a failed SMS, in milliseconds. */
207     @VisibleForTesting
208     public static final int SEND_RETRY_DELAY = 2000;
209     /** Message sending queue limit */
210     private static final int MO_MSG_QUEUE_LIMIT = 5;
211     /** SMS anomaly uuid -- CarrierMessagingService did not respond */
212     private static final UUID sAnomalyNoResponseFromCarrierMessagingService =
213             UUID.fromString("279d9fbc-462d-4fc2-802c-bf21ddd9dd90");
214     /** SMS anomaly uuid -- CarrierMessagingService unexpected callback */
215     private static final UUID sAnomalyUnexpectedCallback =
216             UUID.fromString("0103b6d2-ad07-4d86-9102-14341b9074ef");
217 
218     /**
219      * Message reference for a CONCATENATED_8_BIT_REFERENCE or
220      * CONCATENATED_16_BIT_REFERENCE message set.  Should be
221      * incremented for each set of concatenated messages.
222      * Static field shared by all dispatcher objects.
223      */
224     private static int sConcatenatedRef = new Random().nextInt(256);
225 
226     protected SmsDispatchersController mSmsDispatchersController;
227 
228     /** Number of outgoing SmsTrackers waiting for user confirmation. */
229     private int mPendingTrackerCount;
230 
231     /* Flags indicating whether the current device allows sms service */
232     protected boolean mSmsCapable = true;
233     protected boolean mSmsSendDisabled;
234 
235     @VisibleForTesting
236     public int mCarrierMessagingTimeout = 10 * 60 * 1000; //10 minutes
237 
238     /** Used for storing last TP - Message Reference used*/
239     private int mMessageRef = -1;
240 
241     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getNextConcatenatedRef()242     protected static int getNextConcatenatedRef() {
243         sConcatenatedRef += 1;
244         return sConcatenatedRef;
245     }
246 
247     /**
248      * Create a new SMS dispatcher.
249      * @param phone the Phone to use
250      */
SMSDispatcher(Phone phone, SmsDispatchersController smsDispatchersController)251     protected SMSDispatcher(Phone phone, SmsDispatchersController smsDispatchersController) {
252         mPhone = phone;
253         mSmsDispatchersController = smsDispatchersController;
254         mContext = phone.getContext();
255         mResolver = mContext.getContentResolver();
256         mCi = phone.mCi;
257         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
258         mSettingsObserver = new SettingsObserver(this, mPremiumSmsRule, mContext);
259         mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
260                 Settings.Global.SMS_SHORT_CODE_RULE), false, mSettingsObserver);
261 
262         mSmsCapable = mTelephonyManager.isDeviceSmsCapable();
263         mSmsSendDisabled = !mTelephonyManager.getSmsSendCapableForPhone(
264                 mPhone.getPhoneId(), mSmsCapable);
265         IntentFilter intentFilter = new IntentFilter();
266         intentFilter.addAction(Intent.ACTION_SIM_STATE_CHANGED);
267         mContext.registerReceiver(mBroadcastReceiver, intentFilter);
268         Rlog.d(TAG, "SMSDispatcher: ctor mSmsCapable=" + mSmsCapable + " format=" + getFormat()
269                 + " mSmsSendDisabled=" + mSmsSendDisabled);
270     }
271 
272     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
273         @Override
274         public void onReceive(final Context context, Intent intent) {
275             Rlog.d(TAG, "Received broadcast " + intent.getAction());
276             if (Intent.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
277                 if (!intent.hasExtra(Intent.EXTRA_SIM_STATE)) {
278                     Rlog.d(TAG, "Extra not found in intent.");
279                 } else {
280                     String simState = intent.getStringExtra(Intent.EXTRA_SIM_STATE);
281                     if (simState.equals(Intent.SIM_STATE_LOADED)) {
282                         Rlog.d(TAG, "SIM_STATE_CHANGED : SIM_LOADED");
283                         Message msg = obtainMessage(EVENT_SIM_LOADED);
284                         msg.arg1 = getSubId();
285                         sendMessage(msg);
286                     }
287                 }
288             }
289         }
290     };
291 
292     /**
293      * Observe the secure setting for updated premium sms determination rules
294      */
295     private static class SettingsObserver extends ContentObserver {
296         private final AtomicInteger mPremiumSmsRule;
297         private final Context mContext;
SettingsObserver(Handler handler, AtomicInteger premiumSmsRule, Context context)298         SettingsObserver(Handler handler, AtomicInteger premiumSmsRule, Context context) {
299             super(handler);
300             mPremiumSmsRule = premiumSmsRule;
301             mContext = context;
302             onChange(false); // load initial value;
303         }
304 
305         @Override
onChange(boolean selfChange)306         public void onChange(boolean selfChange) {
307             mPremiumSmsRule.set(Settings.Global.getInt(mContext.getContentResolver(),
308                     Settings.Global.SMS_SHORT_CODE_RULE, PREMIUM_RULE_USE_SIM));
309         }
310     }
311 
312     /** Unregister for incoming SMS events. */
313     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
dispose()314     public void dispose() {
315         mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
316     }
317 
318     /**
319      * The format of the message PDU in the associated broadcast intent.
320      * This will be either "3gpp" for GSM/UMTS/LTE messages in 3GPP format
321      * or "3gpp2" for CDMA/LTE messages in 3GPP2 format.
322      *
323      * Note: All applications which handle incoming SMS messages by processing the
324      * SMS_RECEIVED_ACTION broadcast intent MUST pass the "format" extra from the intent
325      * into the new methods in {@link android.telephony.SmsMessage} which take an
326      * extra format parameter. This is required in order to correctly decode the PDU on
327      * devices which require support for both 3GPP and 3GPP2 formats at the same time,
328      * such as CDMA/LTE devices and GSM/CDMA world phones.
329      *
330      * @return the format of the message PDU
331      */
getFormat()332     protected abstract String getFormat();
333 
334     /**
335      * Gets the maximum number of times the SMS can be retried upon Failure,
336      * from the {@link android.telephony.CarrierConfigManager}
337      *
338      * @return the default maximum number of times SMS can be sent
339      */
getMaxSmsRetryCount()340     protected int getMaxSmsRetryCount() {
341         return MAX_SEND_RETRIES;
342     }
343 
344     /**
345      * Gets the Time delay before next send attempt on a failed SMS,
346      * from the {@link android.telephony.CarrierConfigManager}
347      *
348      * @return the Time in miiliseconds for delay before next send attempt on a failed SMS
349      */
getSmsRetryDelayValue()350     protected int getSmsRetryDelayValue() {
351         return SEND_RETRY_DELAY;
352     }
353 
354     /**
355      * Called when a status report is received. This should correspond to a previously successful
356      * SEND.
357      *
358      * @param o AsyncResult object including a byte array for 3GPP status report PDU or SmsMessage
359      *          object for 3GPP2 status report.
360      */
handleStatusReport(Object o)361     protected void handleStatusReport(Object o) {
362         Rlog.d(TAG, "handleStatusReport() called with no subclass.");
363     }
364 
365     /**
366      * Handles events coming from the phone stack. Overridden from handler.
367      *
368      * @param msg the message to handle
369      */
370     @Override
handleMessage(Message msg)371     public void handleMessage(Message msg) {
372         switch (msg.what) {
373             case EVENT_SEND_SMS_COMPLETE:
374                 // An outbound SMS has been successfully transferred, or failed.
375                 handleSendComplete((AsyncResult) msg.obj);
376                 break;
377 
378             case EVENT_SEND_RETRY:
379                 Rlog.d(TAG, "SMS retry..");
380                 sendRetrySms((SmsTracker) msg.obj);
381                 break;
382 
383             case EVENT_SEND_LIMIT_REACHED_CONFIRMATION:
384                 handleReachSentLimit((SmsTracker[]) (msg.obj));
385                 break;
386 
387             case EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE:
388                 handleConfirmShortCode(false, (SmsTracker[]) (msg.obj));
389                 break;
390 
391             case EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE:
392                 handleConfirmShortCode(true, (SmsTracker[]) (msg.obj));
393                 break;
394 
395             case EVENT_SEND_CONFIRMED_SMS: {
396                 SmsTracker[] trackers = (SmsTracker[]) msg.obj;
397                 for (SmsTracker tracker : trackers) {
398                     sendSms(tracker);
399                 }
400                 mPendingTrackerCount--;
401                 break;
402             }
403 
404             case EVENT_SENDING_NOT_ALLOWED: {
405                 SmsTracker[] trackers = (SmsTracker[]) msg.obj;
406                 Rlog.d(TAG, "SMSDispatcher: EVENT_SENDING_NOT_ALLOWED - "
407                         + "sending SHORT_CODE_NEVER_ALLOWED error code.");
408                 handleSmsTrackersFailure(
409                         trackers, SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED, NO_ERROR_CODE);
410                 break;
411             }
412 
413             case EVENT_STOP_SENDING: {
414                 SmsTracker[] trackers = (SmsTracker[]) msg.obj;
415                 int error;
416                 if (msg.arg1 == ConfirmDialogListener.SHORT_CODE_MSG) {
417                     if (msg.arg2 == ConfirmDialogListener.NEVER_ALLOW) {
418                         error = SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED;
419                         Rlog.d(TAG, "SMSDispatcher: EVENT_STOP_SENDING - "
420                                 + "sending SHORT_CODE_NEVER_ALLOWED error code.");
421                     } else {
422                         error = SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED;
423                         Rlog.d(TAG, "SMSDispatcher: EVENT_STOP_SENDING - "
424                                 + "sending SHORT_CODE_NOT_ALLOWED error code.");
425                     }
426                 } else if (msg.arg1 == ConfirmDialogListener.RATE_LIMIT) {
427                     error = SmsManager.RESULT_ERROR_LIMIT_EXCEEDED;
428                     Rlog.d(TAG, "SMSDispatcher: EVENT_STOP_SENDING - "
429                             + "sending LIMIT_EXCEEDED error code.");
430                 } else {
431                     error = SmsManager.RESULT_UNEXPECTED_EVENT_STOP_SENDING;
432                     Rlog.e(TAG, "SMSDispatcher: EVENT_STOP_SENDING - unexpected cases.");
433                 }
434 
435                 handleSmsTrackersFailure(trackers, error, NO_ERROR_CODE);
436                 mPendingTrackerCount--;
437                 break;
438             }
439 
440             case EVENT_NEW_SMS_STATUS_REPORT:
441                 handleStatusReport(msg.obj);
442                 break;
443             case EVENT_TPMR_SIM_UPDATE_RESPONSE:
444                 handleMessageRefStatus(msg);
445                 break;
446 
447             case EVENT_SIM_LOADED:
448                 /* sim TPMR value is given higher priority if both are non-negative number.
449                    Use case:
450                    if sim was used on another device and inserted in a new device,
451                    that device will start sending the next TPMR after reading from the SIM.
452                  */
453                 mMessageRef = getTpmrValueFromSIM();
454                 if (mMessageRef == -1) {
455                     SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
456                             .getSubscriptionInfoInternal(msg.arg1);
457                     if (subInfo != null) {
458                         mMessageRef = subInfo.getLastUsedTPMessageReference();
459                     }
460                 }
461                 break;
462 
463             default:
464                 Rlog.e(TAG, "handleMessage() ignoring message of unexpected type " + msg.what);
465         }
466     }
467 
handleMessageRefStatus(Message msg)468     private void handleMessageRefStatus(Message msg) {
469         AsyncResult ar = (AsyncResult) msg.obj;
470         if (ar.exception != null) {
471             Rlog.e(TAG, "Failed to update TP - Message reference value to SIM " + ar.exception);
472         } else {
473             Rlog.d(TAG, "TP - Message reference updated to SIM Successfully");
474         }
475     }
476 
updateTPMessageReference()477     private void updateTPMessageReference() {
478         updateSIMLastTPMRValue(mMessageRef);
479         final long identity = Binder.clearCallingIdentity();
480         try {
481             SubscriptionManagerService.getInstance()
482                     .setLastUsedTPMessageReference(getSubId(), mMessageRef);
483         } catch (SecurityException e) {
484             Rlog.e(TAG, "Security Exception caused on messageRef updation to DB " + e.getMessage());
485         } finally {
486             Binder.restoreCallingIdentity(identity);
487         }
488     }
489 
updateSIMLastTPMRValue(int messageRef)490     private void updateSIMLastTPMRValue(int messageRef) {
491         Message msg = obtainMessage(EVENT_TPMR_SIM_UPDATE_RESPONSE);
492         IccRecords iccRecords = getIccRecords();
493         if (iccRecords != null) {
494             iccRecords.setSmssTpmrValue(messageRef, msg);
495         }
496     }
497 
getTpmrValueFromSIM()498     private int getTpmrValueFromSIM() {
499         IccRecords iccRecords = getIccRecords();
500         if (iccRecords != null) {
501             return iccRecords.getSmssTpmrValue();
502         }
503         return -1;
504     }
505 
getIccRecords()506     private IccRecords getIccRecords() {
507         if (mPhone != null && mPhone.getIccRecords() != null) {
508             return mPhone.getIccRecords();
509         }
510         return null;
511     }
512 
513     /**
514      * Returns the next TP message Reference value incremented by 1 for every sms sent .
515      * once a max of 255 is reached TP message Reference is reset to 0.
516      *
517      * @return messageRef TP message Reference value
518      */
nextMessageRef()519     public int nextMessageRef() {
520         if (!isMessageRefIncrementViaTelephony()) {
521             return 0;
522         }
523 
524         mMessageRef = (mMessageRef + 1) % 256;
525         updateTPMessageReference();
526         return mMessageRef;
527     }
528 
529     /**
530      * As modem is using the last used TP-MR value present in SIM card, increment of
531      * messageRef(TP-MR) value should be prevented (config_stk_sms_send_support set to false)
532      * at telephony framework. In future, config_stk_sms_send_support flag will be enabled
533      * so that messageRef(TP-MR) increment will be done at framework side only.
534      *
535      * TODO:- Need to have new flag to control writing TP-MR value to SIM or shared prefrence.
536      */
isMessageRefIncrementViaTelephony()537     public boolean isMessageRefIncrementViaTelephony() {
538         boolean isMessageRefIncrementEnabled = false;
539         try {
540             isMessageRefIncrementEnabled = mContext.getResources().getBoolean(
541                     com.android.internal.R.bool.config_stk_sms_send_support);
542         } catch (NotFoundException e) {
543             Rlog.e(TAG, "isMessageRefIncrementViaTelephony NotFoundException Exception");
544         }
545 
546         Rlog.i(TAG, "bool.config_stk_sms_send_support= " + isMessageRefIncrementEnabled);
547         return isMessageRefIncrementEnabled;
548     }
549 
550     /**
551      * Use the carrier messaging service to send a data or text SMS.
552      */
553     protected abstract class SmsSender extends Handler {
554         private static final int EVENT_TIMEOUT = 1;
555         // Initialized in sendSmsByCarrierApp
556         protected volatile CarrierMessagingCallback mSenderCallback;
557         protected final CarrierMessagingServiceWrapper mCarrierMessagingServiceWrapper =
558                 new CarrierMessagingServiceWrapper();
559         private String mCarrierPackageName;
560 
SmsSender()561         protected SmsSender() {
562             super(Looper.getMainLooper());
563         }
564 
565         /**
566          * Bind to carrierPackageName to send message through it
567          */
sendSmsByCarrierApp(String carrierPackageName, CarrierMessagingCallback senderCallback)568         public synchronized void sendSmsByCarrierApp(String carrierPackageName,
569                 CarrierMessagingCallback senderCallback) {
570             mCarrierPackageName = carrierPackageName;
571             mSenderCallback = senderCallback;
572             if (!mCarrierMessagingServiceWrapper.bindToCarrierMessagingService(
573                     mContext, carrierPackageName, runnable -> runnable.run(),
574                     ()->onServiceReady())) {
575                 Rlog.e(TAG, "bindService() for carrier messaging service failed");
576                 onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK);
577             } else {
578                 Rlog.d(TAG, "bindService() for carrier messaging service succeeded");
579                 sendMessageDelayed(obtainMessage(EVENT_TIMEOUT), mCarrierMessagingTimeout);
580             }
581         }
582 
583         /**
584          * Callback received from mCarrierPackageName on binding to it is done.
585          * NOTE: the implementations of this method must be synchronized to make sure it does not
586          * get called before {@link #sendSmsByCarrierApp} completes and {@link #EVENT_TIMEOUT} is
587          * posted
588          */
onServiceReady()589         public abstract void onServiceReady();
590 
591         /**
592          * Method to call message send callback with passed in result and default parameters
593          */
onSendComplete(@arrierMessagingService.SendResult int result)594         public abstract void onSendComplete(@CarrierMessagingService.SendResult int result);
595 
596         /**
597          * Used to get the SmsTracker for single part messages
598          */
getSmsTracker()599         public abstract SmsTracker getSmsTracker();
600 
601         /**
602          * Used to get the SmsTrackers for multi part messages
603          */
getSmsTrackers()604         public abstract SmsTracker[] getSmsTrackers();
605 
606         @Override
handleMessage(Message msg)607         public void handleMessage(Message msg) {
608             if (msg.what == EVENT_TIMEOUT) {
609                 logWithLocalLog("handleMessage: No response from " + mCarrierPackageName
610                         + " for " + mCarrierMessagingTimeout + " ms");
611                 AnomalyReporter.reportAnomaly(sAnomalyNoResponseFromCarrierMessagingService,
612                         "No response from " + mCarrierPackageName, mPhone.getCarrierId());
613                 onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK);
614             } else {
615                 logWithLocalLog("handleMessage: received unexpected message " + msg.what);
616             }
617         }
618 
removeTimeout()619         public void removeTimeout() {
620             removeMessages(EVENT_TIMEOUT);
621         }
622     }
623 
logWithLocalLog(String logStr)624     private void logWithLocalLog(String logStr) {
625         mLocalLog.log(logStr);
626         Rlog.d(TAG, logStr);
627     }
628 
629     /**
630      * Use the carrier messaging service to send a text SMS.
631      */
632     protected final class TextSmsSender extends SmsSender {
633         private final SmsTracker mTracker;
TextSmsSender(SmsTracker tracker)634         public TextSmsSender(SmsTracker tracker) {
635             super();
636             mTracker = tracker;
637         }
638 
639         @Override
onServiceReady()640         public synchronized void onServiceReady() {
641             Rlog.d(TAG, "TextSmsSender::onServiceReady");
642             HashMap<String, Object> map = mTracker.getData();
643             String text = (String) map.get(MAP_KEY_TEXT);
644 
645             if (text != null) {
646                 try {
647                     mCarrierMessagingServiceWrapper.sendTextSms(
648                             text,
649                             getSubId(),
650                             mTracker.mDestAddress,
651                             (mTracker.mDeliveryIntent != null)
652                                     ? CarrierMessagingService.SEND_FLAG_REQUEST_DELIVERY_STATUS
653                                     : 0,
654                             runnable -> runnable.run(),
655                             mSenderCallback);
656                 } catch (RuntimeException e) {
657                     Rlog.e(TAG, "TextSmsSender::onServiceReady: Exception sending the SMS: "
658                             + e.getMessage());
659                     onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK);
660                 }
661             } else {
662                 Rlog.d(TAG, "TextSmsSender::onServiceReady: text == null");
663                 onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK);
664             }
665         }
666 
667         @Override
onSendComplete(int result)668         public void onSendComplete(int result) {
669             mSenderCallback.onSendSmsComplete(result, 0 /* messageRef */);
670         }
671 
672         @Override
getSmsTracker()673         public SmsTracker getSmsTracker() {
674             return mTracker;
675         }
676 
677         @Override
getSmsTrackers()678         public SmsTracker[] getSmsTrackers() {
679             Rlog.e(TAG, "getSmsTrackers: Unexpected call for TextSmsSender");
680             return null;
681         }
682     }
683 
684     /**
685      * Use the carrier messaging service to send a data SMS.
686      */
687     protected final class DataSmsSender extends SmsSender {
688         private final SmsTracker mTracker;
DataSmsSender(SmsTracker tracker)689         public DataSmsSender(SmsTracker tracker) {
690             super();
691             mTracker = tracker;
692         }
693 
694         @Override
onServiceReady()695         public synchronized void onServiceReady() {
696             Rlog.d(TAG, "DataSmsSender::onServiceReady");
697             HashMap<String, Object> map = mTracker.getData();
698             byte[] data = (byte[]) map.get(MAP_KEY_DATA);
699             int destPort = (int) map.get(MAP_KEY_DEST_PORT);
700 
701             if (data != null) {
702                 try {
703                     mCarrierMessagingServiceWrapper.sendDataSms(
704                             data,
705                             getSubId(),
706                             mTracker.mDestAddress,
707                             destPort,
708                             (mTracker.mDeliveryIntent != null)
709                                     ? CarrierMessagingService.SEND_FLAG_REQUEST_DELIVERY_STATUS
710                                     : 0,
711                             runnable -> runnable.run(),
712                             mSenderCallback);
713                 } catch (RuntimeException e) {
714                     Rlog.e(TAG, "DataSmsSender::onServiceReady: Exception sending the SMS: "
715                             + e
716                             + " " + SmsController.formatCrossStackMessageId(mTracker.mMessageId));
717                     onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK);
718                 }
719             } else {
720                 Rlog.d(TAG, "DataSmsSender::onServiceReady: data == null");
721                 onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK);
722             }
723         }
724 
725         @Override
onSendComplete(int result)726         public void onSendComplete(int result) {
727             mSenderCallback.onSendSmsComplete(result, 0 /* messageRef */);
728         }
729 
730         @Override
getSmsTracker()731         public SmsTracker getSmsTracker() {
732             return mTracker;
733         }
734 
735         @Override
getSmsTrackers()736         public SmsTracker[] getSmsTrackers() {
737             Rlog.e(TAG, "getSmsTrackers: Unexpected call for DataSmsSender");
738             return null;
739         }
740     }
741 
742     /**
743      * Callback for TextSmsSender and DataSmsSender from the carrier messaging service.
744      * Once the result is ready, the carrier messaging service connection is disposed.
745      */
746     protected final class SmsSenderCallback implements CarrierMessagingCallback {
747         private final SmsSender mSmsSender;
748         private boolean mCallbackCalled = false;
749 
SmsSenderCallback(SmsSender smsSender)750         public SmsSenderCallback(SmsSender smsSender) {
751             mSmsSender = smsSender;
752         }
753 
754         /**
755          * This method should be called only once.
756          */
757         @Override
onSendSmsComplete(int result, int messageRef)758         public void onSendSmsComplete(int result, int messageRef) {
759             Rlog.d(TAG, "onSendSmsComplete: result=" + result + " messageRef=" + messageRef);
760             if (cleanupOnSendSmsComplete("onSendSmsComplete")) {
761                 return;
762             }
763 
764             final long identity = Binder.clearCallingIdentity();
765             try {
766                 processSendSmsResponse(mSmsSender.getSmsTracker(), result, messageRef);
767             } finally {
768                 Binder.restoreCallingIdentity(identity);
769             }
770         }
771 
772         /**
773          * This method should be called only once.
774          */
775         @Override
onSendMultipartSmsComplete(int result, int[] messageRefs)776         public void onSendMultipartSmsComplete(int result, int[] messageRefs) {
777             Rlog.d(TAG, "onSendMultipartSmsComplete: result=" + result + " messageRefs="
778                     + Arrays.toString(messageRefs));
779             if (cleanupOnSendSmsComplete("onSendMultipartSmsComplete")) {
780                 return;
781             }
782 
783             final long identity = Binder.clearCallingIdentity();
784             try {
785                 processSendMultipartSmsResponse(mSmsSender.getSmsTrackers(), result, messageRefs);
786             } finally {
787                 Binder.restoreCallingIdentity(identity);
788             }
789         }
790 
cleanupOnSendSmsComplete(String callingFunction)791         private boolean cleanupOnSendSmsComplete(String callingFunction) {
792             if (mCallbackCalled) {
793                 logWithLocalLog(callingFunction + ": unexpected call");
794                 AnomalyReporter.reportAnomaly(sAnomalyUnexpectedCallback,
795                         "Unexpected " + callingFunction, mPhone.getCarrierId());
796                 return true;
797             }
798 
799             mCallbackCalled = true;
800             mSmsSender.removeTimeout();
801             mSmsSender.mCarrierMessagingServiceWrapper.disconnect();
802 
803             return false;
804         }
805 
806         @Override
onReceiveSmsComplete(int result)807         public void onReceiveSmsComplete(int result) {
808             Rlog.e(TAG, "Unexpected onReceiveSmsComplete call with result: " + result);
809         }
810 
811         @Override
onSendMmsComplete(int result, byte[] sendConfPdu)812         public void onSendMmsComplete(int result, byte[] sendConfPdu) {
813             Rlog.e(TAG, "Unexpected onSendMmsComplete call with result: " + result);
814         }
815 
816         @Override
onDownloadMmsComplete(int result)817         public void onDownloadMmsComplete(int result) {
818             Rlog.e(TAG, "Unexpected onDownloadMmsComplete call with result: " + result);
819         }
820     }
821 
822     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
processSendSmsResponse(SmsTracker tracker, int result, int messageRef)823     private void processSendSmsResponse(SmsTracker tracker, int result, int messageRef) {
824         if (tracker == null) {
825             Rlog.e(TAG, "processSendSmsResponse: null tracker");
826             return;
827         }
828 
829         SmsResponse smsResponse = new SmsResponse(messageRef, null /* ackPdu */, NO_ERROR_CODE,
830                 tracker.mMessageId);
831         if (Flags.temporaryFailuresInCarrierMessagingService()) {
832             tracker.mResultCodeFromCarrierMessagingService = result;
833         }
834 
835         switch (result) {
836             case CarrierMessagingService.SEND_STATUS_OK:
837                 Rlog.d(TAG, "processSendSmsResponse: Sending SMS by CarrierMessagingService "
838                         + "succeeded. "
839                         + SmsController.formatCrossStackMessageId(tracker.mMessageId));
840                 sendMessage(obtainMessage(EVENT_SEND_SMS_COMPLETE,
841                                           new AsyncResult(tracker,
842                                                           smsResponse,
843                                                           null /* exception*/)));
844                 break;
845             case CarrierMessagingService.SEND_STATUS_ERROR: // fall through
846             case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_GENERIC_FAILURE: // fall through
847             case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_NULL_PDU: // fall through
848             case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_NO_SERVICE: // fall through
849             case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_LIMIT_EXCEEDED: // fall through
850             case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_FDN_CHECK_FAILURE: // fall through
851             case CarrierMessagingService
852                     .SEND_STATUS_RESULT_ERROR_SHORT_CODE_NOT_ALLOWED: // fall through
853             case CarrierMessagingService
854                     .SEND_STATUS_RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED: // fall through
855             case CarrierMessagingService.SEND_STATUS_RESULT_NETWORK_REJECT: // fall through
856             case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_ARGUMENTS: // fall through
857             case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_STATE: // fall through
858             case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_SMS_FORMAT: // fall through
859             case CarrierMessagingService.SEND_STATUS_RESULT_NETWORK_ERROR: // fall through
860             case CarrierMessagingService.SEND_STATUS_RESULT_ENCODING_ERROR: // fall through
861             case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_SMSC_ADDRESS: // fall through
862             case CarrierMessagingService.SEND_STATUS_RESULT_OPERATION_NOT_ALLOWED: // fall through
863             case CarrierMessagingService.SEND_STATUS_RESULT_CANCELLED: // fall through
864             case CarrierMessagingService.SEND_STATUS_RESULT_REQUEST_NOT_SUPPORTED: // fall through
865             case CarrierMessagingService
866                     .SEND_STATUS_RESULT_SMS_BLOCKED_DURING_EMERGENCY: // fall through
867             case CarrierMessagingService.SEND_STATUS_RESULT_SMS_SEND_RETRY_FAILED: // fall through
868                 Rlog.d(
869                         TAG,
870                         "processSendSmsResponse: Sending SMS by CarrierMessagingService"
871                                 + " failed. "
872                                 + SmsController.formatCrossStackMessageId(tracker.mMessageId));
873                 sendMessage(obtainMessage(EVENT_SEND_SMS_COMPLETE,
874                         new AsyncResult(tracker, smsResponse,
875                                 new CommandException(CommandException.Error.GENERIC_FAILURE))));
876                 break;
877             case CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK:
878                 Rlog.d(TAG, "processSendSmsResponse: Sending SMS by CarrierMessagingService failed."
879                         + " Retry on carrier network. "
880                         + SmsController.formatCrossStackMessageId(tracker.mMessageId));
881                 sendSubmitPdu(tracker);
882                 break;
883             default:
884                 Rlog.d(TAG, "processSendSmsResponse: Unknown result " + result + " Retry on carrier"
885                         + " network. "
886                         + SmsController.formatCrossStackMessageId(tracker.mMessageId));
887                 sendSubmitPdu(tracker);
888         }
889     }
890 
toSmsManagerResultForSendSms(int carrierMessagingServiceResult)891     private int toSmsManagerResultForSendSms(int carrierMessagingServiceResult) {
892         switch (carrierMessagingServiceResult) {
893             case CarrierMessagingService.SEND_STATUS_OK:
894                 return Activity.RESULT_OK;
895             case CarrierMessagingService.SEND_STATUS_ERROR:
896                 return SmsManager.RESULT_RIL_GENERIC_ERROR;
897             case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_GENERIC_FAILURE:
898                 return SmsManager.RESULT_ERROR_GENERIC_FAILURE;
899             case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_NULL_PDU:
900                 return SmsManager.RESULT_ERROR_NULL_PDU;
901             case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_NO_SERVICE:
902                 return SmsManager.RESULT_ERROR_NO_SERVICE;
903             case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_LIMIT_EXCEEDED:
904                 return SmsManager.RESULT_ERROR_LIMIT_EXCEEDED;
905             case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_FDN_CHECK_FAILURE:
906                 return SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE;
907             case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_SHORT_CODE_NOT_ALLOWED:
908                 return SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED;
909             case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED:
910                 return SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED;
911             case CarrierMessagingService.SEND_STATUS_RESULT_NETWORK_REJECT:
912                 return SmsManager.RESULT_NETWORK_REJECT;
913             case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_ARGUMENTS:
914                 return SmsManager.RESULT_INVALID_ARGUMENTS;
915             case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_STATE:
916                 return SmsManager.RESULT_INVALID_STATE;
917             case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_SMS_FORMAT:
918                 return SmsManager.RESULT_INVALID_SMS_FORMAT;
919             case CarrierMessagingService.SEND_STATUS_RESULT_NETWORK_ERROR:
920                 return SmsManager.RESULT_NETWORK_ERROR;
921             case CarrierMessagingService.SEND_STATUS_RESULT_ENCODING_ERROR:
922                 return SmsManager.RESULT_ENCODING_ERROR;
923             case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_SMSC_ADDRESS:
924                 return SmsManager.RESULT_INVALID_SMSC_ADDRESS;
925             case CarrierMessagingService.SEND_STATUS_RESULT_OPERATION_NOT_ALLOWED:
926                 return SmsManager.RESULT_OPERATION_NOT_ALLOWED;
927             case CarrierMessagingService.SEND_STATUS_RESULT_CANCELLED:
928                 return SmsManager.RESULT_CANCELLED;
929             case CarrierMessagingService.SEND_STATUS_RESULT_REQUEST_NOT_SUPPORTED:
930                 return SmsManager.RESULT_REQUEST_NOT_SUPPORTED;
931             case CarrierMessagingService.SEND_STATUS_RESULT_SMS_BLOCKED_DURING_EMERGENCY:
932                 return SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY;
933             case CarrierMessagingService.SEND_STATUS_RESULT_SMS_SEND_RETRY_FAILED:
934                 return SmsManager.RESULT_SMS_SEND_RETRY_FAILED;
935             default:
936                 return SmsManager.RESULT_ERROR_GENERIC_FAILURE;
937         }
938     }
939 
940     /**
941      * Use the carrier messaging service to send a multipart text SMS.
942      */
943     private final class MultipartSmsSender extends SmsSender {
944         private final List<String> mParts;
945         public final SmsTracker[] mTrackers;
946 
MultipartSmsSender(ArrayList<String> parts, SmsTracker[] trackers)947         MultipartSmsSender(ArrayList<String> parts, SmsTracker[] trackers) {
948             super();
949             mParts = parts;
950             mTrackers = trackers;
951         }
952 
953         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
sendSmsByCarrierApp(String carrierPackageName, SmsSenderCallback senderCallback)954         void sendSmsByCarrierApp(String carrierPackageName, SmsSenderCallback senderCallback) {
955             super.sendSmsByCarrierApp(carrierPackageName, senderCallback);
956         }
957 
958         @Override
onServiceReady()959         public synchronized void onServiceReady() {
960             Rlog.d(TAG, "MultipartSmsSender::onServiceReady");
961             boolean statusReportRequested = false;
962             for (SmsTracker tracker : mTrackers) {
963                 if (tracker.mDeliveryIntent != null) {
964                     statusReportRequested = true;
965                     break;
966                 }
967             }
968 
969             try {
970                 mCarrierMessagingServiceWrapper.sendMultipartTextSms(
971                         mParts,
972                         getSubId(),
973                         mTrackers[0].mDestAddress,
974                         statusReportRequested
975                                 ? CarrierMessagingService.SEND_FLAG_REQUEST_DELIVERY_STATUS
976                                 : 0,
977                         runnable -> runnable.run(),
978                         mSenderCallback);
979             } catch (RuntimeException e) {
980                 Rlog.e(TAG, "MultipartSmsSender::onServiceReady: Exception sending the SMS: " + e);
981                 onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK);
982             }
983         }
984 
985         @Override
onSendComplete(int result)986         public void onSendComplete(int result) {
987             mSenderCallback.onSendMultipartSmsComplete(result, null /* messageRefs */);
988         }
989 
990         @Override
getSmsTracker()991         public SmsTracker getSmsTracker() {
992             Rlog.e(TAG, "getSmsTracker: Unexpected call for MultipartSmsSender");
993             return null;
994         }
995 
996         @Override
getSmsTrackers()997         public SmsTracker[] getSmsTrackers() {
998             return mTrackers;
999         }
1000     }
1001 
processSendMultipartSmsResponse( SmsTracker[] trackers, int result, int[] messageRefs)1002     private void processSendMultipartSmsResponse(
1003             SmsTracker[] trackers, int result, int[] messageRefs) {
1004         if (trackers == null) {
1005             Rlog.e(TAG, "processSendMultipartSmsResponse: null trackers");
1006             return;
1007         }
1008 
1009         switch (result) {
1010             case CarrierMessagingService.SEND_STATUS_OK:
1011                 Rlog.d(TAG, "processSendMultipartSmsResponse: Sending SMS by "
1012                         + "CarrierMessagingService succeeded. "
1013                         + SmsController.formatCrossStackMessageId(trackers[0].mMessageId));
1014                 // Sending a multi-part SMS by CarrierMessagingService successfully completed.
1015                 // Send EVENT_SEND_SMS_COMPLETE for all the parts one by one.
1016                 for (int i = 0; i < trackers.length; i++) {
1017                     int messageRef = 0;
1018                     if (messageRefs != null && messageRefs.length > i) {
1019                         messageRef = messageRefs[i];
1020                     }
1021                     sendMessage(
1022                             obtainMessage(
1023                                     EVENT_SEND_SMS_COMPLETE,
1024                                     new AsyncResult(
1025                                             trackers[i],
1026                                             new SmsResponse(
1027                                                     messageRef, null /* ackPdu */, NO_ERROR_CODE),
1028                                             null /* exception */)));
1029                 }
1030                 break;
1031             case CarrierMessagingService.SEND_STATUS_ERROR:
1032                 Rlog.d(TAG, "processSendMultipartSmsResponse: Sending SMS by "
1033                         + "CarrierMessagingService failed. "
1034                         + SmsController.formatCrossStackMessageId(trackers[0].mMessageId));
1035                 // Sending a multi-part SMS by CarrierMessagingService failed.
1036                 // Send EVENT_SEND_SMS_COMPLETE with GENERIC_FAILURE for all the parts one by one.
1037                 for (int i = 0; i < trackers.length; i++) {
1038                     int messageRef = 0;
1039                     if (messageRefs != null && messageRefs.length > i) {
1040                         messageRef = messageRefs[i];
1041                     }
1042                     sendMessage(
1043                             obtainMessage(
1044                                     EVENT_SEND_SMS_COMPLETE,
1045                                     new AsyncResult(
1046                                             trackers[i],
1047                                             new SmsResponse(
1048                                                     messageRef, null /* ackPdu */, NO_ERROR_CODE),
1049                                             new CommandException(
1050                                                     CommandException.Error.GENERIC_FAILURE))));
1051                 }
1052                 break;
1053             case CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK:
1054                 Rlog.d(TAG, "processSendMultipartSmsResponse: Sending SMS by "
1055                         + "CarrierMessagingService failed. Retry on carrier network. "
1056                         + SmsController.formatCrossStackMessageId(trackers[0].mMessageId));
1057                 // All the parts for a multi-part SMS are handled together for retry. It helps to
1058                 // check user confirmation once also if needed.
1059                 sendSubmitPdu(trackers);
1060                 break;
1061             default:
1062                 Rlog.d(TAG, "processSendMultipartSmsResponse: Unknown result " + result
1063                         + ". Retry on carrier network. "
1064                         + SmsController.formatCrossStackMessageId(trackers[0].mMessageId));
1065                 sendSubmitPdu(trackers);
1066         }
1067     }
1068 
1069     /** Send a single SMS PDU. */
1070     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
sendSubmitPdu(SmsTracker tracker)1071     private void sendSubmitPdu(SmsTracker tracker) {
1072         sendSubmitPdu(new SmsTracker[] {tracker});
1073     }
1074 
1075     /** Send a multi-part SMS PDU. Usually just calls {@link sendRawPdu}. */
sendSubmitPdu(SmsTracker[] trackers)1076     private void sendSubmitPdu(SmsTracker[] trackers) {
1077         if (shouldBlockSmsForEcbm()) {
1078             Rlog.d(TAG, "Block SMS in Emergency Callback mode");
1079             handleSmsTrackersFailure(trackers, SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY,
1080                     NO_ERROR_CODE);
1081         } else {
1082             sendRawPdu(trackers);
1083         }
1084     }
1085 
1086     /**
1087      * @return true if MO SMS should be blocked for Emergency Callback Mode.
1088      */
shouldBlockSmsForEcbm()1089     protected abstract boolean shouldBlockSmsForEcbm();
1090 
1091     /**
1092      * Notifies the {@link SmsDispatchersController} that sending MO SMS is failed.
1093      *
1094      * @param tracker holds the SMS message to be sent
1095      * @param isOverIms a flag specifying whether SMS is sent via IMS or not
1096      */
notifySmsSentFailedToEmergencyStateTracker(SmsTracker tracker, boolean isOverIms)1097     protected void notifySmsSentFailedToEmergencyStateTracker(SmsTracker tracker,
1098             boolean isOverIms) {
1099         mSmsDispatchersController.notifySmsSent(tracker, isOverIms,
1100             true /*isLastSmsPart*/, false /*success*/);
1101     }
1102 
1103     /**
1104      * Called when SMS send completes. Broadcasts a sentIntent on success.
1105      * On failure, either sets up retries or broadcasts a sentIntent with
1106      * the failure in the result code.
1107      *
1108      * @param ar AsyncResult passed into the message handler.  ar.result should
1109      *           an SmsResponse instance if send was successful.  ar.userObj
1110      *           should be an SmsTracker instance.
1111      */
handleSendComplete(AsyncResult ar)1112     protected void handleSendComplete(AsyncResult ar) {
1113         SmsTracker tracker = (SmsTracker) ar.userObj;
1114         PendingIntent sentIntent = tracker.mSentIntent;
1115         SmsResponse smsResponse = (SmsResponse) ar.result;
1116 
1117         if (smsResponse != null) {
1118             tracker.mMessageRef = smsResponse.mMessageRef;
1119         } else {
1120             Rlog.d(TAG, "SmsResponse was null");
1121         }
1122 
1123         if (ar.exception == null) {
1124             if (DBG) {
1125                 Rlog.d(TAG, "SMS send complete. Broadcasting intent: " + sentIntent
1126                         + " " + SmsController.formatCrossStackMessageId(tracker.mMessageId));
1127             }
1128 
1129             if (tracker.mDeliveryIntent != null) {
1130                 // Expecting a status report. Put this tracker to the map.
1131                 mSmsDispatchersController.putDeliveryPendingTracker(tracker);
1132             }
1133             tracker.onSent(mContext);
1134             mPhone.notifySmsSent(tracker.mDestAddress);
1135             mSmsDispatchersController.notifySmsSent(tracker, false,
1136                 tracker.isSinglePartOrLastPart(), true /*success*/);
1137 
1138             mPhone.getSmsStats().onOutgoingSms(
1139                     tracker.mImsRetry > 0 /* isOverIms */,
1140                     SmsConstants.FORMAT_3GPP2.equals(getFormat()),
1141                     false /* fallbackToCs */,
1142                     SmsManager.RESULT_ERROR_NONE,
1143                     tracker.mMessageId,
1144                     tracker.isFromDefaultSmsApplication(mContext),
1145                     tracker.getInterval(),
1146                     mTelephonyManager.isEmergencyNumber(tracker.mDestAddress),
1147                     tracker.isMtSmsPollingMessage(mContext));
1148             if (mPhone != null) {
1149                 TelephonyAnalytics telephonyAnalytics = mPhone.getTelephonyAnalytics();
1150                 if (telephonyAnalytics != null) {
1151                     SmsMmsAnalytics smsMmsAnalytics = telephonyAnalytics.getSmsMmsAnalytics();
1152                     if (smsMmsAnalytics != null) {
1153                         smsMmsAnalytics.onOutgoingSms(
1154                                 tracker.mImsRetry > 0 /* isOverIms */,
1155                                 SmsManager.RESULT_ERROR_NONE
1156                         );
1157                     }
1158                 }
1159             }
1160 
1161         } else {
1162             if (DBG) {
1163                 Rlog.d(TAG, "SMS send failed "
1164                         + SmsController.formatCrossStackMessageId(tracker.mMessageId));
1165             }
1166 
1167             int error;
1168             if (Flags.temporaryFailuresInCarrierMessagingService()
1169                     && tracker.mResultCodeFromCarrierMessagingService
1170                             != CarrierMessagingService.SEND_STATUS_OK) {
1171                 error =
1172                         toSmsManagerResultForSendSms(
1173                                 tracker.mResultCodeFromCarrierMessagingService);
1174             } else {
1175                 error =
1176                         rilErrorToSmsManagerResult(
1177                                 ((CommandException) (ar.exception)).getCommandError(), tracker);
1178             }
1179 
1180             int ss = mPhone.getServiceState().getState();
1181             if (tracker.mImsRetry > 0 && ss != ServiceState.STATE_IN_SERVICE) {
1182                 // This is retry after failure over IMS but voice is not available.
1183                 // Set retry to max allowed, so no retry is sent and cause
1184                 // SmsManager.RESULT_ERROR_GENERIC_FAILURE to be returned to app.
1185                 tracker.mRetryCount = getMaxSmsRetryCount();
1186 
1187                 Rlog.d(TAG, "handleSendComplete: Skipping retry: "
1188                         + " isIms()=" + isIms()
1189                         + " mRetryCount=" + tracker.mRetryCount
1190                         + " mImsRetry=" + tracker.mImsRetry
1191                         + " mMessageRef=" + tracker.mMessageRef
1192                         + " SS= " + mPhone.getServiceState().getState()
1193                         + " " + SmsController.formatCrossStackMessageId(tracker.mMessageId));
1194             }
1195 
1196             // if sms over IMS is not supported on data and voice is not available...
1197             if (!isIms() && ss != ServiceState.STATE_IN_SERVICE) {
1198                 tracker.onFailed(mContext, getNotInServiceError(ss), NO_ERROR_CODE);
1199                 notifySmsSentFailedToEmergencyStateTracker(tracker, false);
1200                 mPhone.getSmsStats().onOutgoingSms(
1201                         tracker.mImsRetry > 0 /* isOverIms */,
1202                         SmsConstants.FORMAT_3GPP2.equals(getFormat()),
1203                         false /* fallbackToCs */,
1204                         getNotInServiceError(ss),
1205                         tracker.mMessageId,
1206                         tracker.isFromDefaultSmsApplication(mContext),
1207                         tracker.getInterval(),
1208                         mTelephonyManager.isEmergencyNumber(tracker.mDestAddress),
1209                         tracker.isMtSmsPollingMessage(mContext));
1210                 if (mPhone != null) {
1211                     TelephonyAnalytics telephonyAnalytics = mPhone.getTelephonyAnalytics();
1212                     if (telephonyAnalytics != null) {
1213                         SmsMmsAnalytics smsMmsAnalytics = telephonyAnalytics.getSmsMmsAnalytics();
1214                         if (smsMmsAnalytics != null) {
1215                             smsMmsAnalytics.onOutgoingSms(
1216                                     tracker.mImsRetry > 0 /* isOverIms */,
1217                                     getNotInServiceError(ss)
1218                             );
1219                         }
1220                     }
1221                 }
1222 
1223             } else if (error == SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY
1224                     && tracker.mRetryCount < getMaxSmsRetryCount()) {
1225                 // Retry after a delay if needed.
1226                 // TODO: According to TS 23.040, 9.2.3.6, we should resend
1227                 //       with the same TP-MR as the failed message, and
1228                 //       TP-RD set to 1.  However, we don't have a means of
1229                 //       knowing the MR for the failed message (EF_SMSstatus
1230                 //       may or may not have the MR corresponding to this
1231                 //       message, depending on the failure).  Also, in some
1232                 //       implementations this retry is handled by the baseband.
1233                 tracker.mRetryCount++;
1234                 int errorCode = (smsResponse != null) ? smsResponse.mErrorCode : NO_ERROR_CODE;
1235                 Message retryMsg = obtainMessage(EVENT_SEND_RETRY, tracker);
1236                 sendMessageDelayed(retryMsg, getSmsRetryDelayValue());
1237                 mPhone.getSmsStats().onOutgoingSms(
1238                         tracker.mImsRetry > 0 /* isOverIms */,
1239                         SmsConstants.FORMAT_3GPP2.equals(getFormat()),
1240                         false /* fallbackToCs */,
1241                         SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY,
1242                         errorCode,
1243                         tracker.mMessageId,
1244                         tracker.isFromDefaultSmsApplication(mContext),
1245                         tracker.getInterval(),
1246                         mTelephonyManager.isEmergencyNumber(tracker.mDestAddress),
1247                         tracker.isMtSmsPollingMessage(mContext));
1248                 if (mPhone != null) {
1249                     TelephonyAnalytics telephonyAnalytics = mPhone.getTelephonyAnalytics();
1250                     if (telephonyAnalytics != null) {
1251                         SmsMmsAnalytics smsMmsAnalytics = telephonyAnalytics.getSmsMmsAnalytics();
1252                         if (smsMmsAnalytics != null) {
1253                             smsMmsAnalytics.onOutgoingSms(
1254                                     tracker.mImsRetry > 0 /* isOverIms */,
1255                                     SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY
1256                             );
1257                         }
1258                     }
1259                 }
1260 
1261             } else {
1262                 int errorCode = (smsResponse != null) ? smsResponse.mErrorCode : NO_ERROR_CODE;
1263                 tracker.onFailed(mContext, error, errorCode);
1264                 notifySmsSentFailedToEmergencyStateTracker(tracker, false);
1265                 mPhone.getSmsStats().onOutgoingSms(
1266                         tracker.mImsRetry > 0 /* isOverIms */,
1267                         SmsConstants.FORMAT_3GPP2.equals(getFormat()),
1268                         false /* fallbackToCs */,
1269                         error,
1270                         errorCode,
1271                         tracker.mMessageId,
1272                         tracker.isFromDefaultSmsApplication(mContext),
1273                         tracker.getInterval(),
1274                         mTelephonyManager.isEmergencyNumber(tracker.mDestAddress),
1275                         tracker.isMtSmsPollingMessage(mContext));
1276                 if (mPhone != null) {
1277                     TelephonyAnalytics telephonyAnalytics = mPhone.getTelephonyAnalytics();
1278                     if (telephonyAnalytics != null) {
1279                         SmsMmsAnalytics smsMmsAnalytics = telephonyAnalytics.getSmsMmsAnalytics();
1280                         if (smsMmsAnalytics != null) {
1281                             smsMmsAnalytics.onOutgoingSms(
1282                                     tracker.mImsRetry > 0 /* isOverIms */,
1283                                     error);
1284                         }
1285                     }
1286                 }
1287             }
1288         }
1289     }
1290 
1291     @SmsManager.Result
rilErrorToSmsManagerResult(CommandException.Error rilError, SmsTracker tracker)1292     private int rilErrorToSmsManagerResult(CommandException.Error rilError,
1293             SmsTracker tracker) {
1294         mSmsOutgoingErrorCodes.log("rilError: " + rilError
1295                 + ", MessageId: " + SmsController.formatCrossStackMessageId(tracker.mMessageId));
1296 
1297         ApplicationInfo appInfo = tracker.getAppInfo();
1298         if (appInfo == null
1299                 || !CompatChanges.isChangeEnabled(ADD_MORE_SMS_SENDING_ERROR_CODES, appInfo.uid)) {
1300             if (rilError == CommandException.Error.INVALID_RESPONSE
1301                     || rilError == CommandException.Error.SIM_PIN2
1302                     || rilError == CommandException.Error.SIM_PUK2
1303                     || rilError == CommandException.Error.SUBSCRIPTION_NOT_AVAILABLE
1304                     || rilError == CommandException.Error.SIM_ERR
1305                     || rilError == CommandException.Error.INVALID_SIM_STATE
1306                     || rilError == CommandException.Error.NO_SMS_TO_ACK
1307                     || rilError == CommandException.Error.SIM_BUSY
1308                     || rilError == CommandException.Error.SIM_FULL
1309                     || rilError == CommandException.Error.NO_SUBSCRIPTION
1310                     || rilError == CommandException.Error.NO_NETWORK_FOUND
1311                     || rilError == CommandException.Error.DEVICE_IN_USE
1312                     || rilError == CommandException.Error.ABORTED) {
1313                 return SmsManager.RESULT_ERROR_GENERIC_FAILURE;
1314             }
1315         }
1316 
1317         switch (rilError) {
1318             case RADIO_NOT_AVAILABLE:
1319                 return SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE;
1320             case SMS_FAIL_RETRY:
1321                 return SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY;
1322             case NETWORK_REJECT:
1323                 return SmsManager.RESULT_RIL_NETWORK_REJECT;
1324             case INVALID_STATE:
1325                 return SmsManager.RESULT_RIL_INVALID_STATE;
1326             case INVALID_ARGUMENTS:
1327                 return SmsManager.RESULT_RIL_INVALID_ARGUMENTS;
1328             case NO_MEMORY:
1329                 return SmsManager.RESULT_RIL_NO_MEMORY;
1330             case REQUEST_RATE_LIMITED:
1331                 return SmsManager.RESULT_RIL_REQUEST_RATE_LIMITED;
1332             case INVALID_SMS_FORMAT:
1333                 return SmsManager.RESULT_RIL_INVALID_SMS_FORMAT;
1334             case SYSTEM_ERR:
1335                 return SmsManager.RESULT_RIL_SYSTEM_ERR;
1336             case ENCODING_ERR:
1337                 return SmsManager.RESULT_RIL_ENCODING_ERR;
1338             case MODEM_ERR:
1339                 return SmsManager.RESULT_RIL_MODEM_ERR;
1340             case NETWORK_ERR:
1341                 return SmsManager.RESULT_RIL_NETWORK_ERR;
1342             case INTERNAL_ERR:
1343                 return SmsManager.RESULT_RIL_INTERNAL_ERR;
1344             case REQUEST_NOT_SUPPORTED:
1345                 return SmsManager.RESULT_RIL_REQUEST_NOT_SUPPORTED;
1346             case INVALID_MODEM_STATE:
1347                 return SmsManager.RESULT_RIL_INVALID_MODEM_STATE;
1348             case NETWORK_NOT_READY:
1349                 return SmsManager.RESULT_RIL_NETWORK_NOT_READY;
1350             case OPERATION_NOT_ALLOWED:
1351                 return SmsManager.RESULT_RIL_OPERATION_NOT_ALLOWED;
1352             case NO_RESOURCES:
1353                 return SmsManager.RESULT_RIL_NO_RESOURCES;
1354             case REQUEST_CANCELLED:
1355                 return SmsManager.RESULT_RIL_CANCELLED;
1356             case SIM_ABSENT:
1357                 return SmsManager.RESULT_RIL_SIM_ABSENT;
1358             case FDN_CHECK_FAILURE:
1359                 return SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE;
1360             case SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED:
1361                 return SmsManager.RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED;
1362             case ACCESS_BARRED:
1363                 return SmsManager.RESULT_RIL_ACCESS_BARRED;
1364             case BLOCKED_DUE_TO_CALL:
1365                 return SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL;
1366             case INVALID_SMSC_ADDRESS:
1367                 return SmsManager.RESULT_INVALID_SMSC_ADDRESS;
1368             case INVALID_RESPONSE:
1369                 return SmsManager.RESULT_RIL_INVALID_RESPONSE;
1370             case SIM_PIN2:
1371                 return SmsManager.RESULT_RIL_SIM_PIN2;
1372             case SIM_PUK2:
1373                 return SmsManager.RESULT_RIL_SIM_PUK2;
1374             case SUBSCRIPTION_NOT_AVAILABLE:
1375                 return SmsManager.RESULT_RIL_SUBSCRIPTION_NOT_AVAILABLE;
1376             case SIM_ERR:
1377                 return SmsManager.RESULT_RIL_SIM_ERROR;
1378             case INVALID_SIM_STATE:
1379                 return SmsManager.RESULT_RIL_INVALID_SIM_STATE;
1380             case NO_SMS_TO_ACK:
1381                 return SmsManager.RESULT_RIL_NO_SMS_TO_ACK;
1382             case SIM_BUSY:
1383                 return SmsManager.RESULT_RIL_SIM_BUSY;
1384             case SIM_FULL:
1385                 return SmsManager.RESULT_RIL_SIM_FULL;
1386             case NO_SUBSCRIPTION:
1387                 return SmsManager.RESULT_RIL_NO_SUBSCRIPTION;
1388             case NO_NETWORK_FOUND:
1389                 return SmsManager.RESULT_RIL_NO_NETWORK_FOUND;
1390             case DEVICE_IN_USE:
1391                 return SmsManager.RESULT_RIL_DEVICE_IN_USE;
1392             case ABORTED:
1393                 return SmsManager.RESULT_RIL_ABORTED;
1394             default:
1395                 Rlog.d(TAG, "rilErrorToSmsManagerResult: " + rilError + " "
1396                         + SmsController.formatCrossStackMessageId(tracker.mMessageId));
1397                 return SmsManager.RESULT_RIL_GENERIC_ERROR;
1398         }
1399     }
1400 
1401     /**
1402      * @param ss service state
1403      * @return The result error based on input service state for not in service error
1404      */
1405     @SmsManager.Result
getNotInServiceError(int ss)1406     protected static int getNotInServiceError(int ss) {
1407         if (ss == ServiceState.STATE_POWER_OFF) {
1408             return SmsManager.RESULT_ERROR_RADIO_OFF;
1409         }
1410         return SmsManager.RESULT_ERROR_NO_SERVICE;
1411     }
1412 
1413     /**
1414      * Send a data based SMS to a specific application port.
1415      *
1416      * @param callingPackage the package name of the calling app
1417      * @param destAddr the address to send the message to
1418      * @param scAddr is the service center address or null to use
1419      *  the current default SMSC
1420      * @param destPort the port to deliver the message to
1421      * @param data the body of the message to send
1422      * @param sentIntent if not NULL this <code>PendingIntent</code> is
1423      *  broadcast when the message is successfully sent, or failed.
1424      *  The result code will be <code>Activity.RESULT_OK<code> for success,
1425      *  or one of these errors:<br>
1426      *  <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code><br>
1427      *  <code>SmsManager.RESULT_ERROR_RADIO_OFF</code><br>
1428      *  <code>SmsManager.RESULT_ERROR_NULL_PDU</code><br>
1429      *  <code>SmsManager.RESULT_ERROR_NO_SERVICE</code><br>
1430      *  <code>SmsManager.RESULT_ERROR_LIMIT_EXCEEDED</code><br>
1431      *  <code>SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
1432      *  <code>SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
1433      *  <code>SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
1434      *  <code>SmsManager.RESULT_RADIO_NOT_AVAILABLE</code><br>
1435      *  <code>SmsManager.RESULT_NETWORK_REJECT</code><br>
1436      *  <code>SmsManager.RESULT_INVALID_ARGUMENTS</code><br>
1437      *  <code>SmsManager.RESULT_INVALID_STATE</code><br>
1438      *  <code>SmsManager.RESULT_NO_MEMORY</code><br>
1439      *  <code>SmsManager.RESULT_INVALID_SMS_FORMAT</code><br>
1440      *  <code>SmsManager.RESULT_SYSTEM_ERROR</code><br>
1441      *  <code>SmsManager.RESULT_MODEM_ERROR</code><br>
1442      *  <code>SmsManager.RESULT_NETWORK_ERROR</code><br>
1443      *  <code>SmsManager.RESULT_ENCODING_ERROR</code><br>
1444      *  <code>SmsManager.RESULT_INVALID_SMSC_ADDRESS</code><br>
1445      *  <code>SmsManager.RESULT_OPERATION_NOT_ALLOWED</code><br>
1446      *  <code>SmsManager.RESULT_INTERNAL_ERROR</code><br>
1447      *  <code>SmsManager.RESULT_NO_RESOURCES</code><br>
1448      *  <code>SmsManager.RESULT_CANCELLED</code><br>
1449      *  <code>SmsManager.RESULT_REQUEST_NOT_SUPPORTED</code><br>
1450      *  <code>SmsManager.RESULT_NO_BLUETOOTH_SERVICE</code><br>
1451      *  <code>SmsManager.RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
1452      *  <code>SmsManager.RESULT_BLUETOOTH_DISCONNECTED</code><br>
1453      *  <code>SmsManager.RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
1454      *  <code>SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
1455      *  <code>SmsManager.RESULT_SMS_SEND_RETRY_FAILED</code><br>
1456      *  <code>SmsManager.RESULT_REMOTE_EXCEPTION</code><br>
1457      *  <code>SmsManager.RESULT_NO_DEFAULT_SMS_APP</code><br>
1458      *  <code>SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
1459      *  <code>SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
1460      *  <code>SmsManager.RESULT_RIL_NETWORK_REJECT</code><br>
1461      *  <code>SmsManager.RESULT_RIL_INVALID_STATE</code><br>
1462      *  <code>SmsManager.RESULT_RIL_INVALID_ARGUMENTS</code><br>
1463      *  <code>SmsManager.RESULT_RIL_NO_MEMORY</code><br>
1464      *  <code>SmsManager.RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
1465      *  <code>SmsManager.RESULT_RIL_INVALID_SMS_FORMAT</code><br>
1466      *  <code>SmsManager.RESULT_RIL_SYSTEM_ERR</code><br>
1467      *  <code>SmsManager.RESULT_RIL_ENCODING_ERR</code><br>
1468      *  <code>SmsManager.RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
1469      *  <code>SmsManager.RESULT_RIL_MODEM_ERR</code><br>
1470      *  <code>SmsManager.RESULT_RIL_NETWORK_ERR</code><br>
1471      *  <code>SmsManager.RESULT_RIL_INTERNAL_ERR</code><br>
1472      *  <code>SmsManager.RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
1473      *  <code>SmsManager.RESULT_RIL_INVALID_MODEM_STATE</code><br>
1474      *  <code>SmsManager.RESULT_RIL_NETWORK_NOT_READY</code><br>
1475      *  <code>SmsManager.RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
1476      *  <code>SmsManager.RESULT_RIL_NO_RESOURCES</code><br>
1477      *  <code>SmsManager.RESULT_RIL_CANCELLED</code><br>
1478      *  <code>SmsManager.RESULT_RIL_SIM_ABSENT</code><br>
1479      *  <code>SmsManager.RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
1480      *  <code>SmsManager.RESULT_RIL_ACCESS_BARRED</code><br>
1481      *  <code>SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
1482      *  For <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
1483      *  the sentIntent may include the extra "errorCode" containing a radio technology specific
1484      *  value, generally only useful for troubleshooting.<br>
1485      *  The per-application based SMS control checks sentIntent. If sentIntent
1486      *  is NULL the caller will be checked against all unknown applications,
1487      *  which cause smaller number of SMS to be sent in checking period.
1488      * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
1489      *  broadcast when the message is delivered to the recipient.  The
1490      *  raw pdu of the status report is in the extended data ("pdu").
1491      */
1492     @UnsupportedAppUsage
sendData(String callingPackage, int callingUser, String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean isForVvm, long uniqueMessageId)1493     protected void sendData(String callingPackage, int callingUser, String destAddr, String scAddr,
1494             int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent,
1495             boolean isForVvm, long uniqueMessageId) {
1496         int messageRef = nextMessageRef();
1497         SmsMessageBase.SubmitPduBase pdu = getSubmitPdu(
1498                 scAddr, destAddr, destPort, data, (deliveryIntent != null), messageRef);
1499         if (pdu != null) {
1500             HashMap map = getSmsTrackerMap(destAddr, scAddr, destPort, data, pdu);
1501             SmsTracker tracker = getSmsTracker(callingPackage, callingUser, map, sentIntent,
1502                     deliveryIntent, getFormat(), null /*messageUri*/, false /*expectMore*/,
1503                     null /*fullMessageText*/, false /*isText*/,
1504                     true /*persistMessage*/, isForVvm, 0L /* messageId */, messageRef,
1505                     uniqueMessageId);
1506 
1507             if (!sendSmsByCarrierApp(true /* isDataSms */, tracker)) {
1508                 sendSubmitPdu(tracker);
1509             }
1510         } else {
1511             Rlog.e(TAG, "SMSDispatcher.sendData(): getSubmitPdu() returned null");
1512             triggerSentIntentForFailure(sentIntent);
1513         }
1514     }
1515 
1516     /**
1517      * Send a text based SMS.
1518      *
1519      * @param destAddr the address to send the message to
1520      * @param scAddr is the service center address or null to use
1521      *  the current default SMSC
1522      * @param text the body of the message to send
1523      * @param sentIntent if not NULL this <code>PendingIntent</code> is
1524      *  broadcast when the message is successfully sent, or failed.
1525      *  The result code will be <code>Activity.RESULT_OK<code> for success,
1526      *  or one of these errors:<br>
1527      *  <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code><br>
1528      *  <code>SmsManager.RESULT_ERROR_RADIO_OFF</code><br>
1529      *  <code>SmsManager.RESULT_ERROR_NULL_PDU</code><br>
1530      *  <code>SmsManager.RESULT_ERROR_NO_SERVICE</code><br>
1531      *  <code>SmsManager.RESULT_ERROR_LIMIT_EXCEEDED</code><br>
1532      *  <code>SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
1533      *  <code>SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
1534      *  <code>SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
1535      *  <code>SmsManager.RESULT_RADIO_NOT_AVAILABLE</code><br>
1536      *  <code>SmsManager.RESULT_NETWORK_REJECT</code><br>
1537      *  <code>SmsManager.RESULT_INVALID_ARGUMENTS</code><br>
1538      *  <code>SmsManager.RESULT_INVALID_STATE</code><br>
1539      *  <code>SmsManager.RESULT_NO_MEMORY</code><br>
1540      *  <code>SmsManager.RESULT_INVALID_SMS_FORMAT</code><br>
1541      *  <code>SmsManager.RESULT_SYSTEM_ERROR</code><br>
1542      *  <code>SmsManager.RESULT_MODEM_ERROR</code><br>
1543      *  <code>SmsManager.RESULT_NETWORK_ERROR</code><br>
1544      *  <code>SmsManager.RESULT_ENCODING_ERROR</code><br>
1545      *  <code>SmsManager.RESULT_INVALID_SMSC_ADDRESS</code><br>
1546      *  <code>SmsManager.RESULT_OPERATION_NOT_ALLOWED</code><br>
1547      *  <code>SmsManager.RESULT_INTERNAL_ERROR</code><br>
1548      *  <code>SmsManager.RESULT_NO_RESOURCES</code><br>
1549      *  <code>SmsManager.RESULT_CANCELLED</code><br>
1550      *  <code>SmsManager.RESULT_REQUEST_NOT_SUPPORTED</code><br>
1551      *  <code>SmsManager.RESULT_NO_BLUETOOTH_SERVICE</code><br>
1552      *  <code>SmsManager.RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
1553      *  <code>SmsManager.RESULT_BLUETOOTH_DISCONNECTED</code><br>
1554      *  <code>SmsManager.RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
1555      *  <code>SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
1556      *  <code>SmsManager.RESULT_SMS_SEND_RETRY_FAILED</code><br>
1557      *  <code>SmsManager.RESULT_REMOTE_EXCEPTION</code><br>
1558      *  <code>SmsManager.RESULT_NO_DEFAULT_SMS_APP</code><br>
1559      *  <code>SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
1560      *  <code>SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
1561      *  <code>SmsManager.RESULT_RIL_NETWORK_REJECT</code><br>
1562      *  <code>SmsManager.RESULT_RIL_INVALID_STATE</code><br>
1563      *  <code>SmsManager.RESULT_RIL_INVALID_ARGUMENTS</code><br>
1564      *  <code>SmsManager.RESULT_RIL_NO_MEMORY</code><br>
1565      *  <code>SmsManager.RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
1566      *  <code>SmsManager.RESULT_RIL_INVALID_SMS_FORMAT</code><br>
1567      *  <code>SmsManager.RESULT_RIL_SYSTEM_ERR</code><br>
1568      *  <code>SmsManager.RESULT_RIL_ENCODING_ERR</code><br>
1569      *  <code>SmsManager.RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
1570      *  <code>SmsManager.RESULT_RIL_MODEM_ERR</code><br>
1571      *  <code>SmsManager.RESULT_RIL_NETWORK_ERR</code><br>
1572      *  <code>SmsManager.RESULT_RIL_INTERNAL_ERR</code><br>
1573      *  <code>SmsManager.RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
1574      *  <code>SmsManager.RESULT_RIL_INVALID_MODEM_STATE</code><br>
1575      *  <code>SmsManager.RESULT_RIL_NETWORK_NOT_READY</code><br>
1576      *  <code>SmsManager.RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
1577      *  <code>SmsManager.RESULT_RIL_NO_RESOURCES</code><br>
1578      *  <code>SmsManager.RESULT_RIL_CANCELLED</code><br>
1579      *  <code>SmsManager.RESULT_RIL_SIM_ABSENT</code><br>
1580      *  <code>SmsManager.RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
1581      *  <code>SmsManager.RESULT_RIL_ACCESS_BARRED</code><br>
1582      *  <code>SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
1583      *  For <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
1584      *  the sentIntent may include the extra "errorCode" containing a radio technology specific
1585      *  value, generally only useful for troubleshooting.<br>
1586      *  The per-application based SMS control checks sentIntent. If sentIntent
1587      *  is NULL the caller will be checked against all unknown applications,
1588      *  which cause smaller number of SMS to be sent in checking period.
1589      * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
1590      *  broadcast when the message is delivered to the recipient.  The
1591      * @param messageUri optional URI of the message if it is already stored in the system
1592      * @param callingPkg the calling package name
1593      * @param persistMessage whether to save the sent message into SMS DB for a
1594      *  non-default SMS app.
1595      *
1596      * @param priority Priority level of the message
1597      *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
1598      *  ---------------------------------
1599      *  PRIORITY      | Level of Priority
1600      *  ---------------------------------
1601      *      '00'      |     Normal
1602      *      '01'      |     Interactive
1603      *      '10'      |     Urgent
1604      *      '11'      |     Emergency
1605      *  ----------------------------------
1606      *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
1607      * @param expectMore is a boolean to indicate the sending messages through same link or not.
1608      * @param validityPeriod Validity Period of the message in mins.
1609      *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
1610      *  Validity Period(Minimum) -> 5 mins
1611      *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
1612      *  Any Other values included Negative considered as Invalid Validity Period of the message.
1613      * @param messageId An id that uniquely identifies the message requested to be sent.
1614      *                 Used for logging and diagnostics purposes. The id may be NULL.
1615      */
sendText(String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, Uri messageUri, String callingPkg, int callingUser, boolean persistMessage, int priority, boolean expectMore, int validityPeriod, boolean isForVvm, long messageId)1616     public void sendText(String destAddr, String scAddr, String text,
1617             PendingIntent sentIntent, PendingIntent deliveryIntent, Uri messageUri,
1618             String callingPkg, int callingUser, boolean persistMessage, int priority,
1619             boolean expectMore, int validityPeriod, boolean isForVvm,
1620             long messageId) {
1621         sendText(destAddr, scAddr, text, sentIntent, deliveryIntent, messageUri, callingPkg,
1622                 callingUser, persistMessage, priority, expectMore, validityPeriod, isForVvm,
1623                 messageId, false, PendingRequest.getNextUniqueMessageId());
1624     }
1625 
1626     /**
1627      * Send a text based SMS.
1628      *
1629      * @param destAddr the address to send the message to
1630      * @param scAddr is the service center address or null to use
1631      *  the current default SMSC
1632      * @param text the body of the message to send
1633      * @param sentIntent if not NULL this <code>PendingIntent</code> is
1634      *  broadcast when the message is successfully sent, or failed.
1635      *  The result code will be <code>Activity.RESULT_OK<code> for success,
1636      *  or one of these errors:<br>
1637      *  <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code><br>
1638      *  <code>SmsManager.RESULT_ERROR_RADIO_OFF</code><br>
1639      *  <code>SmsManager.RESULT_ERROR_NULL_PDU</code><br>
1640      *  <code>SmsManager.RESULT_ERROR_NO_SERVICE</code><br>
1641      *  <code>SmsManager.RESULT_ERROR_LIMIT_EXCEEDED</code><br>
1642      *  <code>SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
1643      *  <code>SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
1644      *  <code>SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
1645      *  <code>SmsManager.RESULT_RADIO_NOT_AVAILABLE</code><br>
1646      *  <code>SmsManager.RESULT_NETWORK_REJECT</code><br>
1647      *  <code>SmsManager.RESULT_INVALID_ARGUMENTS</code><br>
1648      *  <code>SmsManager.RESULT_INVALID_STATE</code><br>
1649      *  <code>SmsManager.RESULT_NO_MEMORY</code><br>
1650      *  <code>SmsManager.RESULT_INVALID_SMS_FORMAT</code><br>
1651      *  <code>SmsManager.RESULT_SYSTEM_ERROR</code><br>
1652      *  <code>SmsManager.RESULT_MODEM_ERROR</code><br>
1653      *  <code>SmsManager.RESULT_NETWORK_ERROR</code><br>
1654      *  <code>SmsManager.RESULT_ENCODING_ERROR</code><br>
1655      *  <code>SmsManager.RESULT_INVALID_SMSC_ADDRESS</code><br>
1656      *  <code>SmsManager.RESULT_OPERATION_NOT_ALLOWED</code><br>
1657      *  <code>SmsManager.RESULT_INTERNAL_ERROR</code><br>
1658      *  <code>SmsManager.RESULT_NO_RESOURCES</code><br>
1659      *  <code>SmsManager.RESULT_CANCELLED</code><br>
1660      *  <code>SmsManager.RESULT_REQUEST_NOT_SUPPORTED</code><br>
1661      *  <code>SmsManager.RESULT_NO_BLUETOOTH_SERVICE</code><br>
1662      *  <code>SmsManager.RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
1663      *  <code>SmsManager.RESULT_BLUETOOTH_DISCONNECTED</code><br>
1664      *  <code>SmsManager.RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
1665      *  <code>SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
1666      *  <code>SmsManager.RESULT_SMS_SEND_RETRY_FAILED</code><br>
1667      *  <code>SmsManager.RESULT_REMOTE_EXCEPTION</code><br>
1668      *  <code>SmsManager.RESULT_NO_DEFAULT_SMS_APP</code><br>
1669      *  <code>SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
1670      *  <code>SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
1671      *  <code>SmsManager.RESULT_RIL_NETWORK_REJECT</code><br>
1672      *  <code>SmsManager.RESULT_RIL_INVALID_STATE</code><br>
1673      *  <code>SmsManager.RESULT_RIL_INVALID_ARGUMENTS</code><br>
1674      *  <code>SmsManager.RESULT_RIL_NO_MEMORY</code><br>
1675      *  <code>SmsManager.RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
1676      *  <code>SmsManager.RESULT_RIL_INVALID_SMS_FORMAT</code><br>
1677      *  <code>SmsManager.RESULT_RIL_SYSTEM_ERR</code><br>
1678      *  <code>SmsManager.RESULT_RIL_ENCODING_ERR</code><br>
1679      *  <code>SmsManager.RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
1680      *  <code>SmsManager.RESULT_RIL_MODEM_ERR</code><br>
1681      *  <code>SmsManager.RESULT_RIL_NETWORK_ERR</code><br>
1682      *  <code>SmsManager.RESULT_RIL_INTERNAL_ERR</code><br>
1683      *  <code>SmsManager.RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
1684      *  <code>SmsManager.RESULT_RIL_INVALID_MODEM_STATE</code><br>
1685      *  <code>SmsManager.RESULT_RIL_NETWORK_NOT_READY</code><br>
1686      *  <code>SmsManager.RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
1687      *  <code>SmsManager.RESULT_RIL_NO_RESOURCES</code><br>
1688      *  <code>SmsManager.RESULT_RIL_CANCELLED</code><br>
1689      *  <code>SmsManager.RESULT_RIL_SIM_ABSENT</code><br>
1690      *  <code>SmsManager.RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
1691      *  <code>SmsManager.RESULT_RIL_ACCESS_BARRED</code><br>
1692      *  <code>SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
1693      *  For <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
1694      *  the sentIntent may include the extra "errorCode" containing a radio technology specific
1695      *  value, generally only useful for troubleshooting.<br>
1696      *  The per-application based SMS control checks sentIntent. If sentIntent
1697      *  is NULL the caller will be checked against all unknown applications,
1698      *  which cause smaller number of SMS to be sent in checking period.
1699      * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
1700      *  broadcast when the message is delivered to the recipient.  The
1701      * @param messageUri optional URI of the message if it is already stored in the system
1702      * @param callingPkg the calling package name
1703      * @param persistMessage whether to save the sent message into SMS DB for a
1704      *  non-default SMS app.
1705      *
1706      * @param priority Priority level of the message
1707      *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
1708      *  ---------------------------------
1709      *  PRIORITY      | Level of Priority
1710      *  ---------------------------------
1711      *      '00'      |     Normal
1712      *      '01'      |     Interactive
1713      *      '10'      |     Urgent
1714      *      '11'      |     Emergency
1715      *  ----------------------------------
1716      *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
1717      * @param expectMore is a boolean to indicate the sending messages through same link or not.
1718      * @param validityPeriod Validity Period of the message in mins.
1719      *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
1720      *  Validity Period(Minimum) -> 5 mins
1721      *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
1722      *  Any Other values included Negative considered as Invalid Validity Period of the message.
1723      * @param messageId An id that uniquely identifies the message requested to be sent.
1724      *                 Used for logging and diagnostics purposes. The id may be NULL.
1725      * @param skipShortCodeCheck Skip check for short code type destination address.
1726      */
sendText(String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, Uri messageUri, String callingPkg, int callingUser, boolean persistMessage, int priority, boolean expectMore, int validityPeriod, boolean isForVvm, long messageId, boolean skipShortCodeCheck, long uniqueMessageId)1727     public void sendText(String destAddr, String scAddr, String text,
1728             PendingIntent sentIntent, PendingIntent deliveryIntent, Uri messageUri,
1729             String callingPkg, int callingUser, boolean persistMessage, int priority,
1730             boolean expectMore, int validityPeriod, boolean isForVvm,
1731             long messageId, boolean skipShortCodeCheck, long uniqueMessageId) {
1732         Rlog.d(TAG, "sendText id: " + SmsController.formatCrossStackMessageId(messageId));
1733         int messageRef = nextMessageRef();
1734         SmsMessageBase.SubmitPduBase pdu = getSubmitPdu(
1735                 scAddr, destAddr, text, (deliveryIntent != null), null, priority, validityPeriod,
1736                 messageRef);
1737         if (pdu != null) {
1738             HashMap map = getSmsTrackerMap(destAddr, scAddr, text, pdu);
1739             SmsTracker tracker = getSmsTracker(callingPkg, callingUser, map, sentIntent,
1740                     deliveryIntent, getFormat(), messageUri, expectMore, text, true /*isText*/,
1741                     persistMessage, priority, validityPeriod, isForVvm, messageId, messageRef,
1742                     skipShortCodeCheck, uniqueMessageId);
1743 
1744             if (!sendSmsByCarrierApp(false /* isDataSms */, tracker)) {
1745                 sendSubmitPdu(tracker);
1746             }
1747         } else {
1748             Rlog.e(TAG, "SmsDispatcher.sendText(): getSubmitPdu() returned null "
1749                     + SmsController.formatCrossStackMessageId(messageId));
1750             triggerSentIntentForFailure(sentIntent);
1751         }
1752     }
1753 
triggerSentIntentForFailure(PendingIntent sentIntent)1754     private void triggerSentIntentForFailure(PendingIntent sentIntent) {
1755         if (sentIntent != null) {
1756             try {
1757                 sentIntent.send(SmsManager.RESULT_ERROR_GENERIC_FAILURE);
1758             } catch (CanceledException ex) {
1759                 Rlog.e(TAG, "Intent has been canceled!");
1760             }
1761         }
1762     }
1763 
triggerSentIntentForFailure(List<PendingIntent> sentIntents)1764     private void triggerSentIntentForFailure(List<PendingIntent> sentIntents) {
1765         if (sentIntents == null) {
1766             return;
1767         }
1768 
1769         for (PendingIntent sentIntent : sentIntents) {
1770             triggerSentIntentForFailure(sentIntent);
1771         }
1772     }
1773 
sendSmsByCarrierApp(boolean isDataSms, SmsTracker tracker )1774     private boolean sendSmsByCarrierApp(boolean isDataSms, SmsTracker tracker ) {
1775         String carrierPackage = getCarrierAppPackageName();
1776         if (carrierPackage != null) {
1777             Rlog.d(TAG, "Found carrier package " + carrierPackage);
1778             SmsSender smsSender;
1779             if (isDataSms) {
1780                 smsSender = new DataSmsSender(tracker);
1781             } else {
1782                 smsSender = new TextSmsSender(tracker);
1783             }
1784             smsSender.sendSmsByCarrierApp(carrierPackage, new SmsSenderCallback(smsSender));
1785             return true;
1786         }
1787 
1788         return false;
1789     }
1790 
getSubmitPdu(String scAddr, String destAddr, String message, boolean statusReportRequested, SmsHeader smsHeader, int priority, int validityPeriod)1791     protected abstract SmsMessageBase.SubmitPduBase getSubmitPdu(String scAddr, String destAddr,
1792             String message, boolean statusReportRequested, SmsHeader smsHeader,
1793             int priority, int validityPeriod);
1794 
getSubmitPdu(String scAddr, String destAddr, int destPort, byte[] message, boolean statusReportRequested)1795     protected abstract SmsMessageBase.SubmitPduBase getSubmitPdu(String scAddr, String destAddr,
1796             int destPort, byte[] message, boolean statusReportRequested);
1797 
getSubmitPdu(String scAddr, String destAddr, String message, boolean statusReportRequested, SmsHeader smsHeader, int priority, int validityPeriod, int messageRef)1798     protected abstract SmsMessageBase.SubmitPduBase getSubmitPdu(String scAddr, String destAddr,
1799             String message, boolean statusReportRequested, SmsHeader smsHeader,
1800             int priority, int validityPeriod, int messageRef);
1801 
1802 
getSubmitPdu(String scAddr, String destAddr, int destPort, byte[] message, boolean statusReportRequested, int messageRef)1803     protected abstract SmsMessageBase.SubmitPduBase getSubmitPdu(String scAddr, String destAddr,
1804             int destPort, byte[] message, boolean statusReportRequested, int messageRef);
1805 
1806     /**
1807      * Calculate the number of septets needed to encode the message. This function should only be
1808      * called for individual segments of multipart message.
1809      *
1810      * @param messageBody the message to encode
1811      * @param use7bitOnly ignore (but still count) illegal characters if true
1812      * @return TextEncodingDetails
1813      */
1814     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
calculateLength(CharSequence messageBody, boolean use7bitOnly)1815     protected abstract TextEncodingDetails calculateLength(CharSequence messageBody,
1816             boolean use7bitOnly);
1817 
1818     /**
1819      * Send a multi-part text based SMS.
1820      *
1821      * @param destAddr the address to send the message to
1822      * @param scAddr is the service center address or null to use
1823      *  the current default SMSC
1824      * @param parts an <code>ArrayList</code> of strings that, in order,
1825      *  comprise the original message
1826      * @param sentIntents if not null, an <code>ArrayList</code> of
1827      *  <code>PendingIntent</code>s (one for each message part) that is
1828      *  broadcast when the corresponding message part has been sent.
1829      *  The result code will be <code>Activity.RESULT_OK<code> for success,
1830      *  or one of these errors:
1831      *  <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code><br>
1832      *  <code>SmsManager.RESULT_ERROR_RADIO_OFF</code><br>
1833      *  <code>SmsManager.RESULT_ERROR_NULL_PDU</code><br>
1834      *  <code>SmsManager.RESULT_ERROR_NO_SERVICE</code><br>
1835      *  <code>SmsManager.RESULT_ERROR_LIMIT_EXCEEDED</code><br>
1836      *  <code>SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
1837      *  <code>SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
1838      *  <code>SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
1839      *  <code>SmsManager.RESULT_RADIO_NOT_AVAILABLE</code><br>
1840      *  <code>SmsManager.RESULT_NETWORK_REJECT</code><br>
1841      *  <code>SmsManager.RESULT_INVALID_ARGUMENTS</code><br>
1842      *  <code>SmsManager.RESULT_INVALID_STATE</code><br>
1843      *  <code>SmsManager.RESULT_NO_MEMORY</code><br>
1844      *  <code>SmsManager.RESULT_INVALID_SMS_FORMAT</code><br>
1845      *  <code>SmsManager.RESULT_SYSTEM_ERROR</code><br>
1846      *  <code>SmsManager.RESULT_MODEM_ERROR</code><br>
1847      *  <code>SmsManager.RESULT_NETWORK_ERROR</code><br>
1848      *  <code>SmsManager.RESULT_ENCODING_ERROR</code><br>
1849      *  <code>SmsManager.RESULT_INVALID_SMSC_ADDRESS</code><br>
1850      *  <code>SmsManager.RESULT_OPERATION_NOT_ALLOWED</code><br>
1851      *  <code>SmsManager.RESULT_INTERNAL_ERROR</code><br>
1852      *  <code>SmsManager.RESULT_NO_RESOURCES</code><br>
1853      *  <code>SmsManager.RESULT_CANCELLED</code><br>
1854      *  <code>SmsManager.RESULT_REQUEST_NOT_SUPPORTED</code><br>
1855      *  <code>SmsManager.RESULT_NO_BLUETOOTH_SERVICE</code><br>
1856      *  <code>SmsManager.RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
1857      *  <code>SmsManager.RESULT_BLUETOOTH_DISCONNECTED</code><br>
1858      *  <code>SmsManager.RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
1859      *  <code>SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
1860      *  <code>SmsManager.RESULT_SMS_SEND_RETRY_FAILED</code><br>
1861      *  <code>SmsManager.RESULT_REMOTE_EXCEPTION</code><br>
1862      *  <code>SmsManager.RESULT_NO_DEFAULT_SMS_APP</code><br>
1863      *  <code>SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
1864      *  <code>SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
1865      *  <code>SmsManager.RESULT_RIL_NETWORK_REJECT</code><br>
1866      *  <code>SmsManager.RESULT_RIL_INVALID_STATE</code><br>
1867      *  <code>SmsManager.RESULT_RIL_INVALID_ARGUMENTS</code><br>
1868      *  <code>SmsManager.RESULT_RIL_NO_MEMORY</code><br>
1869      *  <code>SmsManager.RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
1870      *  <code>SmsManager.RESULT_RIL_INVALID_SMS_FORMAT</code><br>
1871      *  <code>SmsManager.RESULT_RIL_SYSTEM_ERR</code><br>
1872      *  <code>SmsManager.RESULT_RIL_ENCODING_ERR</code><br>
1873      *  <code>SmsManager.RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
1874      *  <code>SmsManager.RESULT_RIL_MODEM_ERR</code><br>
1875      *  <code>SmsManager.RESULT_RIL_NETWORK_ERR</code><br>
1876      *  <code>SmsManager.RESULT_RIL_INTERNAL_ERR</code><br>
1877      *  <code>SmsManager.RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
1878      *  <code>SmsManager.RESULT_RIL_INVALID_MODEM_STATE</code><br>
1879      *  <code>SmsManager.RESULT_RIL_NETWORK_NOT_READY</code><br>
1880      *  <code>SmsManager.RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
1881      *  <code>SmsManager.RESULT_RIL_NO_RESOURCES</code><br>
1882      *  <code>SmsManager.RESULT_RIL_CANCELLED</code><br>
1883      *  <code>SmsManager.RESULT_RIL_SIM_ABSENT</code><br>
1884      *  <code>SmsManager.RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
1885      *  <code>SmsManager.RESULT_RIL_ACCESS_BARRED</code><br>
1886      *  <code>SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
1887      *  For <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
1888      *  the sentIntent may include the extra "errorCode" containing a radio technology specific
1889      *  value, generally only useful for troubleshooting.<br>
1890      *  The per-application based SMS control checks sentIntent. If sentIntent
1891      *  is NULL the caller will be checked against all unknown applications,
1892      *  which cause smaller number of SMS to be sent in checking period.
1893      * @param deliveryIntents if not null, an <code>ArrayList</code> of
1894      *  <code>PendingIntent</code>s (one for each message part) that is
1895      *  broadcast when the corresponding message part has been delivered
1896      *  to the recipient.  The raw pdu of the status report is in the
1897      * @param messageUri optional URI of the message if it is already stored in the system
1898      * @param callingPkg the calling package name
1899      * @param persistMessage whether to save the sent message into SMS DB for a
1900      *   non-default SMS app.
1901      * @param priority Priority level of the message
1902      *  Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1
1903      *  ---------------------------------
1904      *  PRIORITY      | Level of Priority
1905      *  ---------------------------------
1906      *      '00'      |     Normal
1907      *      '01'      |     Interactive
1908      *      '10'      |     Urgent
1909      *      '11'      |     Emergency
1910      *  ----------------------------------
1911      *  Any Other values included Negative considered as Invalid Priority Indicator of the message.
1912      * @param expectMore is a boolean to indicate the sending messages through same link or not.
1913      * @param validityPeriod Validity Period of the message in mins.
1914      *  Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
1915      *  Validity Period(Minimum) -> 5 mins
1916      *  Validity Period(Maximum) -> 635040 mins(i.e.63 weeks).
1917      *  Any Other values included Negative considered as Invalid Validity Period of the message.
1918      */
1919     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
sendMultipartText(String destAddr, String scAddr, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents, Uri messageUri, String callingPkg, int callingUser, boolean persistMessage, int priority, boolean expectMore, int validityPeriod, long messageId, long uniqueMessageId)1920     public void sendMultipartText(String destAddr, String scAddr,
1921             ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
1922             ArrayList<PendingIntent> deliveryIntents, Uri messageUri, String callingPkg,
1923             int callingUser, boolean persistMessage, int priority, boolean expectMore,
1924             int validityPeriod, long messageId, long uniqueMessageId) {
1925         final String fullMessageText = getMultipartMessageText(parts);
1926         int refNumber = getNextConcatenatedRef() & 0x00FF;
1927         int encoding = SmsConstants.ENCODING_UNKNOWN;
1928         int msgCount = parts.size();
1929         if (msgCount < 1) {
1930             triggerSentIntentForFailure(sentIntents);
1931             return;
1932         }
1933 
1934         TextEncodingDetails[] encodingForParts = new TextEncodingDetails[msgCount];
1935         for (int i = 0; i < msgCount; i++) {
1936             TextEncodingDetails details = calculateLength(parts.get(i), false);
1937             if (encoding != details.codeUnitSize
1938                     && (encoding == SmsConstants.ENCODING_UNKNOWN
1939                             || encoding == SmsConstants.ENCODING_7BIT)) {
1940                 encoding = details.codeUnitSize;
1941             }
1942             encodingForParts[i] = details;
1943         }
1944 
1945         SmsTracker[] trackers = new SmsTracker[msgCount];
1946 
1947         // States to track at the message level (for all parts)
1948         final AtomicInteger unsentPartCount = new AtomicInteger(msgCount);
1949         final AtomicBoolean anyPartFailed = new AtomicBoolean(false);
1950 
1951         for (int i = 0; i < msgCount; i++) {
1952             SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
1953             concatRef.refNumber = refNumber;
1954             concatRef.seqNumber = i + 1;  // 1-based sequence
1955             concatRef.msgCount = msgCount;
1956             // TODO: We currently set this to true since our messaging app will never
1957             // send more than 255 parts (it converts the message to MMS well before that).
1958             // However, we should support 3rd party messaging apps that might need 16-bit
1959             // references
1960             // Note:  It's not sufficient to just flip this bit to true; it will have
1961             // ripple effects (several calculations assume 8-bit ref).
1962             concatRef.isEightBits = true;
1963             SmsHeader smsHeader = new SmsHeader();
1964             smsHeader.concatRef = concatRef;
1965 
1966             // Set the national language tables for 3GPP 7-bit encoding, if enabled.
1967             if (encoding == SmsConstants.ENCODING_7BIT) {
1968                 smsHeader.languageTable = encodingForParts[i].languageTable;
1969                 smsHeader.languageShiftTable = encodingForParts[i].languageShiftTable;
1970             }
1971 
1972             PendingIntent sentIntent = null;
1973             if (sentIntents != null && sentIntents.size() > i) {
1974                 sentIntent = sentIntents.get(i);
1975             }
1976 
1977             PendingIntent deliveryIntent = null;
1978             if (deliveryIntents != null && deliveryIntents.size() > i) {
1979                 deliveryIntent = deliveryIntents.get(i);
1980             }
1981             int messageRef = nextMessageRef();
1982             trackers[i] =
1983                 getNewSubmitPduTracker(callingPkg, callingUser, destAddr, scAddr, parts.get(i),
1984                         smsHeader, encoding, sentIntent, deliveryIntent, (i == (msgCount - 1)),
1985                         unsentPartCount, anyPartFailed, messageUri,
1986                         fullMessageText, priority, expectMore, validityPeriod, messageId,
1987                         messageRef, uniqueMessageId);
1988             if (trackers[i] == null) {
1989                 triggerSentIntentForFailure(sentIntents);
1990                 return;
1991             }
1992             trackers[i].mPersistMessage = persistMessage;
1993         }
1994 
1995         String carrierPackage = getCarrierAppPackageName();
1996         if (carrierPackage != null) {
1997             Rlog.d(TAG, "Found carrier package " + carrierPackage + " "
1998                     + SmsController.formatCrossStackMessageId(getMultiTrackermessageId(trackers)));
1999             MultipartSmsSender smsSender = new MultipartSmsSender(parts, trackers);
2000             smsSender.sendSmsByCarrierApp(carrierPackage, new SmsSenderCallback(smsSender));
2001         } else {
2002             Rlog.v(TAG, "No carrier package. "
2003                     + SmsController.formatCrossStackMessageId(getMultiTrackermessageId(trackers)));
2004             sendSubmitPdu(trackers);
2005         }
2006     }
2007 
getMultiTrackermessageId(SmsTracker[] trackers)2008     private long getMultiTrackermessageId(SmsTracker[] trackers) {
2009         if (trackers.length == 0) {
2010             return 0L;
2011         }
2012         return trackers[0].mMessageId;
2013     }
2014 
2015     /**
2016      * Create a new SubmitPdu and return the SMS tracker.
2017      */
getNewSubmitPduTracker(String callingPackage, int callingUser, String destinationAddress, String scAddress, String message, SmsHeader smsHeader, int encoding, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart, AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri, String fullMessageText, int priority, boolean expectMore, int validityPeriod, long messageId, int messageRef, long uniqueMessageId)2018     private SmsTracker getNewSubmitPduTracker(String callingPackage, int callingUser,
2019             String destinationAddress, String scAddress, String message, SmsHeader smsHeader,
2020             int encoding, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart,
2021             AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri,
2022             String fullMessageText, int priority, boolean expectMore, int validityPeriod,
2023             long messageId, int messageRef, long uniqueMessageId) {
2024         if (isCdmaMo()) {
2025             UserData uData = new UserData();
2026             uData.payloadStr = message;
2027             uData.userDataHeader = smsHeader;
2028             if (encoding == SmsConstants.ENCODING_7BIT) {
2029                 uData.msgEncoding = isAscii7bitSupportedForLongMessage()
2030                         ? UserData.ENCODING_7BIT_ASCII : UserData.ENCODING_GSM_7BIT_ALPHABET;
2031                 Rlog.d(TAG, "Message encoding for proper 7 bit: " + uData.msgEncoding);
2032             } else { // assume UTF-16
2033                 uData.msgEncoding = UserData.ENCODING_UNICODE_16;
2034             }
2035             uData.msgEncodingSet = true;
2036 
2037             /* By setting the statusReportRequested bit only for the
2038              * last message fragment, this will result in only one
2039              * callback to the sender when that last fragment delivery
2040              * has been acknowledged. */
2041             //TODO FIX
2042             SmsMessageBase.SubmitPduBase submitPdu =
2043                     com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(destinationAddress,
2044                             uData, (deliveryIntent != null) && lastPart, priority);
2045 
2046             if (submitPdu != null) {
2047                 HashMap map = getSmsTrackerMap(destinationAddress, scAddress,
2048                         message, submitPdu);
2049                 return getSmsTracker(callingPackage, callingUser, map, sentIntent,
2050                         deliveryIntent, getFormat(), unsentPartCount, anyPartFailed, messageUri,
2051                         smsHeader, (!lastPart || expectMore), fullMessageText,  /*isText*/
2052                         true,  /*persistMessage*/ true, priority, validityPeriod,  /* isForVvm */
2053                         false, messageId, messageRef, false, uniqueMessageId);
2054             } else {
2055                 Rlog.e(TAG, "CdmaSMSDispatcher.getNewSubmitPduTracker(): getSubmitPdu() returned "
2056                         + "null " + SmsController.formatCrossStackMessageId(messageId));
2057                 return null;
2058             }
2059         } else {
2060             SmsMessageBase.SubmitPduBase pdu =
2061                     com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
2062                             destinationAddress, message, deliveryIntent != null,
2063                             SmsHeader.toByteArray(smsHeader), encoding, smsHeader.languageTable,
2064                             smsHeader.languageShiftTable, validityPeriod, messageRef);
2065             if (pdu != null) {
2066                 HashMap map = getSmsTrackerMap(destinationAddress, scAddress, message, pdu);
2067                 return getSmsTracker(callingPackage, callingUser, map,
2068                         sentIntent, deliveryIntent, getFormat(), unsentPartCount, anyPartFailed,
2069                         messageUri, smsHeader, (!lastPart || expectMore),
2070                         fullMessageText,  /*isText*/
2071                         true,  /*persistMessage*/ false, priority, validityPeriod,  /* isForVvm */
2072                         false, messageId, messageRef, false, uniqueMessageId);
2073             } else {
2074                 Rlog.e(TAG, "GsmSMSDispatcher.getNewSubmitPduTracker(): getSubmitPdu() returned "
2075                         + "null " + SmsController.formatCrossStackMessageId(messageId));
2076                 return null;
2077             }
2078         }
2079     }
2080 
2081     /**
2082      * Send a single or a multi-part SMS
2083      *
2084      * @param trackers each tracker will contain:
2085      * -smsc the SMSC to send the message through, or NULL for the
2086      *  default SMSC
2087      * -pdu the raw PDU to send
2088      * -sentIntent if not NULL this <code>Intent</code> is
2089      *  broadcast when the message is successfully sent, or failed.
2090      *  The result code will be <code>Activity.RESULT_OK<code> for success,
2091      *  or one of these errors:
2092      *  <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code><br>
2093      *  <code>SmsManager.RESULT_ERROR_RADIO_OFF</code><br>
2094      *  <code>SmsManager.RESULT_ERROR_NULL_PDU</code><br>
2095      *  <code>SmsManager.RESULT_ERROR_NO_SERVICE</code><br>
2096      *  <code>SmsManager.RESULT_ERROR_LIMIT_EXCEEDED</code><br>
2097      *  <code>SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE</code><br>
2098      *  <code>SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br>
2099      *  <code>SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br>
2100      *  <code>SmsManager.RESULT_RADIO_NOT_AVAILABLE</code><br>
2101      *  <code>SmsManager.RESULT_NETWORK_REJECT</code><br>
2102      *  <code>SmsManager.RESULT_INVALID_ARGUMENTS</code><br>
2103      *  <code>SmsManager.RESULT_INVALID_STATE</code><br>
2104      *  <code>SmsManager.RESULT_NO_MEMORY</code><br>
2105      *  <code>SmsManager.RESULT_INVALID_SMS_FORMAT</code><br>
2106      *  <code>SmsManager.RESULT_SYSTEM_ERROR</code><br>
2107      *  <code>SmsManager.RESULT_MODEM_ERROR</code><br>
2108      *  <code>SmsManager.RESULT_NETWORK_ERROR</code><br>
2109      *  <code>SmsManager.RESULT_ENCODING_ERROR</code><br>
2110      *  <code>SmsManager.RESULT_INVALID_SMSC_ADDRESS</code><br>
2111      *  <code>SmsManager.RESULT_OPERATION_NOT_ALLOWED</code><br>
2112      *  <code>SmsManager.RESULT_INTERNAL_ERROR</code><br>
2113      *  <code>SmsManager.RESULT_NO_RESOURCES</code><br>
2114      *  <code>SmsManager.RESULT_CANCELLED</code><br>
2115      *  <code>SmsManager.RESULT_REQUEST_NOT_SUPPORTED</code><br>
2116      *  <code>SmsManager.RESULT_NO_BLUETOOTH_SERVICE</code><br>
2117      *  <code>SmsManager.RESULT_INVALID_BLUETOOTH_ADDRESS</code><br>
2118      *  <code>SmsManager.RESULT_BLUETOOTH_DISCONNECTED</code><br>
2119      *  <code>SmsManager.RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br>
2120      *  <code>SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br>
2121      *  <code>SmsManager.RESULT_SMS_SEND_RETRY_FAILED</code><br>
2122      *  <code>SmsManager.RESULT_REMOTE_EXCEPTION</code><br>
2123      *  <code>SmsManager.RESULT_NO_DEFAULT_SMS_APP</code><br>
2124      *  <code>SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE</code><br>
2125      *  <code>SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br>
2126      *  <code>SmsManager.RESULT_RIL_NETWORK_REJECT</code><br>
2127      *  <code>SmsManager.RESULT_RIL_INVALID_STATE</code><br>
2128      *  <code>SmsManager.RESULT_RIL_INVALID_ARGUMENTS</code><br>
2129      *  <code>SmsManager.RESULT_RIL_NO_MEMORY</code><br>
2130      *  <code>SmsManager.RESULT_RIL_REQUEST_RATE_LIMITED</code><br>
2131      *  <code>SmsManager.RESULT_RIL_INVALID_SMS_FORMAT</code><br>
2132      *  <code>SmsManager.RESULT_RIL_SYSTEM_ERR</code><br>
2133      *  <code>SmsManager.RESULT_RIL_ENCODING_ERR</code><br>
2134      *  <code>SmsManager.RESULT_RIL_INVALID_SMSC_ADDRESS</code><br>
2135      *  <code>SmsManager.RESULT_RIL_MODEM_ERR</code><br>
2136      *  <code>SmsManager.RESULT_RIL_NETWORK_ERR</code><br>
2137      *  <code>SmsManager.RESULT_RIL_INTERNAL_ERR</code><br>
2138      *  <code>SmsManager.RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br>
2139      *  <code>SmsManager.RESULT_RIL_INVALID_MODEM_STATE</code><br>
2140      *  <code>SmsManager.RESULT_RIL_NETWORK_NOT_READY</code><br>
2141      *  <code>SmsManager.RESULT_RIL_OPERATION_NOT_ALLOWED</code><br>
2142      *  <code>SmsManager.RESULT_RIL_NO_RESOURCES</code><br>
2143      *  <code>SmsManager.RESULT_RIL_CANCELLED</code><br>
2144      *  <code>SmsManager.RESULT_RIL_SIM_ABSENT</code><br>
2145      *  <code>SmsManager.RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br>
2146      *  <code>SmsManager.RESULT_RIL_ACCESS_BARRED</code><br>
2147      *  <code>SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br>
2148      *  For <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors,
2149      *  the sentIntent may include the extra "errorCode" containing a radio technology specific
2150      *  value, generally only useful for troubleshooting.<br>
2151      *  The per-application based SMS control checks sentIntent. If sentIntent
2152      *  is NULL the caller will be checked against all unknown applications,
2153      *  which cause smaller number of SMS to be sent in checking period.
2154      * -deliveryIntent if not NULL this <code>Intent</code> is
2155      *  broadcast when the message is delivered to the recipient.  The
2156      *  raw pdu of the status report is in the extended data ("pdu").
2157      * -param destAddr the destination phone number (for short code confirmation)
2158      */
2159     @VisibleForTesting
sendRawPdu(SmsTracker[] trackers)2160     public void sendRawPdu(SmsTracker[] trackers) {
2161         @SmsManager.Result int error = SmsManager.RESULT_ERROR_NONE;
2162         PackageInfo appInfo = null;
2163         if (mSmsSendDisabled) {
2164             Rlog.e(TAG, "Device does not support sending sms.");
2165             error = SmsManager.RESULT_ERROR_NO_SERVICE;
2166         } else {
2167             for (SmsTracker tracker : trackers) {
2168                 if (tracker.getData().get(MAP_KEY_PDU) == null) {
2169                     Rlog.e(TAG, "Empty PDU");
2170                     error = SmsManager.RESULT_ERROR_NULL_PDU;
2171                     break;
2172                 }
2173             }
2174 
2175             if (error == SmsManager.RESULT_ERROR_NONE) {
2176                 UserHandle userHandle = UserHandle.of(trackers[0].mUserId);
2177                 PackageManager pm = mContext.createContextAsUser(userHandle, 0).getPackageManager();
2178 
2179                 try {
2180                     // Get package info via packagemanager
2181                     appInfo =
2182                             pm.getPackageInfo(
2183                                     trackers[0].getAppPackageName(),
2184                                     PackageManager.GET_SIGNATURES);
2185                 } catch (PackageManager.NameNotFoundException e) {
2186                     Rlog.e(TAG, "Can't get calling app package info: refusing to send SMS "
2187                             + SmsController.formatCrossStackMessageId(
2188                                     getMultiTrackermessageId(trackers)));
2189                     error = SmsManager.RESULT_ERROR_GENERIC_FAILURE;
2190                 }
2191             }
2192         }
2193 
2194         if (error != SmsManager.RESULT_ERROR_NONE) {
2195             handleSmsTrackersFailure(trackers, error, NO_ERROR_CODE);
2196             return;
2197         }
2198 
2199         // checkDestination() returns true if the destination is not a premium short code or the
2200         // sending app is approved to send to short codes. Otherwise, a message is sent to our
2201         // handler with the SmsTracker to request user confirmation before sending.
2202         if (checkDestination(trackers)) {
2203             // check for excessive outgoing SMS usage by this app
2204             if (!mSmsDispatchersController
2205                     .getUsageMonitor()
2206                     .check(appInfo.packageName, trackers.length)) {
2207                 sendMessage(obtainMessage(EVENT_SEND_LIMIT_REACHED_CONFIRMATION, trackers));
2208                 return;
2209             }
2210 
2211             for (SmsTracker tracker : trackers) {
2212                 sendSms(tracker);
2213             }
2214         }
2215 
2216         if (mPhone.hasCalling() && mTelephonyManager.isEmergencyNumber(trackers[0].mDestAddress)) {
2217             new AsyncEmergencyContactNotifier(mContext).execute();
2218         }
2219     }
2220 
2221     /**
2222      * Check if destination is a potential premium short code and sender is not pre-approved to send
2223      * to short codes.
2224      *
2225      * @param trackers the trackers for a single or a multi-part SMS to send
2226      * @return true if the destination is approved; false if user confirmation event was sent
2227      */
checkDestination(SmsTracker[] trackers)2228     boolean checkDestination(SmsTracker[] trackers) {
2229         if (mContext.checkCallingOrSelfPermission(SEND_SMS_NO_CONFIRMATION)
2230                 == PackageManager.PERMISSION_GRANTED || trackers[0].mIsForVvm
2231                 || trackers[0].mSkipShortCodeDestAddrCheck) {
2232             Rlog.d(TAG, "checkDestination: app pre-approved");
2233             return true;            // app is pre-approved to send to short codes
2234         } else {
2235             int rule = mPremiumSmsRule.get();
2236             int smsCategory = SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
2237             if (rule == PREMIUM_RULE_USE_SIM || rule == PREMIUM_RULE_USE_BOTH) {
2238                 String simCountryIso =
2239                         mTelephonyManager.getSimCountryIsoForPhone(mPhone.getPhoneId());
2240                 if (simCountryIso == null || simCountryIso.length() != 2) {
2241                     Rlog.e(TAG, "Can't get SIM country Iso: trying network country Iso "
2242                             + SmsController.formatCrossStackMessageId(
2243                                     getMultiTrackermessageId(trackers)));
2244                     simCountryIso =
2245                             mTelephonyManager.getNetworkCountryIso(mPhone.getPhoneId());
2246                 }
2247 
2248                 smsCategory =
2249                         mSmsDispatchersController
2250                                 .getUsageMonitor()
2251                                 .checkDestination(trackers[0].mDestAddress, simCountryIso);
2252                 Rlog.d(TAG, "checkDestination: simCountryIso=" + simCountryIso);
2253             }
2254             if (rule == PREMIUM_RULE_USE_NETWORK || rule == PREMIUM_RULE_USE_BOTH) {
2255                 String networkCountryIso =
2256                         mTelephonyManager.getNetworkCountryIso(mPhone.getPhoneId());
2257                 if (networkCountryIso == null || networkCountryIso.length() != 2) {
2258                     Rlog.e(TAG, "Can't get Network country Iso: trying SIM country Iso "
2259                             + SmsController.formatCrossStackMessageId(
2260                                     getMultiTrackermessageId(trackers)));
2261                     networkCountryIso =
2262                             mTelephonyManager.getSimCountryIsoForPhone(mPhone.getPhoneId());
2263                 }
2264 
2265                 smsCategory =
2266                         SmsUsageMonitor.mergeShortCodeCategories(
2267                                 smsCategory,
2268                                 mSmsDispatchersController
2269                                         .getUsageMonitor()
2270                                         .checkDestination(
2271                                                 trackers[0].mDestAddress, networkCountryIso));
2272                 Rlog.d(TAG, "checkDestination: networkCountryIso=" + networkCountryIso);
2273             }
2274             Rlog.d(TAG, "checkDestination: smsCategory=" + smsCategory);
2275 
2276             if (smsCategory != SmsManager.SMS_CATEGORY_NOT_SHORT_CODE) {
2277                 int xmlVersion = mSmsDispatchersController.getUsageMonitor()
2278                         .getShortCodeXmlFileVersion();
2279                 mPhone.getSmsStats().onOutgoingShortCodeSms(smsCategory, xmlVersion);
2280             }
2281 
2282             if (smsCategory == SmsManager.SMS_CATEGORY_NOT_SHORT_CODE
2283                     || smsCategory == SmsManager.SMS_CATEGORY_FREE_SHORT_CODE
2284                     || smsCategory == SmsManager.SMS_CATEGORY_STANDARD_SHORT_CODE) {
2285                 return true;    // not a premium short code
2286             }
2287 
2288             // Do not allow any premium sms during SuW
2289             if (Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
2290                 Rlog.e(TAG, "Can't send premium sms during Setup Wizard "
2291                         + SmsController.formatCrossStackMessageId(
2292                                 getMultiTrackermessageId(trackers)));
2293                 return false;
2294             }
2295 
2296             // Check whether to block premium sms in satellite mode.
2297             if (shouldBlockPremiumSmsInSatelliteMode()) {
2298                 Rlog.d(TAG, "Block premium SMS in satellite mode."
2299                         + " messageId=" + SmsController.formatCrossStackMessageId(
2300                                 getMultiTrackermessageId(trackers)));
2301                 return false;
2302             }
2303 
2304             // Wait for user confirmation unless the user has set permission to always allow/deny
2305             int premiumSmsPermission =
2306                     mSmsDispatchersController
2307                             .getUsageMonitor()
2308                             .getPremiumSmsPermission(trackers[0].getAppPackageName());
2309             if (premiumSmsPermission == SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN) {
2310                 // First time trying to send to premium SMS.
2311                 premiumSmsPermission = SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ASK_USER;
2312             }
2313 
2314             switch (premiumSmsPermission) {
2315                 case SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW:
2316                     Rlog.d(TAG, "User approved this app to send to premium SMS "
2317                             + SmsController.formatCrossStackMessageId(
2318                                     getMultiTrackermessageId(trackers)));
2319                     return true;
2320 
2321                 case SmsUsageMonitor.PREMIUM_SMS_PERMISSION_NEVER_ALLOW:
2322                     Rlog.w(TAG, "User denied this app from sending to premium SMS "
2323                             + SmsController.formatCrossStackMessageId(
2324                                     getMultiTrackermessageId(trackers)));
2325                     Message msg = obtainMessage(EVENT_SENDING_NOT_ALLOWED, trackers);
2326                     sendMessage(msg);
2327                     return false;   // reject this message
2328 
2329                 case SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ASK_USER:
2330                 default:
2331                     int event;
2332                     if (smsCategory == SmsManager.SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE) {
2333                         event = EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE;
2334                     } else {
2335                         event = EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE;
2336                     }
2337                     sendMessage(obtainMessage(event, trackers));
2338                     return false;   // wait for user confirmation
2339             }
2340         }
2341     }
2342 
2343     /** Block premium sms in satellite mode. */
2344     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
shouldBlockPremiumSmsInSatelliteMode()2345     public boolean shouldBlockPremiumSmsInSatelliteMode() {
2346         SatelliteController sc = SatelliteController.getInstance();
2347 
2348         if (sc.isSatelliteBeingEnabled()) {
2349             Rlog.d(TAG, "shouldBlockPremiumSmsInSatelliteMode: block premium sms when "
2350                     + "satellite is being enabled");
2351             return true;
2352         }
2353 
2354         if (sc.isSatelliteEnabled()) {
2355             int satelliteSubId = sc.getSelectedSatelliteSubId();
2356             int[] services = sc.getSupportedServicesOnCarrierRoamingNtn(satelliteSubId);
2357             boolean isSmsSupported = ArrayUtils.contains(
2358                     services, NetworkRegistrationInfo.SERVICE_TYPE_SMS);
2359             Rlog.d(TAG, "shouldBlockPremiumSmsInSatelliteMode: satelliteSubId="
2360                     + satelliteSubId + " isSmsSupported=" + isSmsSupported
2361                     + " services=" + Arrays.toString(services));
2362             return !isSmsSupported;
2363         }
2364 
2365         Rlog.d(TAG, "shouldBlockPremiumSmsInSatelliteMode: return false.");
2366         return false;
2367     }
2368 
2369     /**
2370      * Deny sending a single or a multi-part SMS if the outgoing queue limit is reached. Used when
2371      * the message must be confirmed by the user due to excessive usage or potential premium SMS
2372      * detected.
2373      *
2374      * @param trackers the SmsTracker array for the message to send
2375      * @return true if the message was denied; false to continue with send confirmation
2376      */
denyIfQueueLimitReached(SmsTracker[] trackers)2377     private boolean denyIfQueueLimitReached(SmsTracker[] trackers) {
2378         // one SmsTracker array is treated as one message for checking queue limit.
2379         if (mPendingTrackerCount >= MO_MSG_QUEUE_LIMIT) {
2380             // Deny sending message when the queue limit is reached.
2381             Rlog.e(TAG, "Denied because queue limit reached "
2382                     + SmsController.formatCrossStackMessageId(getMultiTrackermessageId(trackers)));
2383             handleSmsTrackersFailure(
2384                     trackers, SmsManager.RESULT_ERROR_LIMIT_EXCEEDED, NO_ERROR_CODE);
2385             return true;
2386         }
2387         mPendingTrackerCount++;
2388         return false;
2389     }
2390 
2391     /**
2392      * Returns the label for the specified app package name.
2393      * @param appPackage the package name of the app requesting to send an SMS
2394      * @return the label for the specified app, or the package name if getApplicationInfo() fails
2395      */
getAppLabel(String appPackage, @UserIdInt int userId)2396     private CharSequence getAppLabel(String appPackage, @UserIdInt int userId) {
2397         PackageManager pm = mContext.getPackageManager();
2398         try {
2399             ApplicationInfo appInfo = pm.getApplicationInfoAsUser(appPackage, 0,
2400                     UserHandle.of(userId));
2401             return appInfo.loadSafeLabel(pm);
2402         } catch (PackageManager.NameNotFoundException e) {
2403             Rlog.e(TAG, "PackageManager Name Not Found for package " + appPackage);
2404             return appPackage;  // fall back to package name if we can't get app label
2405         }
2406     }
2407 
2408     /**
2409      * Post an alert when SMS needs confirmation due to excessive usage.
2410      *
2411      * @param trackers the SmsTracker array for the current message.
2412      */
handleReachSentLimit(SmsTracker[] trackers)2413     protected void handleReachSentLimit(SmsTracker[] trackers) {
2414         if (denyIfQueueLimitReached(trackers)) {
2415             return;     // queue limit reached; error was returned to caller
2416         }
2417 
2418         CharSequence appLabel = getAppLabel(trackers[0].getAppPackageName(), trackers[0].mUserId);
2419         Resources r = Resources.getSystem();
2420         Spanned messageText = Html.fromHtml(r.getString(R.string.sms_control_message, appLabel));
2421 
2422         // Construct ConfirmDialogListenter for Rate Limit handling
2423         ConfirmDialogListener listener =
2424                 new ConfirmDialogListener(trackers, null, ConfirmDialogListener.RATE_LIMIT);
2425 
2426         AlertDialog d = new AlertDialog.Builder(mContext)
2427                 .setTitle(R.string.sms_control_title)
2428                 .setIcon(R.drawable.stat_sys_warning)
2429                 .setMessage(messageText)
2430                 .setPositiveButton(r.getString(R.string.sms_control_yes), listener)
2431                 .setNegativeButton(r.getString(R.string.sms_control_no), listener)
2432                 .setOnCancelListener(listener)
2433                 .create();
2434 
2435         d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
2436         d.show();
2437     }
2438 
2439     /**
2440      * Post an alert for user confirmation when sending to a potential short code.
2441      *
2442      * @param isPremium true if the destination is known to be a premium short code
2443      * @param trackers the SmsTracker array for the current message.
2444      */
2445     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
handleConfirmShortCode(boolean isPremium, SmsTracker[] trackers)2446     protected void handleConfirmShortCode(boolean isPremium, SmsTracker[] trackers) {
2447         if (denyIfQueueLimitReached(trackers)) {
2448             return;     // queue limit reached; error was returned to caller
2449         }
2450 
2451         int detailsId;
2452         if (isPremium) {
2453             detailsId = R.string.sms_premium_short_code_details;
2454         } else {
2455             detailsId = R.string.sms_short_code_details;
2456         }
2457 
2458         CharSequence appLabel = getAppLabel(trackers[0].getAppPackageName(), trackers[0].mUserId);
2459         Resources r = Resources.getSystem();
2460         Spanned messageText =
2461                 Html.fromHtml(
2462                         r.getString(
2463                                 R.string.sms_short_code_confirm_message,
2464                                 appLabel,
2465                                 trackers[0].mDestAddress));
2466 
2467         LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
2468                 Context.LAYOUT_INFLATER_SERVICE);
2469         View layout = inflater.inflate(R.layout.sms_short_code_confirmation_dialog, null);
2470 
2471         // Construct ConfirmDialogListenter for short code message sending
2472         ConfirmDialogListener listener =
2473                 new ConfirmDialogListener(
2474                         trackers,
2475                         (TextView)
2476                                 layout.findViewById(R.id.sms_short_code_remember_undo_instruction),
2477                         ConfirmDialogListener.SHORT_CODE_MSG);
2478 
2479         TextView messageView = (TextView) layout.findViewById(R.id.sms_short_code_confirm_message);
2480         messageView.setText(messageText);
2481 
2482         ViewGroup detailsLayout = (ViewGroup) layout.findViewById(
2483                 R.id.sms_short_code_detail_layout);
2484         TextView detailsView = (TextView) detailsLayout.findViewById(
2485                 R.id.sms_short_code_detail_message);
2486         detailsView.setText(detailsId);
2487 
2488         CheckBox rememberChoice = (CheckBox) layout.findViewById(
2489                 R.id.sms_short_code_remember_choice_checkbox);
2490         rememberChoice.setOnCheckedChangeListener(listener);
2491 
2492         AlertDialog d = new AlertDialog.Builder(mContext)
2493                 .setView(layout)
2494                 .setPositiveButton(r.getString(R.string.sms_short_code_confirm_allow), listener)
2495                 .setNegativeButton(r.getString(R.string.sms_short_code_confirm_deny), listener)
2496                 .setOnCancelListener(listener)
2497                 .create();
2498 
2499         d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
2500         d.show();
2501 
2502         listener.setPositiveButton(d.getButton(DialogInterface.BUTTON_POSITIVE));
2503         listener.setNegativeButton(d.getButton(DialogInterface.BUTTON_NEGATIVE));
2504     }
2505 
2506     /**
2507      * Send the message along to the radio.
2508      *
2509      * @param tracker holds the SMS message to send
2510      */
2511     @UnsupportedAppUsage
sendSms(SmsTracker tracker)2512     protected abstract void sendSms(SmsTracker tracker);
2513 
2514     /**
2515      * Retry the message along to the radio.
2516      *
2517      * @param tracker holds the SMS message to send
2518      */
sendRetrySms(SmsTracker tracker)2519     public void sendRetrySms(SmsTracker tracker) {
2520         // re-routing to SmsDispatchersController
2521         if (mSmsDispatchersController != null) {
2522             mSmsDispatchersController.sendRetrySms(tracker);
2523         } else {
2524             Rlog.e(TAG, mSmsDispatchersController + " is null. Retry failed "
2525                     + SmsController.formatCrossStackMessageId(tracker.mMessageId));
2526         }
2527     }
2528 
handleSmsTrackersFailure(SmsTracker[] trackers, @SmsManager.Result int error, int errorCode)2529     private void handleSmsTrackersFailure(SmsTracker[] trackers, @SmsManager.Result int error,
2530             int errorCode) {
2531         for (SmsTracker tracker : trackers) {
2532             tracker.onFailed(mContext, error, errorCode);
2533             notifySmsSentFailedToEmergencyStateTracker(tracker, false);
2534         }
2535         if (trackers.length > 0) {
2536             // This error occurs before the SMS is sent. Make an assumption if it would have
2537             // been sent over IMS or not.
2538             mPhone.getSmsStats().onOutgoingSms(
2539                     isIms(),
2540                     SmsConstants.FORMAT_3GPP2.equals(getFormat()),
2541                     false /* fallbackToCs */,
2542                     error,
2543                     trackers[0].mMessageId,
2544                     trackers[0].isFromDefaultSmsApplication(mContext),
2545                     trackers[0].getInterval(),
2546                     mTelephonyManager.isEmergencyNumber(trackers[0].mDestAddress),
2547                     trackers[0].isMtSmsPollingMessage(mContext));
2548             if (mPhone != null) {
2549                 TelephonyAnalytics telephonyAnalytics = mPhone.getTelephonyAnalytics();
2550                 if (telephonyAnalytics != null) {
2551                     SmsMmsAnalytics smsMmsAnalytics = telephonyAnalytics.getSmsMmsAnalytics();
2552                     if (smsMmsAnalytics != null) {
2553                         smsMmsAnalytics.onOutgoingSms(
2554                                 isIms(),
2555                                 error);
2556                     }
2557                 }
2558             }
2559         }
2560     }
2561 
2562     /**
2563      * Keeps track of an SMS that has been sent to the RIL, until it has
2564      * successfully been sent, or we're done trying.
2565      */
2566     public static class SmsTracker {
2567         // fields need to be public for derived SmsDispatchers
2568         @UnsupportedAppUsage
2569         private final HashMap<String, Object> mData;
2570         public int mRetryCount;
2571         // IMS retry counter. Nonzero indicates initial message was sent over IMS channel in RIL and
2572         // counts how many retries have been made on the IMS channel.
2573         // Used in older implementations where the message is sent over IMS using the RIL.
2574         public int mImsRetry;
2575         // Tag indicating that this SMS is being handled by the ImsSmsDispatcher. This tracker
2576         // should not try to use SMS over IMS over the RIL interface in this case when falling back.
2577         public boolean mUsesImsServiceForIms;
2578         @UnsupportedAppUsage
2579         public int mMessageRef;
2580         public boolean mExpectMore;
2581         public int mValidityPeriod;
2582         public int mPriority;
2583         String mFormat;
2584 
2585         @UnsupportedAppUsage
2586         public final PendingIntent mSentIntent;
2587         @UnsupportedAppUsage
2588         public final PendingIntent mDeliveryIntent;
2589 
2590         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
2591         public final PackageInfo mAppInfo;
2592         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
2593         public final String mDestAddress;
2594 
2595         public final SmsHeader mSmsHeader;
2596 
2597         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
2598         private long mTimestamp = SystemClock.elapsedRealtime();
2599         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
2600         public Uri mMessageUri; // Uri of persisted message if we wrote one
2601 
2602         // Reference to states of a multipart message that this part belongs to
2603         private AtomicInteger mUnsentPartCount;
2604         private AtomicBoolean mAnyPartFailed;
2605         // The full message content of a single part message
2606         // or a multipart message that this part belongs to
2607         private String mFullMessageText;
2608 
2609         private int mSubId;
2610 
2611         // If this is a text message (instead of data message)
2612         private boolean mIsText;
2613 
2614         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
2615         private boolean mPersistMessage;
2616 
2617         // User who sends the SMS.
2618         private final @UserIdInt int mUserId;
2619 
2620         private final boolean mIsForVvm;
2621 
2622         public final long mMessageId;
2623 
2624         // A CarrierMessagingService result code to be returned to the caller.
2625         public int mResultCodeFromCarrierMessagingService;
2626 
2627         private Boolean mIsFromDefaultSmsApplication;
2628 
2629         private int mCarrierId;
2630         private boolean mSkipShortCodeDestAddrCheck;
2631         public final long mUniqueMessageId;
2632         // SMS anomaly uuid -- unexpected error from RIL
2633         private final UUID mAnomalyUnexpectedErrorFromRilUUID =
2634                 UUID.fromString("43043600-ea7a-44d2-9ae6-a58567ac7886");
2635 
SmsTracker(HashMap<String, Object> data, PendingIntent sentIntent, PendingIntent deliveryIntent, PackageInfo appInfo, String destAddr, String format, AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri, SmsHeader smsHeader, boolean expectMore, String fullMessageText, int subId, boolean isText, boolean persistMessage, int userId, int priority, int validityPeriod, boolean isForVvm, long messageId, int carrierId, int messageRef, boolean skipShortCodeDestAddrCheck, long uniqueMessageId)2636         private SmsTracker(HashMap<String, Object> data, PendingIntent sentIntent,
2637                 PendingIntent deliveryIntent, PackageInfo appInfo, String destAddr, String format,
2638                 AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri,
2639                 SmsHeader smsHeader, boolean expectMore, String fullMessageText, int subId,
2640                 boolean isText, boolean persistMessage, int userId, int priority,
2641                 int validityPeriod, boolean isForVvm, long messageId, int carrierId,
2642                 int messageRef, boolean skipShortCodeDestAddrCheck,
2643                 long uniqueMessageId) {
2644             mData = data;
2645             mSentIntent = sentIntent;
2646             mDeliveryIntent = deliveryIntent;
2647             mRetryCount = 0;
2648             mAppInfo = appInfo;
2649             mDestAddress = destAddr;
2650             mFormat = format;
2651             mExpectMore = expectMore;
2652             mImsRetry = 0;
2653             mUsesImsServiceForIms = false;
2654             mMessageRef = messageRef;
2655             mUnsentPartCount = unsentPartCount;
2656             mAnyPartFailed = anyPartFailed;
2657             mMessageUri = messageUri;
2658             mSmsHeader = smsHeader;
2659             mFullMessageText = fullMessageText;
2660             mSubId = subId;
2661             mIsText = isText;
2662             mPersistMessage = persistMessage;
2663             mUserId = userId;
2664             mPriority = priority;
2665             mValidityPeriod = validityPeriod;
2666             mIsForVvm = isForVvm;
2667             mMessageId = messageId;
2668             mCarrierId = carrierId;
2669             mSkipShortCodeDestAddrCheck = skipShortCodeDestAddrCheck;
2670             mUniqueMessageId = uniqueMessageId;
2671             mResultCodeFromCarrierMessagingService = CarrierMessagingService.SEND_STATUS_OK;
2672         }
2673 
2674         @VisibleForTesting
SmsTracker(String destAddr, long messageId, String messageText)2675         public SmsTracker(String destAddr, long messageId, String messageText) {
2676             mData = null;
2677             mSentIntent = null;
2678             mDeliveryIntent = null;
2679             mAppInfo = null;
2680             mDestAddress = destAddr;
2681             mUsesImsServiceForIms = false;
2682             mSmsHeader = null;
2683             mMessageId = messageId;
2684             mUserId = 0;
2685             mPriority = 0;
2686             mValidityPeriod = 0;
2687             mIsForVvm = false;
2688             mCarrierId = 0;
2689             mSkipShortCodeDestAddrCheck = false;
2690             mUniqueMessageId = 0;
2691             mResultCodeFromCarrierMessagingService = CarrierMessagingService.SEND_STATUS_OK;
2692             mFullMessageText = messageText;
2693         }
2694 
getData()2695         public HashMap<String, Object> getData() {
2696             return mData;
2697         }
2698 
2699         /**
2700          * Get the App package name
2701          * @return App package name info
2702          */
getAppPackageName()2703         public String getAppPackageName() {
2704             return mAppInfo != null ? mAppInfo.packageName : null;
2705         }
2706 
2707         /**
2708          * Get the calling Application Info
2709          * @return Application Info
2710          */
getAppInfo()2711         public ApplicationInfo getAppInfo() {
2712             return mAppInfo == null ? null : mAppInfo.applicationInfo;
2713         }
2714 
2715         /** Return if the SMS was originated from the default SMS application. */
isFromDefaultSmsApplication(Context context)2716         public boolean isFromDefaultSmsApplication(Context context) {
2717             if (mIsFromDefaultSmsApplication == null) {
2718                 UserHandle userHandle;
2719                 final long identity = Binder.clearCallingIdentity();
2720                 try {
2721                     userHandle = TelephonyUtils.getSubscriptionUserHandle(context, mSubId);
2722                 } finally {
2723                     Binder.restoreCallingIdentity(identity);
2724                 }
2725                 // Perform a lazy initialization, due to the cost of the operation.
2726                 mIsFromDefaultSmsApplication = SmsApplication.isDefaultSmsApplicationAsUser(context,
2727                                     getAppPackageName(), userHandle);
2728             }
2729             return mIsFromDefaultSmsApplication;
2730         }
2731 
2732         /**
2733          * Check if the message is a MT SMS polling message.
2734          *
2735          * @param context The Context
2736          * @return true if the message is a MT SMS polling message, false otherwise.
2737          */
isMtSmsPollingMessage(Context context)2738         public boolean isMtSmsPollingMessage(Context context) {
2739             if (mFullMessageText == null) {
2740                 return false;
2741             }
2742 
2743             String mtSmsPollingText =
2744                     context.getResources().getString(R.string.config_mt_sms_polling_text);
2745             return mFullMessageText.equals(mtSmsPollingText);
2746         }
2747 
2748         /**
2749          * Update the status of this message if we persisted it
2750          */
2751         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
updateSentMessageStatus(Context context, int status)2752         public void updateSentMessageStatus(Context context, int status) {
2753             if (mMessageUri != null) {
2754                 // If we wrote this message in writeSentMessage, update it now
2755                 ContentValues values = new ContentValues(1);
2756                 values.put(Sms.STATUS, status);
2757                 context.getContentResolver().update(mMessageUri, values, null, null);
2758             }
2759         }
2760 
2761         /**
2762          * Set the final state of a message: FAILED or SENT
2763          *
2764          * @param context The Context
2765          * @param messageType The final message type
2766          * @param errorCode The error code
2767          */
updateMessageState(Context context, int messageType, int errorCode)2768         private void updateMessageState(Context context, int messageType, int errorCode) {
2769             if (mMessageUri == null) {
2770                 return;
2771             }
2772             final ContentValues values = new ContentValues(2);
2773             values.put(Sms.TYPE, messageType);
2774             values.put(Sms.ERROR_CODE, errorCode);
2775             final long identity = Binder.clearCallingIdentity();
2776             try {
2777                 if (context.getContentResolver().update(mMessageUri, values,
2778                         null/*where*/, null/*selectionArgs*/) != 1) {
2779                     Rlog.e(TAG, "Failed to move message to " + messageType);
2780                 }
2781             } finally {
2782                 Binder.restoreCallingIdentity(identity);
2783             }
2784         }
2785 
2786         /**
2787          * Returns the interval in milliseconds between sending the message out and current time.
2788          * Called after receiving success/failure response to calculate the time
2789          * to complete the SMS send to the network.
2790          */
getInterval()2791         protected long getInterval() {
2792             return SystemClock.elapsedRealtime() - mTimestamp;
2793         }
2794 
2795         /**
2796          * Returns the flag specifying whether this {@link SmsTracker} is a single part or
2797          * the last part of multipart message.
2798          */
isSinglePartOrLastPart()2799         protected boolean isSinglePartOrLastPart() {
2800             return mUnsentPartCount != null ? (mUnsentPartCount.get() == 0) : true;
2801         }
2802 
2803         /**
2804          * Returns the flag specifying whether any part of this {@link SmsTracker} failed to send
2805          * or not.
2806          */
isAnyPartFailed()2807         protected boolean isAnyPartFailed() {
2808             return mAnyPartFailed != null && mAnyPartFailed.get();
2809         }
2810 
2811         /**
2812          * Persist a sent SMS if required:
2813          * 1. It is a text message
2814          * 2. SmsApplication tells us to persist: sent from apps that are not default-SMS app or
2815          *    bluetooth
2816          *
2817          * @param context
2818          * @param messageType The folder to store (FAILED or SENT)
2819          * @param errorCode The current error code for this SMS or SMS part
2820          * @return The telephony provider URI if stored
2821          */
persistSentMessageIfRequired(Context context, int messageType, int errorCode)2822         private Uri persistSentMessageIfRequired(Context context, int messageType, int errorCode) {
2823             if (!mIsText || !mPersistMessage || isFromDefaultSmsApplication(context)) {
2824                 return null;
2825             }
2826             Rlog.d(TAG, "Persist SMS into "
2827                     + (messageType == Sms.MESSAGE_TYPE_FAILED ? "FAILED" : "SENT"));
2828             final ContentValues values = new ContentValues();
2829             values.put(Sms.SUBSCRIPTION_ID, mSubId);
2830             values.put(Sms.ADDRESS, mDestAddress);
2831             values.put(Sms.BODY, mFullMessageText);
2832             values.put(Sms.DATE, System.currentTimeMillis()); // milliseconds
2833             values.put(Sms.SEEN, 1);
2834             values.put(Sms.READ, 1);
2835             final String creator = mAppInfo != null ? mAppInfo.packageName : null;
2836             if (!TextUtils.isEmpty(creator)) {
2837                 values.put(Sms.CREATOR, creator);
2838             }
2839             if (mDeliveryIntent != null) {
2840                 values.put(Sms.STATUS, Telephony.Sms.STATUS_PENDING);
2841             }
2842             if (errorCode != NO_ERROR_CODE) {
2843                 values.put(Sms.ERROR_CODE, errorCode);
2844             }
2845             final long identity = Binder.clearCallingIdentity();
2846             final ContentResolver resolver = context.getContentResolver();
2847             try {
2848                 final Uri uri =  resolver.insert(Telephony.Sms.Sent.CONTENT_URI, values);
2849                 if (uri != null && messageType == Sms.MESSAGE_TYPE_FAILED) {
2850                     // Since we can't persist a message directly into FAILED box,
2851                     // we have to update the column after we persist it into SENT box.
2852                     // The gap between the state change is tiny so I would not expect
2853                     // it to cause any serious problem
2854                     // TODO: we should add a "failed" URI for this in SmsProvider?
2855                     final ContentValues updateValues = new ContentValues(1);
2856                     updateValues.put(Sms.TYPE, Sms.MESSAGE_TYPE_FAILED);
2857                     resolver.update(uri, updateValues, null/*where*/, null/*selectionArgs*/);
2858                 }
2859                 return uri;
2860             } catch (Exception e) {
2861                 Rlog.e(TAG, "writeOutboxMessage: Failed to persist outbox message", e);
2862                 return null;
2863             } finally {
2864                 Binder.restoreCallingIdentity(identity);
2865             }
2866         }
2867 
2868         /**
2869          * Persist or update an SMS depending on if we send a new message or a stored message
2870          *
2871          * @param context
2872          * @param messageType The message folder for this SMS, FAILED or SENT
2873          * @param errorCode The current error code for this SMS or SMS part
2874          */
persistOrUpdateMessage(Context context, int messageType, int errorCode)2875         private void persistOrUpdateMessage(Context context, int messageType, int errorCode) {
2876             if (mMessageUri != null) {
2877                 updateMessageState(context, messageType, errorCode);
2878             } else {
2879                 mMessageUri = persistSentMessageIfRequired(context, messageType, errorCode);
2880             }
2881         }
2882 
2883         /**
2884          * Handle a failure of a single part message or a part of a multipart message
2885          *
2886          * @param context The Context
2887          * @param error The error to send back with
2888          * @param errorCode
2889          */
2890         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
onFailed(Context context, int error, int errorCode)2891         public void onFailed(Context context, int error, int errorCode) {
2892             if (mAnyPartFailed != null) {
2893                 mAnyPartFailed.set(true);
2894             }
2895             // is single part or last part of multipart message
2896             boolean isSinglePartOrLastPart = true;
2897             if (mUnsentPartCount != null) {
2898                 isSinglePartOrLastPart = mUnsentPartCount.decrementAndGet() == 0;
2899             }
2900             if (isSinglePartOrLastPart) {
2901                 persistOrUpdateMessage(context, Sms.MESSAGE_TYPE_FAILED, errorCode);
2902             }
2903             if (mSentIntent != null) {
2904                 try {
2905                     // Extra information to send with the sent intent
2906                     Intent fillIn = new Intent();
2907                     if (mMessageUri != null) {
2908                         // Pass this to SMS apps so that they know where it is stored
2909                         fillIn.putExtra("uri", mMessageUri.toString());
2910                     }
2911                     if (errorCode != NO_ERROR_CODE) {
2912                         fillIn.putExtra("errorCode", errorCode);
2913                     }
2914                     if (mUnsentPartCount != null && isSinglePartOrLastPart) {
2915                         // Is multipart and last part
2916                         fillIn.putExtra(SEND_NEXT_MSG_EXTRA, true);
2917                     }
2918                     if (mMessageId != 0L) {
2919                         // Send the id back to the caller so they can verify the message id
2920                         // with the one they passed to SmsManager.
2921                         fillIn.putExtra(MESSAGE_ID_EXTRA, mMessageId);
2922                     }
2923                     fillIn.putExtra("format", mFormat);
2924                     fillIn.putExtra("ims", mUsesImsServiceForIms);
2925                     mSentIntent.send(context, error, fillIn);
2926                 } catch (CanceledException ex) {
2927                     Rlog.e(TAG, "Failed to send result "
2928                             + SmsController.formatCrossStackMessageId(mMessageId));
2929                 }
2930             }
2931             reportAnomaly(error, errorCode);
2932         }
2933 
reportAnomaly(int error, int errorCode)2934         private void reportAnomaly(int error, int errorCode) {
2935             switch (error) {
2936                 // Exclude known failed reason
2937                 case SmsManager.RESULT_ERROR_NO_SERVICE:
2938                 case SmsManager.RESULT_ERROR_RADIO_OFF:
2939                 case SmsManager.RESULT_ERROR_LIMIT_EXCEEDED:
2940                 case SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED:
2941                 case SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED:
2942                 case SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY:
2943                     break;
2944                 // Dump bugreport for analysis
2945                 default:
2946                     String message = "SMS failed";
2947                     Rlog.d(TAG, message + " with error " + error + ", errorCode " + errorCode);
2948                     AnomalyReporter.reportAnomaly(
2949                             generateUUID(error, errorCode), message, mCarrierId);
2950             }
2951         }
2952 
generateUUID(int error, int errorCode)2953         private UUID generateUUID(int error, int errorCode) {
2954             long lerror = error;
2955             long lerrorCode = errorCode;
2956             return new UUID(mAnomalyUnexpectedErrorFromRilUUID.getMostSignificantBits(),
2957                     mAnomalyUnexpectedErrorFromRilUUID.getLeastSignificantBits()
2958                             + ((lerrorCode << 32) + lerror));
2959         }
2960 
2961         /**
2962          * Handle the sent of a single part message or a part of a multipart message
2963          *
2964          * @param context The Context
2965          */
2966         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
onSent(Context context)2967         public void onSent(Context context) {
2968             // is single part or last part of multipart message
2969             boolean isSinglePartOrLastPart = true;
2970             if (mUnsentPartCount != null) {
2971                 isSinglePartOrLastPart = mUnsentPartCount.decrementAndGet() == 0;
2972             }
2973             if (isSinglePartOrLastPart) {
2974                 int messageType = Sms.MESSAGE_TYPE_SENT;
2975                 if (mAnyPartFailed != null && mAnyPartFailed.get()) {
2976                     messageType = Sms.MESSAGE_TYPE_FAILED;
2977                 }
2978                 persistOrUpdateMessage(context, messageType, NO_ERROR_CODE);
2979             }
2980             if (mSentIntent != null) {
2981                 try {
2982                     // Extra information to send with the sent intent
2983                     Intent fillIn = new Intent();
2984                     if (mMessageUri != null) {
2985                         // Pass this to SMS apps so that they know where it is stored
2986                         fillIn.putExtra("uri", mMessageUri.toString());
2987                     }
2988                     if (mUnsentPartCount != null && isSinglePartOrLastPart) {
2989                         // Is multipart and last part
2990                         fillIn.putExtra(SEND_NEXT_MSG_EXTRA, true);
2991                     }
2992                     fillIn.putExtra("format", mFormat);
2993                     fillIn.putExtra("ims", mUsesImsServiceForIms);
2994                     mSentIntent.send(context, Activity.RESULT_OK, fillIn);
2995                 } catch (CanceledException ex) {
2996                     Rlog.e(TAG, "Failed to send result");
2997                 }
2998             }
2999         }
3000     }
3001 
getSmsTracker(String callingPackage, int callingUser, HashMap<String, Object> data, PendingIntent sentIntent, PendingIntent deliveryIntent, String format, AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri, SmsHeader smsHeader, boolean expectMore, String fullMessageText, boolean isText, boolean persistMessage, int priority, int validityPeriod, boolean isForVvm, long messageId, int messageRef, boolean skipShortCodeCheck, long uniqueMessageId)3002     protected SmsTracker getSmsTracker(String callingPackage, int callingUser,
3003             HashMap<String, Object> data,
3004             PendingIntent sentIntent, PendingIntent deliveryIntent, String format,
3005             AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri,
3006             SmsHeader smsHeader, boolean expectMore, String fullMessageText, boolean isText,
3007             boolean persistMessage, int priority, int validityPeriod, boolean isForVvm,
3008             long messageId, int messageRef, boolean skipShortCodeCheck,
3009             long uniqueMessageId) {
3010         if (!Flags.smsMmsDeliverBroadcastsRedirectToMainUser()) {
3011             callingUser = UserHandle.getUserHandleForUid(Binder.getCallingUid()).getIdentifier();
3012         }
3013 
3014         // Get package info via packagemanager
3015         PackageManager pm = mContext.createContextAsUser(UserHandle.of(callingUser), 0)
3016                 .getPackageManager();
3017         PackageInfo appInfo = null;
3018         try {
3019             appInfo = pm.getPackageInfo(callingPackage, PackageManager.GET_SIGNATURES);
3020         } catch (PackageManager.NameNotFoundException e) {
3021             // error will be logged in sendRawPdu
3022         }
3023         // Strip non-digits from destination phone number before checking for short codes
3024         // and before displaying the number to the user if confirmation is required.
3025         String destAddr = PhoneNumberUtils.extractNetworkPortion((String) data.get("destAddr"));
3026         return new SmsTracker(data, sentIntent, deliveryIntent, appInfo, destAddr, format,
3027                 unsentPartCount, anyPartFailed, messageUri, smsHeader, expectMore,
3028                 fullMessageText, getSubId(), isText, persistMessage, callingUser, priority,
3029                 validityPeriod, isForVvm, messageId, mPhone.getCarrierId(), messageRef,
3030                 skipShortCodeCheck, uniqueMessageId);
3031     }
3032 
getSmsTracker(String callingPackage, int callingUser, HashMap<String, Object> data, PendingIntent sentIntent, PendingIntent deliveryIntent, String format, Uri messageUri, boolean expectMore, String fullMessageText, boolean isText, boolean persistMessage, boolean isForVvm, long messageId, int messageRef, long uniqueMessageId)3033     protected SmsTracker getSmsTracker(String callingPackage, int callingUser,
3034             HashMap<String, Object> data, PendingIntent sentIntent, PendingIntent deliveryIntent,
3035             String format, Uri messageUri, boolean expectMore, String fullMessageText,
3036             boolean isText, boolean persistMessage, boolean isForVvm,
3037             long messageId, int messageRef, long uniqueMessageId) {
3038         return getSmsTracker(callingPackage, callingUser , data, sentIntent, deliveryIntent,
3039                 format, /*unsentPartCount*/ null, /*anyPartFailed*/ null, messageUri, /*smsHeader*/
3040                 null, expectMore, fullMessageText, isText,
3041                 persistMessage, SMS_MESSAGE_PRIORITY_NOT_SPECIFIED,
3042                 SMS_MESSAGE_PERIOD_NOT_SPECIFIED,
3043                 isForVvm, messageId, messageRef, false, uniqueMessageId);
3044     }
3045 
getSmsTracker(String callingPackage, int callingUser, HashMap<String, Object> data, PendingIntent sentIntent, PendingIntent deliveryIntent, String format, Uri messageUri, boolean expectMore, String fullMessageText, boolean isText, boolean persistMessage, int priority, int validityPeriod, boolean isForVvm, long messageId, int messageRef, boolean skipShortCodeCheck, long uniqueMessageId)3046     protected SmsTracker getSmsTracker(String callingPackage, int callingUser,
3047             HashMap<String, Object> data, PendingIntent sentIntent, PendingIntent deliveryIntent,
3048             String format, Uri messageUri, boolean expectMore, String fullMessageText,
3049             boolean isText, boolean persistMessage, int priority, int validityPeriod,
3050             boolean isForVvm, long messageId, int messageRef, boolean skipShortCodeCheck,
3051             long uniqueMessageId) {
3052         return getSmsTracker(callingPackage, callingUser, data, sentIntent, deliveryIntent,
3053                 format, /*unsentPartCount*/ null, /*anyPartFailed*/ null, messageUri, /*smsHeader*/
3054                 null, expectMore, fullMessageText, isText, persistMessage, priority,
3055                 validityPeriod, isForVvm, messageId, messageRef, skipShortCodeCheck,
3056                 uniqueMessageId);
3057     }
3058 
getSmsTrackerMap(String destAddr, String scAddr, String text, SmsMessageBase.SubmitPduBase pdu)3059     protected HashMap<String, Object> getSmsTrackerMap(String destAddr, String scAddr,
3060             String text, SmsMessageBase.SubmitPduBase pdu) {
3061         HashMap<String, Object> map = new HashMap<String, Object>();
3062         map.put(MAP_KEY_DEST_ADDR, destAddr);
3063         map.put(MAP_KEY_SC_ADDR, scAddr);
3064         map.put(MAP_KEY_TEXT, text);
3065         map.put(MAP_KEY_SMSC, pdu.encodedScAddress);
3066         map.put(MAP_KEY_PDU, pdu.encodedMessage);
3067         return map;
3068     }
3069 
getSmsTrackerMap(String destAddr, String scAddr, int destPort, byte[] data, SmsMessageBase.SubmitPduBase pdu)3070     protected HashMap<String, Object> getSmsTrackerMap(String destAddr, String scAddr,
3071             int destPort, byte[] data, SmsMessageBase.SubmitPduBase pdu) {
3072         HashMap<String, Object> map = new HashMap<String, Object>();
3073         map.put(MAP_KEY_DEST_ADDR, destAddr);
3074         map.put(MAP_KEY_SC_ADDR, scAddr);
3075         map.put(MAP_KEY_DEST_PORT, destPort);
3076         map.put(MAP_KEY_DATA, data);
3077         map.put(MAP_KEY_SMSC, pdu.encodedScAddress);
3078         map.put(MAP_KEY_PDU, pdu.encodedMessage);
3079         return map;
3080     }
3081 
3082     /**
3083      * Dialog listener for SMS confirmation dialog.
3084      */
3085     private final class ConfirmDialogListener
3086             implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener,
3087             CompoundButton.OnCheckedChangeListener {
3088 
3089         private final SmsTracker[] mTrackers;
3090         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
3091         private Button mPositiveButton;
3092         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
3093         private Button mNegativeButton;
3094         private boolean mRememberChoice;    // default is unchecked
3095         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
3096         private final TextView mRememberUndoInstruction;
3097         private int mConfirmationType;  // 0 - Short Code Msg Sending; 1 - Rate Limit Exceeded
3098         private static final int SHORT_CODE_MSG = 0; // Short Code Msg
3099         private static final int RATE_LIMIT = 1; // Rate Limit Exceeded
3100         private static final int NEVER_ALLOW = 1; // Never Allow
3101 
ConfirmDialogListener(SmsTracker[] trackers, TextView textView, int confirmationType)3102         ConfirmDialogListener(SmsTracker[] trackers, TextView textView, int confirmationType) {
3103             mTrackers = trackers;
3104             mRememberUndoInstruction = textView;
3105             mConfirmationType = confirmationType;
3106         }
3107 
setPositiveButton(Button button)3108         void setPositiveButton(Button button) {
3109             mPositiveButton = button;
3110         }
3111 
setNegativeButton(Button button)3112         void setNegativeButton(Button button) {
3113             mNegativeButton = button;
3114         }
3115 
3116         @Override
onClick(DialogInterface dialog, int which)3117         public void onClick(DialogInterface dialog, int which) {
3118             // Always set the SMS permission so that Settings will show a permission setting
3119             // for the app (it won't be shown until after the app tries to send to a short code).
3120             int newSmsPermission = SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ASK_USER;
3121 
3122             if (which == DialogInterface.BUTTON_POSITIVE) {
3123                 Rlog.d(TAG, "CONFIRM sending SMS");
3124                 // XXX this is lossy- apps can have more than one signature
3125                 EventLog.writeEvent(
3126                         EventLogTags.EXP_DET_SMS_SENT_BY_USER,
3127                         mTrackers[0].mAppInfo.applicationInfo == null
3128                                 ? -1
3129                                 : mTrackers[0].mAppInfo.applicationInfo.uid);
3130                 sendMessage(obtainMessage(EVENT_SEND_CONFIRMED_SMS, mTrackers));
3131                 if (mRememberChoice) {
3132                     newSmsPermission = SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW;
3133                 }
3134             } else if (which == DialogInterface.BUTTON_NEGATIVE) {
3135                 Rlog.d(TAG, "DENY sending SMS");
3136                 // XXX this is lossy- apps can have more than one signature
3137                 EventLog.writeEvent(
3138                         EventLogTags.EXP_DET_SMS_DENIED_BY_USER,
3139                         mTrackers[0].mAppInfo.applicationInfo == null
3140                                 ? -1
3141                                 : mTrackers[0].mAppInfo.applicationInfo.uid);
3142                 Message msg = obtainMessage(EVENT_STOP_SENDING, mTrackers);
3143                 msg.arg1 = mConfirmationType;
3144                 if (mRememberChoice) {
3145                     newSmsPermission = SmsUsageMonitor.PREMIUM_SMS_PERMISSION_NEVER_ALLOW;
3146                     msg.arg2 = ConfirmDialogListener.NEVER_ALLOW;
3147                 }
3148                 sendMessage(msg);
3149             }
3150             mSmsDispatchersController.setPremiumSmsPermission(
3151                     mTrackers[0].getAppPackageName(), newSmsPermission);
3152         }
3153 
3154         @Override
onCancel(DialogInterface dialog)3155         public void onCancel(DialogInterface dialog) {
3156             Rlog.d(TAG, "dialog dismissed: don't send SMS");
3157             Message msg = obtainMessage(EVENT_STOP_SENDING, mTrackers);
3158             msg.arg1 = mConfirmationType;
3159             sendMessage(msg);
3160         }
3161 
3162         @Override
onCheckedChanged(CompoundButton buttonView, boolean isChecked)3163         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
3164             Rlog.d(TAG, "remember this choice: " + isChecked);
3165             mRememberChoice = isChecked;
3166             if (isChecked) {
3167                 mPositiveButton.setText(R.string.sms_short_code_confirm_always_allow);
3168                 mNegativeButton.setText(R.string.sms_short_code_confirm_never_allow);
3169                 if (mRememberUndoInstruction != null) {
3170                     mRememberUndoInstruction
3171                             .setText(R.string.sms_short_code_remember_undo_instruction);
3172                     mRememberUndoInstruction.setPadding(0,0,0,32);
3173                 }
3174             } else {
3175                 mPositiveButton.setText(R.string.sms_short_code_confirm_allow);
3176                 mNegativeButton.setText(R.string.sms_short_code_confirm_deny);
3177                 if (mRememberUndoInstruction != null) {
3178                     mRememberUndoInstruction.setText("");
3179                     mRememberUndoInstruction.setPadding(0,0,0,0);
3180                 }
3181             }
3182         }
3183     }
3184 
isIms()3185     public boolean isIms() {
3186         if (mSmsDispatchersController != null) {
3187             return mSmsDispatchersController.isIms();
3188         } else {
3189             Rlog.e(TAG, "mSmsDispatchersController is null");
3190             return false;
3191         }
3192     }
3193 
3194     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getMultipartMessageText(ArrayList<String> parts)3195     private String getMultipartMessageText(ArrayList<String> parts) {
3196         final StringBuilder sb = new StringBuilder();
3197         for (String part : parts) {
3198             if (part != null) {
3199                 sb.append(part);
3200             }
3201         }
3202         return sb.toString();
3203     }
3204 
3205     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getCarrierAppPackageName()3206     protected String getCarrierAppPackageName() {
3207         CarrierPrivilegesTracker cpt = mPhone.getCarrierPrivilegesTracker();
3208         if (cpt == null) {
3209             return null;
3210         }
3211         List<String> carrierPackages =
3212                 cpt.getCarrierPackageNamesForIntent(
3213                         new Intent(CarrierMessagingService.SERVICE_INTERFACE));
3214         if (carrierPackages != null && carrierPackages.size() == 1) {
3215             return carrierPackages.get(0);
3216         }
3217         // If there is no carrier package which implements CarrierMessagingService, then lookup
3218         // an ImsService implementing RCS that also implements CarrierMessagingService.
3219         return CarrierSmsUtils.getImsRcsPackageForIntent(mContext, mPhone,
3220                 new Intent(CarrierMessagingService.SERVICE_INTERFACE));
3221     }
3222 
3223     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getSubId()3224     protected int getSubId() {
3225         return SubscriptionManager.getSubscriptionId(mPhone.getPhoneId());
3226     }
3227 
isCdmaMo()3228     protected boolean isCdmaMo() {
3229         return mSmsDispatchersController.isCdmaMo();
3230     }
3231 
isAscii7bitSupportedForLongMessage()3232     private boolean isAscii7bitSupportedForLongMessage() {
3233         //TODO: Do not rely on calling identity here, we should store UID & clear identity earlier.
3234         long token = Binder.clearCallingIdentity();
3235         try {
3236             CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(
3237                     Context.CARRIER_CONFIG_SERVICE);
3238             PersistableBundle pb = null;
3239             pb = configManager.getConfigForSubId(mPhone.getSubId());
3240             if (pb != null) {
3241                 return pb.getBoolean(CarrierConfigManager
3242                         .KEY_ASCII_7_BIT_SUPPORT_FOR_LONG_MESSAGE_BOOL);
3243             }
3244             return false;
3245         } finally {
3246             Binder.restoreCallingIdentity(token);
3247         }
3248     }
3249 
3250     /**
3251      * Dump local logs
3252      */
dump(FileDescriptor fd, PrintWriter printWriter, String[] args)3253     public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
3254         IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
3255         pw.println(TAG);
3256         pw.increaseIndent();
3257 
3258         pw.println("mLocalLog:");
3259         pw.increaseIndent();
3260         mLocalLog.dump(fd, pw, args);
3261         pw.decreaseIndent();
3262 
3263         pw.println("mSmsOutgoingErrorCodes:");
3264         pw.increaseIndent();
3265         mSmsOutgoingErrorCodes.dump(fd, pw, args);
3266         pw.decreaseIndent();
3267 
3268         pw.decreaseIndent();
3269     }
3270 }
3271