1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
4  * Not a Contribution.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 package com.android.internal.telephony;
20 
21 import static com.android.internal.telephony.util.TelephonyUtils.checkDumpPermission;
22 
23 import android.annotation.Nullable;
24 import android.app.ActivityManager;
25 import android.app.AppOpsManager;
26 import android.app.PendingIntent;
27 import android.compat.annotation.UnsupportedAppUsage;
28 import android.content.Context;
29 import android.net.Uri;
30 import android.os.BaseBundle;
31 import android.os.Binder;
32 import android.os.Build;
33 import android.os.Bundle;
34 import android.os.TelephonyServiceManager.ServiceRegisterer;
35 import android.provider.Telephony.Sms.Intents;
36 import android.telephony.CarrierConfigManager;
37 import android.telephony.SmsManager;
38 import android.telephony.SubscriptionInfo;
39 import android.telephony.SubscriptionManager;
40 import android.telephony.TelephonyFrameworkInitializer;
41 import android.telephony.TelephonyManager;
42 
43 import com.android.internal.util.IndentingPrintWriter;
44 import com.android.telephony.Rlog;
45 
46 import java.io.FileDescriptor;
47 import java.io.PrintWriter;
48 import java.nio.charset.StandardCharsets;
49 import java.util.List;
50 
51 /**
52  * Implements the ISmsImplBase interface used in the SmsManager API.
53  */
54 public class SmsController extends ISmsImplBase {
55     static final String LOG_TAG = "SmsController";
56 
57     private final Context mContext;
58 
SmsController(Context context)59     protected SmsController(Context context) {
60         mContext = context;
61         ServiceRegisterer smsServiceRegisterer = TelephonyFrameworkInitializer
62                 .getTelephonyServiceManager()
63                 .getSmsServiceRegisterer();
64         if (smsServiceRegisterer.get() == null) {
65             smsServiceRegisterer.register(this);
66         }
67     }
68 
getPhone(int subId)69     private Phone getPhone(int subId) {
70         Phone phone = PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId));
71         if (phone == null) {
72             phone = PhoneFactory.getDefaultPhone();
73         }
74         return phone;
75     }
76 
getSmsPermissions(int subId)77     private SmsPermissions getSmsPermissions(int subId) {
78         Phone phone = getPhone(subId);
79 
80         return new SmsPermissions(phone, mContext,
81                 (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE));
82     }
83 
84     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
85     @Override
updateMessageOnIccEfForSubscriber(int subId, String callingPackage, int index, int status, byte[] pdu)86     public boolean updateMessageOnIccEfForSubscriber(int subId, String callingPackage, int index,
87             int status, byte[] pdu) {
88         if (callingPackage == null) {
89             callingPackage = getCallingPackage();
90         }
91         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
92         if (iccSmsIntMgr != null) {
93             return iccSmsIntMgr.updateMessageOnIccEf(callingPackage, index, status, pdu);
94         } else {
95             Rlog.e(LOG_TAG, "updateMessageOnIccEfForSubscriber iccSmsIntMgr is null"
96                     + " for Subscription: " + subId);
97             return false;
98         }
99     }
100 
101     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
102     @Override
copyMessageToIccEfForSubscriber(int subId, String callingPackage, int status, byte[] pdu, byte[] smsc)103     public boolean copyMessageToIccEfForSubscriber(int subId, String callingPackage, int status,
104             byte[] pdu, byte[] smsc) {
105         if (callingPackage == null) {
106             callingPackage = getCallingPackage();
107         }
108         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
109         if (iccSmsIntMgr != null) {
110             return iccSmsIntMgr.copyMessageToIccEf(callingPackage, status, pdu, smsc);
111         } else {
112             Rlog.e(LOG_TAG, "copyMessageToIccEfForSubscriber iccSmsIntMgr is null"
113                     + " for Subscription: " + subId);
114             return false;
115         }
116     }
117 
118     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
119     @Override
getAllMessagesFromIccEfForSubscriber(int subId, String callingPackage)120     public List<SmsRawData> getAllMessagesFromIccEfForSubscriber(int subId, String callingPackage) {
121         if (callingPackage == null) {
122             callingPackage = getCallingPackage();
123         }
124         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
125         if (iccSmsIntMgr != null) {
126             return iccSmsIntMgr.getAllMessagesFromIccEf(callingPackage);
127         } else {
128             Rlog.e(LOG_TAG, "getAllMessagesFromIccEfForSubscriber iccSmsIntMgr is"
129                     + " null for Subscription: " + subId);
130             return null;
131         }
132     }
133 
134     /**
135      * @deprecated Use {@link #sendDataForSubscriber(int, String, String, String, String, int,
136      * byte[], PendingIntent, PendingIntent)} instead
137      */
138     @Deprecated
139     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
sendDataForSubscriber(int subId, String callingPackage, String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent)140     public void sendDataForSubscriber(int subId, String callingPackage, String destAddr,
141             String scAddr, int destPort, byte[] data, PendingIntent sentIntent,
142             PendingIntent deliveryIntent) {
143         sendDataForSubscriber(subId, callingPackage, null, destAddr, scAddr, destPort, data,
144                 sentIntent, deliveryIntent);
145     }
146 
147     @Override
sendDataForSubscriber(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent)148     public void sendDataForSubscriber(int subId, String callingPackage,
149             String callingAttributionTag, String destAddr, String scAddr, int destPort, byte[] data,
150             PendingIntent sentIntent, PendingIntent deliveryIntent) {
151         if (callingPackage == null) {
152             callingPackage = getCallingPackage();
153         }
154         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
155         if (iccSmsIntMgr != null) {
156             iccSmsIntMgr.sendData(callingPackage, callingAttributionTag, destAddr, scAddr, destPort,
157                     data, sentIntent, deliveryIntent);
158         } else {
159             Rlog.e(LOG_TAG, "sendDataForSubscriber iccSmsIntMgr is null for"
160                     + " Subscription: " + subId);
161             // TODO: Use a more specific error code to replace RESULT_ERROR_GENERIC_FAILURE.
162             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
163         }
164     }
165 
sendDataForSubscriberWithSelfPermissionsInternal(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean isForVvm)166     private void sendDataForSubscriberWithSelfPermissionsInternal(int subId, String callingPackage,
167             String callingAttributionTag, String destAddr, String scAddr, int destPort, byte[] data,
168             PendingIntent sentIntent, PendingIntent deliveryIntent, boolean isForVvm) {
169         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
170         if (iccSmsIntMgr != null) {
171             iccSmsIntMgr.sendDataWithSelfPermissions(callingPackage, callingAttributionTag,
172                     destAddr, scAddr, destPort, data, sentIntent, deliveryIntent, isForVvm);
173         } else {
174             Rlog.e(LOG_TAG, "sendText iccSmsIntMgr is null for"
175                     + " Subscription: " + subId);
176             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
177         }
178     }
179 
getCallingPackage()180     private String getCallingPackage() {
181         return mContext.getPackageManager().getPackagesForUid(Binder.getCallingUid())[0];
182     }
183 
184     @Override
sendTextForSubscriber(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp, long messageId)185     public void sendTextForSubscriber(int subId, String callingPackage,
186             String callingAttributionTag, String destAddr, String scAddr, String text,
187             PendingIntent sentIntent, PendingIntent deliveryIntent,
188             boolean persistMessageForNonDefaultSmsApp, long messageId) {
189         if (callingPackage == null) {
190             callingPackage = getCallingPackage();
191         }
192         if (!getSmsPermissions(subId).checkCallingCanSendText(persistMessageForNonDefaultSmsApp,
193                 callingPackage, callingAttributionTag, "Sending SMS message")) {
194             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
195             return;
196         }
197         long token = Binder.clearCallingIdentity();
198         SubscriptionInfo info;
199         try {
200             info = getSubscriptionInfo(subId);
201         } finally {
202             Binder.restoreCallingIdentity(token);
203         }
204         if (isBluetoothSubscription(info)) {
205             sendBluetoothText(info, destAddr, text, sentIntent, deliveryIntent);
206         } else {
207             sendIccText(subId, callingPackage, destAddr, scAddr, text, sentIntent, deliveryIntent,
208                     persistMessageForNonDefaultSmsApp, messageId);
209         }
210     }
211 
isBluetoothSubscription(SubscriptionInfo info)212     private boolean isBluetoothSubscription(SubscriptionInfo info) {
213         return info != null
214                 && info.getSubscriptionType() == SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM;
215     }
216 
sendBluetoothText(SubscriptionInfo info, String destAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)217     private void sendBluetoothText(SubscriptionInfo info, String destAddr,
218             String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
219         BtSmsInterfaceManager btSmsInterfaceManager = new BtSmsInterfaceManager();
220         btSmsInterfaceManager.sendText(mContext, destAddr, text, sentIntent, deliveryIntent, info);
221     }
222 
sendIccText(int subId, String callingPackage, String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp, long messageId)223     private void sendIccText(int subId, String callingPackage, String destAddr,
224             String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
225             boolean persistMessageForNonDefaultSmsApp, long messageId) {
226         Rlog.d(LOG_TAG, "sendTextForSubscriber iccSmsIntMgr"
227                 + " Subscription: " + subId + " id: " + messageId);
228         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
229         if (iccSmsIntMgr != null) {
230             iccSmsIntMgr.sendText(callingPackage, destAddr, scAddr, text, sentIntent,
231                     deliveryIntent, persistMessageForNonDefaultSmsApp, messageId);
232         } else {
233             Rlog.e(LOG_TAG, "sendTextForSubscriber iccSmsIntMgr is null for"
234                     + " Subscription: " + subId + " id: " + messageId);
235             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
236         }
237     }
238 
sendTextForSubscriberWithSelfPermissionsInternal(int subId, String callingPackage, String callingAttributeTag, String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, boolean isForVvm)239     private void sendTextForSubscriberWithSelfPermissionsInternal(int subId, String callingPackage,
240             String callingAttributeTag, String destAddr, String scAddr, String text,
241             PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage,
242             boolean isForVvm) {
243         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
244         if (iccSmsIntMgr != null) {
245             iccSmsIntMgr.sendTextWithSelfPermissions(callingPackage, callingAttributeTag, destAddr,
246                     scAddr, text, sentIntent, deliveryIntent, persistMessage, isForVvm);
247         } else {
248             Rlog.e(LOG_TAG, "sendText iccSmsIntMgr is null for"
249                     + " Subscription: " + subId);
250             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
251         }
252     }
253 
254     @Override
sendTextForSubscriberWithOptions(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, String parts, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, int priority, boolean expectMore, int validityPeriod)255     public void sendTextForSubscriberWithOptions(int subId, String callingPackage,
256             String callingAttributionTag, String destAddr, String scAddr, String parts,
257             PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage,
258             int priority, boolean expectMore, int validityPeriod) {
259         if (callingPackage == null) {
260             callingPackage = getCallingPackage();
261         }
262         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
263         if (iccSmsIntMgr != null) {
264             iccSmsIntMgr.sendTextWithOptions(callingPackage, callingAttributionTag, destAddr,
265                     scAddr, parts, sentIntent, deliveryIntent, persistMessage, priority, expectMore,
266                     validityPeriod);
267         } else {
268             Rlog.e(LOG_TAG, "sendTextWithOptions iccSmsIntMgr is null for"
269                     + " Subscription: " + subId);
270             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
271         }
272     }
273 
274     @Override
sendMultipartTextForSubscriber(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp, long messageId)275     public void sendMultipartTextForSubscriber(int subId, String callingPackage,
276             String callingAttributionTag, String destAddr, String scAddr, List<String> parts,
277             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
278             boolean persistMessageForNonDefaultSmsApp, long messageId) {
279         // This is different from the checking of other method. It prefers the package name
280         // returned by getCallPackage() for backward-compatibility.
281         if (getCallingPackage() != null) {
282             callingPackage = getCallingPackage();
283         }
284         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
285         if (iccSmsIntMgr != null) {
286             iccSmsIntMgr.sendMultipartText(callingPackage, callingAttributionTag, destAddr, scAddr,
287                     parts, sentIntents, deliveryIntents, persistMessageForNonDefaultSmsApp,
288                     messageId);
289         } else {
290             Rlog.e(LOG_TAG, "sendMultipartTextForSubscriber iccSmsIntMgr is null for"
291                     + " Subscription: " + subId + " id: " + messageId);
292             sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
293         }
294     }
295 
296     @Override
sendMultipartTextForSubscriberWithOptions(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, boolean persistMessage, int priority, boolean expectMore, int validityPeriod)297     public void sendMultipartTextForSubscriberWithOptions(int subId, String callingPackage,
298             String callingAttributionTag, String destAddr, String scAddr, List<String> parts,
299             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
300             boolean persistMessage, int priority, boolean expectMore, int validityPeriod) {
301         if (callingPackage == null) {
302             callingPackage = getCallingPackage();
303         }
304         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
305         if (iccSmsIntMgr != null) {
306             iccSmsIntMgr.sendMultipartTextWithOptions(callingPackage, callingAttributionTag,
307                     destAddr, scAddr, parts, sentIntents, deliveryIntents, persistMessage, priority,
308                     expectMore, validityPeriod, 0L /* messageId */);
309         } else {
310             Rlog.e(LOG_TAG, "sendMultipartTextWithOptions iccSmsIntMgr is null for"
311                     + " Subscription: " + subId);
312             sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
313         }
314     }
315 
316     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
317     @Override
enableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType)318     public boolean enableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType) {
319         return enableCellBroadcastRangeForSubscriber(subId, messageIdentifier, messageIdentifier,
320                 ranType);
321     }
322 
323     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
324     @Override
enableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId, int ranType)325     public boolean enableCellBroadcastRangeForSubscriber(int subId, int startMessageId,
326             int endMessageId, int ranType) {
327         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
328         if (iccSmsIntMgr != null) {
329             return iccSmsIntMgr.enableCellBroadcastRange(startMessageId, endMessageId, ranType);
330         } else {
331             Rlog.e(LOG_TAG, "enableCellBroadcastRangeForSubscriber iccSmsIntMgr is null for"
332                     + " Subscription: " + subId);
333         }
334         return false;
335     }
336 
337     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
338     @Override
disableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType)339     public boolean disableCellBroadcastForSubscriber(int subId,
340             int messageIdentifier, int ranType) {
341         return disableCellBroadcastRangeForSubscriber(subId, messageIdentifier, messageIdentifier,
342                 ranType);
343     }
344 
345     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
346     @Override
disableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId, int ranType)347     public boolean disableCellBroadcastRangeForSubscriber(int subId, int startMessageId,
348             int endMessageId, int ranType) {
349         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
350         if (iccSmsIntMgr != null) {
351             return iccSmsIntMgr.disableCellBroadcastRange(startMessageId, endMessageId, ranType);
352         } else {
353             Rlog.e(LOG_TAG, "disableCellBroadcastRangeForSubscriber iccSmsIntMgr is null for"
354                     + " Subscription:" + subId);
355         }
356         return false;
357     }
358 
359     @Override
getPremiumSmsPermission(String packageName)360     public int getPremiumSmsPermission(String packageName) {
361         return getPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName);
362     }
363 
364     @Override
getPremiumSmsPermissionForSubscriber(int subId, String packageName)365     public int getPremiumSmsPermissionForSubscriber(int subId, String packageName) {
366         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
367         if (iccSmsIntMgr != null) {
368             return iccSmsIntMgr.getPremiumSmsPermission(packageName);
369         } else {
370             Rlog.e(LOG_TAG, "getPremiumSmsPermissionForSubscriber iccSmsIntMgr is null");
371         }
372         //TODO Rakesh
373         return 0;
374     }
375 
376     @Override
setPremiumSmsPermission(String packageName, int permission)377     public void setPremiumSmsPermission(String packageName, int permission) {
378         setPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName,
379                 permission);
380     }
381 
382     @Override
setPremiumSmsPermissionForSubscriber(int subId, String packageName, int permission)383     public void setPremiumSmsPermissionForSubscriber(int subId, String packageName,
384             int permission) {
385         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
386         if (iccSmsIntMgr != null) {
387             iccSmsIntMgr.setPremiumSmsPermission(packageName, permission);
388         } else {
389             Rlog.e(LOG_TAG, "setPremiumSmsPermissionForSubscriber iccSmsIntMgr is null");
390         }
391     }
392 
393     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
394     @Override
isImsSmsSupportedForSubscriber(int subId)395     public boolean isImsSmsSupportedForSubscriber(int subId) {
396         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
397         if (iccSmsIntMgr != null) {
398             return iccSmsIntMgr.isImsSmsSupported();
399         } else {
400             Rlog.e(LOG_TAG, "isImsSmsSupportedForSubscriber iccSmsIntMgr is null");
401         }
402         return false;
403     }
404 
405     @Override
isSmsSimPickActivityNeeded(int subId)406     public boolean isSmsSimPickActivityNeeded(int subId) {
407         final Context context = mContext.getApplicationContext();
408         ActivityManager am = context.getSystemService(ActivityManager.class);
409         // Don't show the SMS SIM Pick activity if it is not foreground.
410         boolean isCallingProcessForeground = am != null
411                 && am.getUidImportance(Binder.getCallingUid())
412                         == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
413         if (!isCallingProcessForeground) {
414             Rlog.d(LOG_TAG, "isSmsSimPickActivityNeeded: calling process not foreground. "
415                     + "Suppressing activity.");
416             return false;
417         }
418         TelephonyManager telephonyManager =
419                 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
420         List<SubscriptionInfo> subInfoList;
421         final long identity = Binder.clearCallingIdentity();
422         try {
423             subInfoList = SubscriptionManager.from(context).getActiveSubscriptionInfoList();
424         } finally {
425             Binder.restoreCallingIdentity(identity);
426         }
427 
428         if (subInfoList != null) {
429             final int subInfoLength = subInfoList.size();
430 
431             for (int i = 0; i < subInfoLength; ++i) {
432                 final SubscriptionInfo sir = subInfoList.get(i);
433                 if (sir != null && sir.getSubscriptionId() == subId) {
434                     // The subscription id is valid, sms sim pick activity not needed
435                     return false;
436                 }
437             }
438 
439             // If reached here and multiple SIMs and subs present, sms sim pick activity is needed
440             if (subInfoLength > 1 && telephonyManager.getSimCount() > 1) {
441                 return true;
442             }
443         }
444 
445         return false;
446     }
447 
448     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
449     @Override
getImsSmsFormatForSubscriber(int subId)450     public String getImsSmsFormatForSubscriber(int subId) {
451         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
452         if (iccSmsIntMgr != null) {
453             return iccSmsIntMgr.getImsSmsFormat();
454         } else {
455             Rlog.e(LOG_TAG, "getImsSmsFormatForSubscriber iccSmsIntMgr is null");
456         }
457         return null;
458     }
459 
460     @Override
injectSmsPduForSubscriber( int subId, byte[] pdu, String format, PendingIntent receivedIntent)461     public void injectSmsPduForSubscriber(
462             int subId, byte[] pdu, String format, PendingIntent receivedIntent) {
463         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
464         if (iccSmsIntMgr != null) {
465             iccSmsIntMgr.injectSmsPdu(pdu, format, receivedIntent);
466         } else {
467             Rlog.e(LOG_TAG, "injectSmsPduForSubscriber iccSmsIntMgr is null");
468             // RESULT_SMS_GENERIC_ERROR is documented for injectSmsPdu
469             sendErrorInPendingIntent(receivedIntent, Intents.RESULT_SMS_GENERIC_ERROR);
470         }
471     }
472 
473     /**
474      * Get preferred SMS subscription.
475      *
476      * @return User-defined default SMS subscription. If there is no default, return the active
477      * subscription if there is only one active. If no preference can be found, return
478      * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
479      */
480     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
481     @Override
getPreferredSmsSubscription()482     public int getPreferredSmsSubscription() {
483         // If there is a default, choose that one.
484         int defaultSubId = SubscriptionController.getInstance().getDefaultSmsSubId();
485         if (SubscriptionManager.isValidSubscriptionId(defaultSubId)) {
486             return defaultSubId;
487         }
488         // No default, if there is only one sub active, choose that as the "preferred" sub id.
489         long token = Binder.clearCallingIdentity();
490         try {
491             int[] activeSubs = SubscriptionController.getInstance()
492                     .getActiveSubIdList(true /*visibleOnly*/);
493             if (activeSubs.length == 1) {
494                 return activeSubs[0];
495             }
496         } finally {
497             Binder.restoreCallingIdentity(token);
498         }
499         // No preference can be found.
500         return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
501     }
502 
503     /**
504      * Get SMS prompt property enabled or not
505      *
506      * @return True if SMS prompt is enabled.
507      */
508     @Override
isSMSPromptEnabled()509     public boolean isSMSPromptEnabled() {
510         return PhoneFactory.isSMSPromptEnabled();
511     }
512 
513     @Override
sendStoredText(int subId, String callingPkg, String callingAttributionTag, Uri messageUri, String scAddress, PendingIntent sentIntent, PendingIntent deliveryIntent)514     public void sendStoredText(int subId, String callingPkg, String callingAttributionTag,
515             Uri messageUri, String scAddress, PendingIntent sentIntent,
516             PendingIntent deliveryIntent) {
517         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
518         if (!getCallingPackage().equals(callingPkg)) {
519             throw new SecurityException("sendStoredText: Package " + callingPkg
520                     + "does not belong to " + Binder.getCallingUid());
521         }
522         if (iccSmsIntMgr != null) {
523             iccSmsIntMgr.sendStoredText(callingPkg, callingAttributionTag, messageUri, scAddress,
524                     sentIntent, deliveryIntent);
525         } else {
526             Rlog.e(LOG_TAG, "sendStoredText iccSmsIntMgr is null for subscription: " + subId);
527             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
528         }
529     }
530 
531     @Override
sendStoredMultipartText(int subId, String callingPkg, String callingAttributionTag, Uri messageUri, String scAddress, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents)532     public void sendStoredMultipartText(int subId, String callingPkg, String callingAttributionTag,
533             Uri messageUri, String scAddress, List<PendingIntent> sentIntents,
534             List<PendingIntent> deliveryIntents) {
535         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
536         if (!getCallingPackage().equals(callingPkg)) {
537             throw new SecurityException("sendStoredMultipartText: Package " + callingPkg
538                     + " does not belong to " + Binder.getCallingUid());
539         }
540         if (iccSmsIntMgr != null) {
541             iccSmsIntMgr.sendStoredMultipartText(callingPkg, callingAttributionTag, messageUri,
542                     scAddress, sentIntents, deliveryIntents);
543         } else {
544             Rlog.e(LOG_TAG, "sendStoredMultipartText iccSmsIntMgr is null for subscription: "
545                     + subId);
546             sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
547         }
548     }
549 
550     @Override
getCarrierConfigValuesForSubscriber(int subId)551     public Bundle getCarrierConfigValuesForSubscriber(int subId) {
552         final long identity = Binder.clearCallingIdentity();
553         try {
554             final CarrierConfigManager configManager =
555                     (CarrierConfigManager)
556                             mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
557             return getMmsConfig(configManager.getConfigForSubId(subId));
558         } finally {
559             Binder.restoreCallingIdentity(identity);
560         }
561     }
562 
563     /**
564      * Filters a bundle to only contain MMS config variables.
565      *
566      * This is for use with bundles returned by CarrierConfigManager which contain MMS config and
567      * unrelated config. It is assumed that all MMS_CONFIG_* keys are present in the supplied
568      * bundle.
569      *
570      * @param config a Bundle that contains MMS config variables and possibly more.
571      * @return a new Bundle that only contains the MMS_CONFIG_* keys defined in SmsManager.
572      */
getMmsConfig(BaseBundle config)573     private static Bundle getMmsConfig(BaseBundle config) {
574         Bundle filtered = new Bundle();
575         filtered.putBoolean(
576                 SmsManager.MMS_CONFIG_APPEND_TRANSACTION_ID,
577                 config.getBoolean(SmsManager.MMS_CONFIG_APPEND_TRANSACTION_ID));
578         filtered.putBoolean(
579                 SmsManager.MMS_CONFIG_MMS_ENABLED,
580                 config.getBoolean(SmsManager.MMS_CONFIG_MMS_ENABLED));
581         filtered.putBoolean(
582                 SmsManager.MMS_CONFIG_GROUP_MMS_ENABLED,
583                 config.getBoolean(SmsManager.MMS_CONFIG_GROUP_MMS_ENABLED));
584         filtered.putBoolean(
585                 SmsManager.MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED,
586                 config.getBoolean(SmsManager.MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED));
587         filtered.putBoolean(
588                 SmsManager.MMS_CONFIG_ALIAS_ENABLED,
589                 config.getBoolean(SmsManager.MMS_CONFIG_ALIAS_ENABLED));
590         filtered.putBoolean(
591                 SmsManager.MMS_CONFIG_ALLOW_ATTACH_AUDIO,
592                 config.getBoolean(SmsManager.MMS_CONFIG_ALLOW_ATTACH_AUDIO));
593         filtered.putBoolean(
594                 SmsManager.MMS_CONFIG_MULTIPART_SMS_ENABLED,
595                 config.getBoolean(SmsManager.MMS_CONFIG_MULTIPART_SMS_ENABLED));
596         filtered.putBoolean(
597                 SmsManager.MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED,
598                 config.getBoolean(SmsManager.MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED));
599         filtered.putBoolean(
600                 SmsManager.MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION,
601                 config.getBoolean(SmsManager.MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION));
602         filtered.putBoolean(
603                 SmsManager.MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES,
604                 config.getBoolean(SmsManager.MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES));
605         filtered.putBoolean(
606                 SmsManager.MMS_CONFIG_MMS_READ_REPORT_ENABLED,
607                 config.getBoolean(SmsManager.MMS_CONFIG_MMS_READ_REPORT_ENABLED));
608         filtered.putBoolean(
609                 SmsManager.MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED,
610                 config.getBoolean(SmsManager.MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED));
611         filtered.putBoolean(
612                 SmsManager.MMS_CONFIG_CLOSE_CONNECTION,
613                 config.getBoolean(SmsManager.MMS_CONFIG_CLOSE_CONNECTION));
614         filtered.putInt(
615                 SmsManager.MMS_CONFIG_MAX_MESSAGE_SIZE,
616                 config.getInt(SmsManager.MMS_CONFIG_MAX_MESSAGE_SIZE));
617         filtered.putInt(
618                 SmsManager.MMS_CONFIG_MAX_IMAGE_WIDTH,
619                 config.getInt(SmsManager.MMS_CONFIG_MAX_IMAGE_WIDTH));
620         filtered.putInt(
621                 SmsManager.MMS_CONFIG_MAX_IMAGE_HEIGHT,
622                 config.getInt(SmsManager.MMS_CONFIG_MAX_IMAGE_HEIGHT));
623         filtered.putInt(
624                 SmsManager.MMS_CONFIG_RECIPIENT_LIMIT,
625                 config.getInt(SmsManager.MMS_CONFIG_RECIPIENT_LIMIT));
626         filtered.putInt(
627                 SmsManager.MMS_CONFIG_ALIAS_MIN_CHARS,
628                 config.getInt(SmsManager.MMS_CONFIG_ALIAS_MIN_CHARS));
629         filtered.putInt(
630                 SmsManager.MMS_CONFIG_ALIAS_MAX_CHARS,
631                 config.getInt(SmsManager.MMS_CONFIG_ALIAS_MAX_CHARS));
632         filtered.putInt(
633                 SmsManager.MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD,
634                 config.getInt(SmsManager.MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD));
635         filtered.putInt(
636                 SmsManager.MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD,
637                 config.getInt(SmsManager.MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD));
638         filtered.putInt(
639                 SmsManager.MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE,
640                 config.getInt(SmsManager.MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE));
641         filtered.putInt(
642                 SmsManager.MMS_CONFIG_SUBJECT_MAX_LENGTH,
643                 config.getInt(SmsManager.MMS_CONFIG_SUBJECT_MAX_LENGTH));
644         filtered.putInt(
645                 SmsManager.MMS_CONFIG_HTTP_SOCKET_TIMEOUT,
646                 config.getInt(SmsManager.MMS_CONFIG_HTTP_SOCKET_TIMEOUT));
647         filtered.putString(
648                 SmsManager.MMS_CONFIG_UA_PROF_TAG_NAME,
649                 config.getString(SmsManager.MMS_CONFIG_UA_PROF_TAG_NAME));
650         filtered.putString(
651                 SmsManager.MMS_CONFIG_USER_AGENT,
652                 config.getString(SmsManager.MMS_CONFIG_USER_AGENT));
653         filtered.putString(
654                 SmsManager.MMS_CONFIG_UA_PROF_URL,
655                 config.getString(SmsManager.MMS_CONFIG_UA_PROF_URL));
656         filtered.putString(
657                 SmsManager.MMS_CONFIG_HTTP_PARAMS,
658                 config.getString(SmsManager.MMS_CONFIG_HTTP_PARAMS));
659         filtered.putString(
660                 SmsManager.MMS_CONFIG_EMAIL_GATEWAY_NUMBER,
661                 config.getString(SmsManager.MMS_CONFIG_EMAIL_GATEWAY_NUMBER));
662         filtered.putString(
663                 SmsManager.MMS_CONFIG_NAI_SUFFIX,
664                 config.getString(SmsManager.MMS_CONFIG_NAI_SUFFIX));
665         filtered.putBoolean(
666                 SmsManager.MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS,
667                 config.getBoolean(SmsManager.MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS));
668         filtered.putBoolean(
669                 SmsManager.MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER,
670                 config.getBoolean(SmsManager.MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER));
671         return filtered;
672     }
673 
674     @Override
createAppSpecificSmsTokenWithPackageInfo( int subId, String callingPkg, String prefixes, PendingIntent intent)675     public String createAppSpecificSmsTokenWithPackageInfo(
676             int subId, String callingPkg, String prefixes, PendingIntent intent) {
677         if (callingPkg == null) {
678             callingPkg = getCallingPackage();
679         }
680         return getPhone(subId).getAppSmsManager().createAppSpecificSmsTokenWithPackageInfo(
681                 subId, callingPkg, prefixes, intent);
682     }
683 
684     @Override
createAppSpecificSmsToken(int subId, String callingPkg, PendingIntent intent)685     public String createAppSpecificSmsToken(int subId, String callingPkg, PendingIntent intent) {
686         if (callingPkg == null) {
687             callingPkg = getCallingPackage();
688         }
689         return getPhone(subId).getAppSmsManager().createAppSpecificSmsToken(callingPkg, intent);
690     }
691 
692     @Override
checkSmsShortCodeDestination(int subId, String callingPackage, String callingFeatureId, String destAddress, String countryIso)693     public int checkSmsShortCodeDestination(int subId, String callingPackage,
694             String callingFeatureId, String destAddress, String countryIso) {
695         if (callingPackage == null) {
696             callingPackage = getCallingPackage();
697         }
698         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(getPhone(subId).getContext(),
699                 subId, callingPackage, callingFeatureId, "checkSmsShortCodeDestination")) {
700             return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
701         }
702         final long identity = Binder.clearCallingIdentity();
703         try {
704             return getPhone(subId).mSmsUsageMonitor.checkDestination(destAddress, countryIso);
705         } finally {
706             Binder.restoreCallingIdentity(identity);
707         }
708     }
709 
710     /**
711      * Internal API to send visual voicemail related SMS. This is not exposed outside the phone
712      * process, and should be called only after verifying that the caller is the default VVM app.
713      */
sendVisualVoicemailSmsForSubscriber(String callingPackage, String callingAttributionTag, int subId, String number, int port, String text, PendingIntent sentIntent)714     public void sendVisualVoicemailSmsForSubscriber(String callingPackage,
715             String callingAttributionTag, int subId, String number, int port, String text,
716             PendingIntent sentIntent) {
717         if (port == 0) {
718             sendTextForSubscriberWithSelfPermissionsInternal(subId, callingPackage,
719                     callingAttributionTag, number, null, text, sentIntent, null, false,
720                     true /* isForVvm */);
721         } else {
722             byte[] data = text.getBytes(StandardCharsets.UTF_8);
723             sendDataForSubscriberWithSelfPermissionsInternal(subId, callingPackage,
724                     callingAttributionTag, number, null, (short) port, data, sentIntent, null,
725                     true /* isForVvm */);
726         }
727     }
728 
729     @Override
getSmscAddressFromIccEfForSubscriber(int subId, String callingPackage)730     public String getSmscAddressFromIccEfForSubscriber(int subId, String callingPackage) {
731         if (callingPackage == null) {
732             callingPackage = getCallingPackage();
733         }
734         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
735         if (iccSmsIntMgr != null) {
736             return iccSmsIntMgr.getSmscAddressFromIccEf(callingPackage);
737         } else {
738             Rlog.e(LOG_TAG, "getSmscAddressFromIccEfForSubscriber iccSmsIntMgr is null"
739                     + " for Subscription: " + subId);
740             return null;
741         }
742     }
743 
744     @Override
setSmscAddressOnIccEfForSubscriber( String smsc, int subId, String callingPackage)745     public boolean setSmscAddressOnIccEfForSubscriber(
746             String smsc, int subId, String callingPackage) {
747         if (callingPackage == null) {
748             callingPackage = getCallingPackage();
749         }
750         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
751         if (iccSmsIntMgr != null) {
752             return iccSmsIntMgr.setSmscAddressOnIccEf(callingPackage, smsc);
753         } else {
754             Rlog.e(LOG_TAG, "setSmscAddressOnIccEfForSubscriber iccSmsIntMgr is null"
755                     + " for Subscription: " + subId);
756             return false;
757         }
758     }
759 
760     /**
761      * Triggered by `adb shell dumpsys isms`
762      */
763     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)764     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
765         if (!checkDumpPermission(mContext, LOG_TAG, pw)) {
766             return;
767         }
768 
769         IndentingPrintWriter indentingPW =
770                 new IndentingPrintWriter(pw, "    " /* singleIndent */);
771         for (Phone phone : PhoneFactory.getPhones()) {
772             int subId = phone.getSubId();
773             indentingPW.println(String.format("SmsManager for subId = %d:", subId));
774             indentingPW.increaseIndent();
775             if (getIccSmsInterfaceManager(subId) != null) {
776                 getIccSmsInterfaceManager(subId).dump(fd, indentingPW, args);
777             }
778             indentingPW.decreaseIndent();
779         }
780         indentingPW.flush();
781     }
782 
783     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
sendErrorInPendingIntent(@ullable PendingIntent intent, int errorCode)784     private void sendErrorInPendingIntent(@Nullable PendingIntent intent, int errorCode) {
785         if (intent != null) {
786             try {
787                 intent.send(errorCode);
788             } catch (PendingIntent.CanceledException ex) {
789             }
790         }
791     }
792 
793     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
sendErrorInPendingIntents(List<PendingIntent> intents, int errorCode)794     private void sendErrorInPendingIntents(List<PendingIntent> intents, int errorCode) {
795         if (intents == null) {
796             return;
797         }
798 
799         for (PendingIntent intent : intents) {
800             sendErrorInPendingIntent(intent, errorCode);
801         }
802     }
803 
804     /**
805      * Get sms interface manager object based on subscription.
806      *
807      * @return ICC SMS manager
808      */
809     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getIccSmsInterfaceManager(int subId)810     private @Nullable IccSmsInterfaceManager getIccSmsInterfaceManager(int subId) {
811         return getPhone(subId).getIccSmsInterfaceManager();
812     }
813 
getSubscriptionInfo(int subId)814     private SubscriptionInfo getSubscriptionInfo(int subId) {
815         SubscriptionManager manager = (SubscriptionManager) mContext
816                 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
817         return manager.getActiveSubscriptionInfo(subId);
818     }
819 
820     /**
821      * Get the capacity count of sms on Icc card.
822      */
823     @Override
getSmsCapacityOnIccForSubscriber(int subId)824     public int getSmsCapacityOnIccForSubscriber(int subId) {
825         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
826 
827         if (iccSmsIntMgr != null ) {
828             return iccSmsIntMgr.getSmsCapacityOnIcc(getCallingPackage(), null);
829         } else {
830             Rlog.e(LOG_TAG, "iccSmsIntMgr is null for " + " subId: " + subId);
831             return 0;
832         }
833     }
834 
835     /**
836      * Reset all cell broadcast ranges. Previously enabled ranges will become invalid after this.
837      *
838      * @param subId Subscription index
839      * @return {@code true} if succeeded, otherwise {@code false}.
840      */
841     @Override
resetAllCellBroadcastRanges(int subId)842     public boolean resetAllCellBroadcastRanges(int subId) {
843         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
844         if (iccSmsIntMgr != null) {
845             iccSmsIntMgr.resetAllCellBroadcastRanges();
846             return true;
847         } else {
848             Rlog.e(LOG_TAG, "iccSmsIntMgr is null for " + " subId: " + subId);
849             return false;
850         }
851     }
852 
853     /**
854      * Internal API to consistently format the debug log output of the cross-stack message id.
855      */
formatCrossStackMessageId(long id)856     public static String formatCrossStackMessageId(long id) {
857         return "{x-message-id:" + id + "}";
858     }
859 }
860