• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.content.pm.PackageManager.FEATURE_TELEPHONY_MESSAGING;
22 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23 import static android.telephony.TelephonyManager.ENABLE_FEATURE_MAPPING;
24 
25 import static com.android.internal.telephony.util.TelephonyUtils.checkDumpPermission;
26 
27 import android.annotation.NonNull;
28 import android.annotation.Nullable;
29 import android.app.ActivityManager;
30 import android.app.AppOpsManager;
31 import android.app.PendingIntent;
32 import android.app.compat.CompatChanges;
33 import android.compat.annotation.UnsupportedAppUsage;
34 import android.content.Context;
35 import android.content.pm.PackageManager;
36 import android.net.Uri;
37 import android.os.BaseBundle;
38 import android.os.Binder;
39 import android.os.Build;
40 import android.os.Bundle;
41 import android.os.SystemProperties;
42 import android.os.TelephonyServiceManager.ServiceRegisterer;
43 import android.os.UserHandle;
44 import android.provider.Telephony.Sms.Intents;
45 import android.telephony.CarrierConfigManager;
46 import android.telephony.SmsManager;
47 import android.telephony.SubscriptionInfo;
48 import android.telephony.SubscriptionManager;
49 import android.telephony.TelephonyFrameworkInitializer;
50 import android.telephony.TelephonyManager;
51 
52 import com.android.internal.annotations.VisibleForTesting;
53 import com.android.internal.telephony.flags.FeatureFlags;
54 import com.android.internal.telephony.subscription.SubscriptionManagerService;
55 import com.android.internal.telephony.util.TelephonyUtils;
56 import com.android.internal.util.IndentingPrintWriter;
57 import com.android.telephony.Rlog;
58 
59 import java.io.FileDescriptor;
60 import java.io.PrintWriter;
61 import java.nio.charset.StandardCharsets;
62 import java.util.Arrays;
63 import java.util.List;
64 import java.util.Locale;
65 
66 /**
67  * Implements the ISmsImplBase interface used in the SmsManager API.
68  */
69 public class SmsController extends ISmsImplBase {
70     static final String LOG_TAG = "SmsController";
71 
72     private final Context mContext;
73     private final PackageManager mPackageManager;
74     private final int mVendorApiLevel;
75 
76     @NonNull private final FeatureFlags mFlags;
77 
78     @VisibleForTesting
SmsController(Context context, @NonNull FeatureFlags flags)79     public SmsController(Context context, @NonNull FeatureFlags flags) {
80         mContext = context;
81         mFlags = flags;
82         mPackageManager = context.getPackageManager();
83         ServiceRegisterer smsServiceRegisterer = TelephonyFrameworkInitializer
84                 .getTelephonyServiceManager()
85                 .getSmsServiceRegisterer();
86         if (smsServiceRegisterer.get() == null) {
87             smsServiceRegisterer.register(this);
88         }
89 
90         mVendorApiLevel = SystemProperties.getInt(
91                 "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT);
92     }
93 
getPhone(int subId)94     private Phone getPhone(int subId) {
95         Phone phone = PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId));
96         if (phone == null) {
97             phone = PhoneFactory.getDefaultPhone();
98         }
99         return phone;
100     }
101 
getSmsPermissions(int subId)102     private SmsPermissions getSmsPermissions(int subId) {
103         Phone phone = getPhone(subId);
104 
105         return new SmsPermissions(phone, mContext,
106                 (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE));
107     }
108 
109     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
110     @Override
updateMessageOnIccEfForSubscriber(int subId, String callingPackage, int index, int status, byte[] pdu)111     public boolean updateMessageOnIccEfForSubscriber(int subId, String callingPackage, int index,
112             int status, byte[] pdu) {
113         if (callingPackage == null) {
114             callingPackage = getCallingPackage();
115         }
116         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
117         if (iccSmsIntMgr != null) {
118             return iccSmsIntMgr.updateMessageOnIccEf(callingPackage, index, status, pdu);
119         } else {
120             Rlog.e(LOG_TAG, "updateMessageOnIccEfForSubscriber iccSmsIntMgr is null"
121                     + " for Subscription: " + subId);
122             return false;
123         }
124     }
125 
126     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
127     @Override
copyMessageToIccEfForSubscriber(int subId, String callingPackage, int status, byte[] pdu, byte[] smsc)128     public boolean copyMessageToIccEfForSubscriber(int subId, String callingPackage, int status,
129             byte[] pdu, byte[] smsc) {
130         if (callingPackage == null) {
131             callingPackage = getCallingPackage();
132         }
133         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
134         if (iccSmsIntMgr != null) {
135             return iccSmsIntMgr.copyMessageToIccEf(callingPackage, status, pdu, smsc);
136         } else {
137             Rlog.e(LOG_TAG, "copyMessageToIccEfForSubscriber iccSmsIntMgr is null"
138                     + " for Subscription: " + subId);
139             return false;
140         }
141     }
142 
143     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
144     @Override
getAllMessagesFromIccEfForSubscriber(int subId, String callingPackage)145     public List<SmsRawData> getAllMessagesFromIccEfForSubscriber(int subId, String callingPackage) {
146         if (callingPackage == null) {
147             callingPackage = getCallingPackage();
148         }
149         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
150         if (iccSmsIntMgr != null) {
151             return iccSmsIntMgr.getAllMessagesFromIccEf(callingPackage);
152         } else {
153             Rlog.e(LOG_TAG, "getAllMessagesFromIccEfForSubscriber iccSmsIntMgr is"
154                     + " null for Subscription: " + subId);
155             return null;
156         }
157     }
158 
159     /**
160      * @deprecated Use {@link #sendDataForSubscriber(int, String, String, String, String, int,
161      * byte[], PendingIntent, PendingIntent)} instead
162      */
163     @Deprecated
164     @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)165     public void sendDataForSubscriber(int subId, String callingPackage, String destAddr,
166             String scAddr, int destPort, byte[] data, PendingIntent sentIntent,
167             PendingIntent deliveryIntent) {
168         sendDataForSubscriber(subId, callingPackage, null, destAddr, scAddr, destPort, data,
169                 sentIntent, deliveryIntent);
170     }
171 
172     @Override
sendDataForSubscriber(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent)173     public void sendDataForSubscriber(int subId, String callingPackage,
174             String callingAttributionTag, String destAddr, String scAddr, int destPort, byte[] data,
175             PendingIntent sentIntent, PendingIntent deliveryIntent) {
176         if (callingPackage == null) {
177             callingPackage = getCallingPackage();
178         }
179         UserHandle callingUser = Binder.getCallingUserHandle();
180 
181         Rlog.d(LOG_TAG, "sendDataForSubscriber caller=" + callingPackage);
182 
183         // Check if user is associated with the subscription
184         if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
185                 callingUser, destAddr)) {
186             TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId,
187                     Binder.getCallingUid(), callingPackage);
188             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_USER_NOT_ALLOWED);
189             return;
190         }
191 
192         // Perform FDN check
193         if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) {
194             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE);
195             return;
196         }
197 
198         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
199         if (iccSmsIntMgr != null) {
200             iccSmsIntMgr.sendData(callingPackage, callingUser.getIdentifier(),
201                     callingAttributionTag, destAddr, scAddr, destPort,
202                     data, sentIntent, deliveryIntent);
203         } else {
204             Rlog.e(LOG_TAG, "sendDataForSubscriber iccSmsIntMgr is null for"
205                     + " Subscription: " + subId);
206             // TODO: Use a more specific error code to replace RESULT_ERROR_GENERIC_FAILURE.
207             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
208         }
209     }
210 
sendDataForSubscriberWithSelfPermissionsInternal(int subId, String callingPackage, int callingUser, String callingAttributionTag, String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean isForVvm)211     private void sendDataForSubscriberWithSelfPermissionsInternal(int subId, String callingPackage,
212             int callingUser, String callingAttributionTag, String destAddr, String scAddr,
213             int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent,
214             boolean isForVvm) {
215         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
216         if (iccSmsIntMgr != null) {
217             iccSmsIntMgr.sendDataWithSelfPermissions(callingPackage, callingUser,
218                     callingAttributionTag, destAddr, scAddr, destPort, data, sentIntent,
219                     deliveryIntent, isForVvm);
220         } else {
221             Rlog.e(LOG_TAG, "sendText iccSmsIntMgr is null for"
222                     + " Subscription: " + subId);
223             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
224         }
225     }
226 
227     @NonNull
getCallingPackage()228     private String getCallingPackage() {
229         if (mFlags.hsumPackageManager()) {
230             PackageManager pm = mContext.createContextAsUser(Binder.getCallingUserHandle(), 0)
231                     .getPackageManager();
232             String[] packages = pm.getPackagesForUid(Binder.getCallingUid());
233             if (packages == null || packages.length == 0) return "";
234             return packages[0];
235         }
236         return mContext.getPackageManager().getPackagesForUid(Binder.getCallingUid())[0];
237     }
238 
239     @Override
sendTextForSubscriber(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp, long messageId)240     public void sendTextForSubscriber(int subId, String callingPackage,
241             String callingAttributionTag, String destAddr, String scAddr, String text,
242             PendingIntent sentIntent, PendingIntent deliveryIntent,
243             boolean persistMessageForNonDefaultSmsApp, long messageId) {
244         sendTextForSubscriber(subId, callingPackage, callingAttributionTag, destAddr, scAddr,
245                 text, sentIntent, deliveryIntent, persistMessageForNonDefaultSmsApp, messageId,
246                 false, false);
247 
248     }
249 
250     /**
251      * @param subId Subscription Id
252      * @param callingAttributionTag the attribution tag of the caller
253      * @param destAddr the address to send the message to
254      * @param scAddr is the service center address or null to use
255      *  the current default SMSC
256      * @param text the body of the message to send
257      * @param sentIntent if not NULL this <code>PendingIntent</code> is
258      *  broadcast when the message is successfully sent, or failed.
259      *  The result code will be <code>Activity.RESULT_OK</code> for success, or relevant errors
260      *  the sentIntent may include the extra "errorCode" containing a radio technology specific
261      *  value, generally only useful for troubleshooting.
262      * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
263      *  broadcast when the message is delivered to the recipient.  The
264      *  raw pdu of the status report is in the extended data ("pdu").
265      * @param skipFdnCheck if set to true, FDN check must be skipped .This is set in case of STK sms
266      *
267      * @hide
268      */
sendTextForSubscriber(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp, long messageId, boolean skipFdnCheck, boolean skipShortCodeCheck)269     public void sendTextForSubscriber(int subId, String callingPackage,
270             String callingAttributionTag, String destAddr, String scAddr, String text,
271             PendingIntent sentIntent, PendingIntent deliveryIntent,
272             boolean persistMessageForNonDefaultSmsApp, long messageId, boolean skipFdnCheck,
273             boolean skipShortCodeCheck) {
274         if (callingPackage == null) {
275             callingPackage = getCallingPackage();
276         }
277         UserHandle callingUser = Binder.getCallingUserHandle();
278 
279 
280         Rlog.d(LOG_TAG, "sendTextForSubscriber caller=" + callingPackage);
281 
282         if (skipFdnCheck || skipShortCodeCheck) {
283             if (mContext.checkCallingOrSelfPermission(
284                     android.Manifest.permission.MODIFY_PHONE_STATE)
285                     != PackageManager.PERMISSION_GRANTED) {
286                 throw new SecurityException("Requires MODIFY_PHONE_STATE permission.");
287             }
288         }
289         if (!getSmsPermissions(subId).checkCallingCanSendText(persistMessageForNonDefaultSmsApp,
290                 callingPackage, callingAttributionTag, "Sending SMS message")) {
291             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
292             return;
293         }
294 
295         // Check if user is associated with the subscription
296         boolean crossUserFullGranted = mContext.checkCallingOrSelfPermission(
297                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) == PERMISSION_GRANTED;
298         Rlog.d(LOG_TAG, "sendTextForSubscriber: caller has INTERACT_ACROSS_USERS_FULL? "
299                 + crossUserFullGranted);
300         if (!crossUserFullGranted
301                 && !TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
302                 Binder.getCallingUserHandle(), destAddr)) {
303             TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId,
304                     Binder.getCallingUid(), callingPackage);
305             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_USER_NOT_ALLOWED);
306             return;
307         }
308 
309         // Perform FDN check
310         if (!skipFdnCheck && isNumberBlockedByFDN(subId, destAddr, callingPackage)) {
311             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE);
312             return;
313         }
314 
315         enforceTelephonyFeatureWithException(callingPackage, "sendTextForSubscriber");
316 
317         long token = Binder.clearCallingIdentity();
318         SubscriptionInfo info;
319         try {
320             info = getSubscriptionInfo(subId);
321 
322             if (isBluetoothSubscription(info)) {
323                 sendBluetoothText(info, destAddr, text, sentIntent, deliveryIntent);
324             } else {
325                 sendIccText(subId, callingPackage, callingUser.getIdentifier(), destAddr, scAddr,
326                         text, sentIntent, deliveryIntent, persistMessageForNonDefaultSmsApp,
327                         messageId, skipShortCodeCheck);
328             }
329         } finally {
330             Binder.restoreCallingIdentity(token);
331         }
332     }
333 
isBluetoothSubscription(SubscriptionInfo info)334     private boolean isBluetoothSubscription(SubscriptionInfo info) {
335         return info != null
336                 && info.getSubscriptionType() == SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM;
337     }
338 
sendBluetoothText(SubscriptionInfo info, String destAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)339     private void sendBluetoothText(SubscriptionInfo info, String destAddr,
340             String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
341         BtSmsInterfaceManager btSmsInterfaceManager = new BtSmsInterfaceManager();
342         btSmsInterfaceManager.sendText(mContext, destAddr, text, sentIntent, deliveryIntent, info);
343     }
344 
sendIccText(int subId, String callingPackage, int callingUser, String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp, long messageId, boolean skipShortCodeCheck)345     private void sendIccText(int subId, String callingPackage, int callingUser, String destAddr,
346             String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
347             boolean persistMessageForNonDefaultSmsApp, long messageId, boolean skipShortCodeCheck) {
348         Rlog.d(LOG_TAG, "sendTextForSubscriber iccSmsIntMgr"
349                 + " Subscription: " + subId + " " + formatCrossStackMessageId(messageId));
350         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
351         if (iccSmsIntMgr != null) {
352             iccSmsIntMgr.sendText(callingPackage, callingUser, destAddr, scAddr, text, sentIntent,
353                     deliveryIntent, persistMessageForNonDefaultSmsApp, messageId,
354                     skipShortCodeCheck);
355         } else {
356             Rlog.e(LOG_TAG, "sendTextForSubscriber iccSmsIntMgr is null for"
357                     + " Subscription: " + subId + " " + formatCrossStackMessageId(messageId));
358             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
359         }
360     }
361 
sendTextForSubscriberWithSelfPermissionsInternal(int subId, String callingPackage, int callingUser, String callingAttributeTag, String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, boolean isForVvm)362     private void sendTextForSubscriberWithSelfPermissionsInternal(int subId, String callingPackage,
363             int callingUser, String callingAttributeTag, String destAddr, String scAddr,
364             String text, PendingIntent sentIntent, PendingIntent deliveryIntent,
365             boolean persistMessage, boolean isForVvm) {
366         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
367         if (iccSmsIntMgr != null) {
368             iccSmsIntMgr.sendTextWithSelfPermissions(callingPackage, callingUser,
369                     callingAttributeTag, destAddr, scAddr, text, sentIntent, deliveryIntent,
370                     persistMessage, isForVvm);
371         } else {
372             Rlog.e(LOG_TAG, "sendText iccSmsIntMgr is null for"
373                     + " Subscription: " + subId);
374             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
375         }
376     }
377 
378     @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)379     public void sendTextForSubscriberWithOptions(int subId, String callingPackage,
380             String callingAttributionTag, String destAddr, String scAddr, String parts,
381             PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage,
382             int priority, boolean expectMore, int validityPeriod) {
383         if (callingPackage == null) {
384             callingPackage = getCallingPackage();
385         }
386         UserHandle callingUser = Binder.getCallingUserHandle();
387 
388         Rlog.d(LOG_TAG, "sendTextForSubscriberWithOptions caller=" + callingPackage);
389 
390         // Check if user is associated with the subscription
391         if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
392                 Binder.getCallingUserHandle(), destAddr)) {
393             TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId,
394                     Binder.getCallingUid(), callingPackage);
395             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_USER_NOT_ALLOWED);
396             return;
397         }
398 
399         // Perform FDN check
400         if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) {
401             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE);
402             return;
403         }
404 
405         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
406         if (iccSmsIntMgr != null) {
407             iccSmsIntMgr.sendTextWithOptions(callingPackage, callingUser.getIdentifier(),
408                     callingAttributionTag, destAddr, scAddr, parts, sentIntent, deliveryIntent,
409                     persistMessage, priority, expectMore, validityPeriod);
410         } else {
411             Rlog.e(LOG_TAG, "sendTextWithOptions iccSmsIntMgr is null for"
412                     + " Subscription: " + subId);
413             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
414         }
415     }
416 
417     @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)418     public void sendMultipartTextForSubscriber(int subId, String callingPackage,
419             String callingAttributionTag, String destAddr, String scAddr, List<String> parts,
420             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
421             boolean persistMessageForNonDefaultSmsApp, long messageId) {
422         // This is different from the checking of other method. It prefers the package name
423         // returned by getCallPackage() for backward-compatibility.
424         callingPackage = getCallingPackage();
425         UserHandle callingUser = Binder.getCallingUserHandle();
426 
427         Rlog.d(LOG_TAG, "sendMultipartTextForSubscriber caller=" + callingPackage);
428 
429         // Check if user is associated with the subscription
430         if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
431                 Binder.getCallingUserHandle(), destAddr)) {
432             TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId,
433                     Binder.getCallingUid(), callingPackage);
434             sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_USER_NOT_ALLOWED);
435             return;
436         }
437 
438         enforceTelephonyFeatureWithException(callingPackage, "sendMultipartTextForSubscriber");
439 
440         // Perform FDN check
441         if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) {
442             sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE);
443             return;
444         }
445 
446         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
447         if (iccSmsIntMgr != null) {
448             iccSmsIntMgr.sendMultipartText(callingPackage, callingUser.getIdentifier(),
449                     callingAttributionTag, destAddr, scAddr, parts, sentIntents, deliveryIntents,
450                     persistMessageForNonDefaultSmsApp, messageId);
451         } else {
452             Rlog.e(LOG_TAG, "sendMultipartTextForSubscriber iccSmsIntMgr is null for"
453                     + " Subscription: " + subId + " " + formatCrossStackMessageId(messageId));
454             sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
455         }
456     }
457 
458     @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)459     public void sendMultipartTextForSubscriberWithOptions(int subId, String callingPackage,
460             String callingAttributionTag, String destAddr, String scAddr, List<String> parts,
461             List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents,
462             boolean persistMessage, int priority, boolean expectMore, int validityPeriod) {
463         if (callingPackage == null) {
464             callingPackage = getCallingPackage();
465         }
466         UserHandle callingUser = Binder.getCallingUserHandle();
467 
468         Rlog.d(LOG_TAG, "sendMultipartTextForSubscriberWithOptions caller=" + callingPackage);
469 
470         // Check if user is associated with the subscription
471         if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
472                 Binder.getCallingUserHandle(), destAddr)) {
473             TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId,
474                     Binder.getCallingUid(), callingPackage);
475             sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_USER_NOT_ALLOWED);
476             return;
477         }
478 
479         // Perform FDN check
480         if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) {
481             sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE);
482             return;
483         }
484 
485         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
486         if (iccSmsIntMgr != null) {
487             iccSmsIntMgr.sendMultipartTextWithOptions(callingPackage, callingUser.getIdentifier(),
488                     callingAttributionTag, destAddr, scAddr, parts, sentIntents, deliveryIntents,
489                     persistMessage, priority, expectMore, validityPeriod, 0L /* messageId */);
490         } else {
491             Rlog.e(LOG_TAG, "sendMultipartTextWithOptions iccSmsIntMgr is null for"
492                     + " Subscription: " + subId);
493             sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
494         }
495     }
496 
497     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
498     @Override
enableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType)499     public boolean enableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType) {
500         return enableCellBroadcastRangeForSubscriber(subId, messageIdentifier, messageIdentifier,
501                 ranType);
502     }
503 
504     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
505     @Override
enableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId, int ranType)506     public boolean enableCellBroadcastRangeForSubscriber(int subId, int startMessageId,
507             int endMessageId, int ranType) {
508         enforceTelephonyFeatureWithException(getCallingPackage(),
509                 "enableCellBroadcastRangeForSubscriber");
510 
511         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
512         if (iccSmsIntMgr != null) {
513             return iccSmsIntMgr.enableCellBroadcastRange(startMessageId, endMessageId, ranType);
514         } else {
515             Rlog.e(LOG_TAG, "enableCellBroadcastRangeForSubscriber iccSmsIntMgr is null for"
516                     + " Subscription: " + subId);
517         }
518         return false;
519     }
520 
521     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
522     @Override
disableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType)523     public boolean disableCellBroadcastForSubscriber(int subId,
524             int messageIdentifier, int ranType) {
525         return disableCellBroadcastRangeForSubscriber(subId, messageIdentifier, messageIdentifier,
526                 ranType);
527     }
528 
529     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
530     @Override
disableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId, int ranType)531     public boolean disableCellBroadcastRangeForSubscriber(int subId, int startMessageId,
532             int endMessageId, int ranType) {
533         enforceTelephonyFeatureWithException(getCallingPackage(),
534                 "disableCellBroadcastRangeForSubscriber");
535 
536         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
537         if (iccSmsIntMgr != null) {
538             return iccSmsIntMgr.disableCellBroadcastRange(startMessageId, endMessageId, ranType);
539         } else {
540             Rlog.e(LOG_TAG, "disableCellBroadcastRangeForSubscriber iccSmsIntMgr is null for"
541                     + " Subscription:" + subId);
542         }
543         return false;
544     }
545 
546     @Override
getPremiumSmsPermission(String packageName)547     public int getPremiumSmsPermission(String packageName) {
548         enforceTelephonyFeatureWithException(packageName, "getPremiumSmsPermission");
549 
550         return getPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName);
551     }
552 
553     @Override
getPremiumSmsPermissionForSubscriber(int subId, String packageName)554     public int getPremiumSmsPermissionForSubscriber(int subId, String packageName) {
555         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
556         if (iccSmsIntMgr != null) {
557             return iccSmsIntMgr.getPremiumSmsPermission(packageName);
558         } else {
559             Rlog.e(LOG_TAG, "getPremiumSmsPermissionForSubscriber iccSmsIntMgr is null");
560         }
561         //TODO Rakesh
562         return 0;
563     }
564 
565     @Override
setPremiumSmsPermission(String packageName, int permission)566     public void setPremiumSmsPermission(String packageName, int permission) {
567         enforceTelephonyFeatureWithException(packageName, "setPremiumSmsPermission");
568 
569         setPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName,
570                 permission);
571     }
572 
573     @Override
setPremiumSmsPermissionForSubscriber(int subId, String packageName, int permission)574     public void setPremiumSmsPermissionForSubscriber(int subId, String packageName,
575             int permission) {
576         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
577         if (iccSmsIntMgr != null) {
578             iccSmsIntMgr.setPremiumSmsPermission(packageName, permission);
579         } else {
580             Rlog.e(LOG_TAG, "setPremiumSmsPermissionForSubscriber iccSmsIntMgr is null");
581         }
582     }
583 
584     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
585     @Override
isImsSmsSupportedForSubscriber(int subId)586     public boolean isImsSmsSupportedForSubscriber(int subId) {
587         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
588         if (iccSmsIntMgr != null) {
589             return iccSmsIntMgr.isImsSmsSupported();
590         } else {
591             Rlog.e(LOG_TAG, "isImsSmsSupportedForSubscriber iccSmsIntMgr is null");
592         }
593         return false;
594     }
595 
596     @Override
isSmsSimPickActivityNeeded(int subId)597     public boolean isSmsSimPickActivityNeeded(int subId) {
598         final Context context = mContext.getApplicationContext();
599         ActivityManager am = context.getSystemService(ActivityManager.class);
600         // Don't show the SMS SIM Pick activity if it is not foreground.
601         boolean isCallingProcessForeground = am != null
602                 && am.getUidImportance(Binder.getCallingUid())
603                 == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
604         if (!isCallingProcessForeground) {
605             Rlog.d(LOG_TAG, "isSmsSimPickActivityNeeded: calling process not foreground. "
606                     + "Suppressing activity.");
607             return false;
608         }
609 
610         enforceTelephonyFeatureWithException(getCallingPackage(), "isSmsSimPickActivityNeeded");
611 
612         TelephonyManager telephonyManager =
613                 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
614         if (mFlags.enforceSubscriptionUserFilter()) {
615             int[] activeSubIds;
616             final UserHandle user = Binder.getCallingUserHandle();
617             final long identity = Binder.clearCallingIdentity();
618             try {
619                 activeSubIds = Arrays.stream(SubscriptionManagerService.getInstance()
620                         .getActiveSubIdList(true /*visibleOnly*/))
621                         .filter(sub -> SubscriptionManagerService.getInstance()
622                                 .isSubscriptionAssociatedWithUser(sub, user))
623                         .toArray();
624                 for (int activeSubId : activeSubIds) {
625                     // Check if the subId is associated with the caller user profile.
626                     if (activeSubId == subId) {
627                         return false;
628                     }
629                 }
630 
631                 // If reached here and multiple SIMs and subs present, need sms sim pick activity.
632                 return activeSubIds.length > 1 && telephonyManager.getSimCount() > 1;
633             } finally {
634                 Binder.restoreCallingIdentity(identity);
635             }
636         } else {
637             List<SubscriptionInfo> subInfoList;
638             final long identity = Binder.clearCallingIdentity();
639             try {
640                 subInfoList = SubscriptionManager.from(context).getActiveSubscriptionInfoList();
641             } finally {
642                 Binder.restoreCallingIdentity(identity);
643             }
644 
645             if (subInfoList != null) {
646                 final int subInfoLength = subInfoList.size();
647 
648                 for (int i = 0; i < subInfoLength; ++i) {
649                     final SubscriptionInfo sir = subInfoList.get(i);
650                     if (sir != null && sir.getSubscriptionId() == subId) {
651                         // The subscription id is valid, sms sim pick activity not needed
652                         return false;
653                     }
654                 }
655 
656                 // If reached here and multiple SIMs and subs present, need sms sim pick activity
657                 if (subInfoLength > 1 && telephonyManager.getSimCount() > 1) {
658                     return true;
659                 }
660             }
661             return false;
662         }
663     }
664 
665     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
666     @Override
getImsSmsFormatForSubscriber(int subId)667     public String getImsSmsFormatForSubscriber(int subId) {
668         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
669         if (iccSmsIntMgr != null) {
670             return iccSmsIntMgr.getImsSmsFormat();
671         } else {
672             Rlog.e(LOG_TAG, "getImsSmsFormatForSubscriber iccSmsIntMgr is null");
673         }
674         return null;
675     }
676 
677     @Override
injectSmsPduForSubscriber( int subId, byte[] pdu, String format, PendingIntent receivedIntent)678     public void injectSmsPduForSubscriber(
679             int subId, byte[] pdu, String format, PendingIntent receivedIntent) {
680         enforceTelephonyFeatureWithException(getCallingPackage(), "injectSmsPduForSubscriber");
681 
682         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
683         if (iccSmsIntMgr != null) {
684             iccSmsIntMgr.injectSmsPdu(pdu, format, receivedIntent);
685         } else {
686             Rlog.e(LOG_TAG, "injectSmsPduForSubscriber iccSmsIntMgr is null");
687             // RESULT_SMS_GENERIC_ERROR is documented for injectSmsPdu
688             sendErrorInPendingIntent(receivedIntent, Intents.RESULT_SMS_GENERIC_ERROR);
689         }
690     }
691 
692     /**
693      * Get preferred SMS subscription.
694      *
695      * @return User-defined default SMS subscription. If there is no default, return the active
696      * subscription if there is only one active. If no preference can be found, return
697      * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
698      */
699     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
700     @Override
getPreferredSmsSubscription()701     public int getPreferredSmsSubscription() {
702         // If there is a default, choose that one.
703         int defaultSubId = SubscriptionManagerService.getInstance().getDefaultSmsSubId();
704 
705         if (SubscriptionManager.isValidSubscriptionId(defaultSubId)) {
706             return defaultSubId;
707         }
708 
709         enforceTelephonyFeatureWithException(getCallingPackage(), "getPreferredSmsSubscription");
710 
711         // No default, if there is only one sub active, choose that as the "preferred" sub id.
712         long token = Binder.clearCallingIdentity();
713         try {
714             int[] activeSubs = SubscriptionManagerService.getInstance()
715                     .getActiveSubIdList(true /*visibleOnly*/);
716             if (activeSubs.length == 1) {
717                 return activeSubs[0];
718             }
719         } finally {
720             Binder.restoreCallingIdentity(token);
721         }
722         // No preference can be found.
723         return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
724     }
725 
726     /**
727      * Get SMS prompt property enabled or not
728      *
729      * @return True if SMS prompt is enabled.
730      */
731     @Override
isSMSPromptEnabled()732     public boolean isSMSPromptEnabled() {
733         return PhoneFactory.isSMSPromptEnabled();
734     }
735 
736     @Override
sendStoredText(int subId, String callingPkg, String callingAttributionTag, Uri messageUri, String scAddress, PendingIntent sentIntent, PendingIntent deliveryIntent)737     public void sendStoredText(int subId, String callingPkg, String callingAttributionTag,
738             Uri messageUri, String scAddress, PendingIntent sentIntent,
739             PendingIntent deliveryIntent) {
740         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
741         UserHandle callingUser = Binder.getCallingUserHandle();
742         if (!getCallingPackage().equals(callingPkg)) {
743             throw new SecurityException("sendStoredText: Package " + callingPkg
744                     + "does not belong to " + Binder.getCallingUid());
745         }
746         Rlog.d(LOG_TAG, "sendStoredText caller=" + callingPkg);
747 
748         if (iccSmsIntMgr != null) {
749             iccSmsIntMgr.sendStoredText(callingPkg, callingUser.getIdentifier(),
750                     callingAttributionTag, messageUri, scAddress, sentIntent, deliveryIntent);
751         } else {
752             Rlog.e(LOG_TAG, "sendStoredText iccSmsIntMgr is null for subscription: " + subId);
753             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
754         }
755     }
756 
757     @Override
sendStoredMultipartText(int subId, String callingPkg, String callingAttributionTag, Uri messageUri, String scAddress, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents)758     public void sendStoredMultipartText(int subId, String callingPkg, String callingAttributionTag,
759             Uri messageUri, String scAddress, List<PendingIntent> sentIntents,
760             List<PendingIntent> deliveryIntents) {
761         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
762         UserHandle callingUser = Binder.getCallingUserHandle();
763 
764         if (!getCallingPackage().equals(callingPkg)) {
765             throw new SecurityException("sendStoredMultipartText: Package " + callingPkg
766                     + " does not belong to " + Binder.getCallingUid());
767         }
768         Rlog.d(LOG_TAG, "sendStoredMultipartText caller=" + callingPkg);
769 
770         if (iccSmsIntMgr != null) {
771             iccSmsIntMgr.sendStoredMultipartText(callingPkg, callingUser.getIdentifier(),
772                     callingAttributionTag, messageUri, scAddress, sentIntents, deliveryIntents);
773         } else {
774             Rlog.e(LOG_TAG, "sendStoredMultipartText iccSmsIntMgr is null for subscription: "
775                     + subId);
776             sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
777         }
778     }
779 
780     @Override
getCarrierConfigValuesForSubscriber(int subId)781     public Bundle getCarrierConfigValuesForSubscriber(int subId) {
782         enforceTelephonyFeatureWithException(getCallingPackage(),
783                 "getCarrierConfigValuesForSubscriber");
784 
785         final long identity = Binder.clearCallingIdentity();
786         try {
787             final CarrierConfigManager configManager =
788                     (CarrierConfigManager)
789                             mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
790             return getMmsConfig(configManager.getConfigForSubId(subId));
791         } finally {
792             Binder.restoreCallingIdentity(identity);
793         }
794     }
795 
796     /**
797      * Filters a bundle to only contain MMS config variables.
798      *
799      * This is for use with bundles returned by CarrierConfigManager which contain MMS config and
800      * unrelated config. It is assumed that all MMS_CONFIG_* keys are present in the supplied
801      * bundle.
802      *
803      * @param config a Bundle that contains MMS config variables and possibly more.
804      * @return a new Bundle that only contains the MMS_CONFIG_* keys defined in SmsManager.
805      */
getMmsConfig(BaseBundle config)806     private static Bundle getMmsConfig(BaseBundle config) {
807         Bundle filtered = new Bundle();
808         filtered.putBoolean(
809                 SmsManager.MMS_CONFIG_APPEND_TRANSACTION_ID,
810                 config.getBoolean(SmsManager.MMS_CONFIG_APPEND_TRANSACTION_ID));
811         filtered.putBoolean(
812                 SmsManager.MMS_CONFIG_MMS_ENABLED,
813                 config.getBoolean(SmsManager.MMS_CONFIG_MMS_ENABLED));
814         filtered.putBoolean(
815                 SmsManager.MMS_CONFIG_GROUP_MMS_ENABLED,
816                 config.getBoolean(SmsManager.MMS_CONFIG_GROUP_MMS_ENABLED));
817         filtered.putBoolean(
818                 SmsManager.MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED,
819                 config.getBoolean(SmsManager.MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED));
820         filtered.putBoolean(
821                 SmsManager.MMS_CONFIG_ALIAS_ENABLED,
822                 config.getBoolean(SmsManager.MMS_CONFIG_ALIAS_ENABLED));
823         filtered.putBoolean(
824                 SmsManager.MMS_CONFIG_ALLOW_ATTACH_AUDIO,
825                 config.getBoolean(SmsManager.MMS_CONFIG_ALLOW_ATTACH_AUDIO));
826         filtered.putBoolean(
827                 SmsManager.MMS_CONFIG_MULTIPART_SMS_ENABLED,
828                 config.getBoolean(SmsManager.MMS_CONFIG_MULTIPART_SMS_ENABLED));
829         filtered.putBoolean(
830                 SmsManager.MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED,
831                 config.getBoolean(SmsManager.MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED));
832         filtered.putBoolean(
833                 SmsManager.MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION,
834                 config.getBoolean(SmsManager.MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION));
835         filtered.putBoolean(
836                 SmsManager.MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES,
837                 config.getBoolean(SmsManager.MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES));
838         filtered.putBoolean(
839                 SmsManager.MMS_CONFIG_MMS_READ_REPORT_ENABLED,
840                 config.getBoolean(SmsManager.MMS_CONFIG_MMS_READ_REPORT_ENABLED));
841         filtered.putBoolean(
842                 SmsManager.MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED,
843                 config.getBoolean(SmsManager.MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED));
844         filtered.putBoolean(
845                 SmsManager.MMS_CONFIG_CLOSE_CONNECTION,
846                 config.getBoolean(SmsManager.MMS_CONFIG_CLOSE_CONNECTION));
847         filtered.putInt(
848                 SmsManager.MMS_CONFIG_MAX_MESSAGE_SIZE,
849                 config.getInt(SmsManager.MMS_CONFIG_MAX_MESSAGE_SIZE));
850         filtered.putInt(
851                 SmsManager.MMS_CONFIG_MAX_IMAGE_WIDTH,
852                 config.getInt(SmsManager.MMS_CONFIG_MAX_IMAGE_WIDTH));
853         filtered.putInt(
854                 SmsManager.MMS_CONFIG_MAX_IMAGE_HEIGHT,
855                 config.getInt(SmsManager.MMS_CONFIG_MAX_IMAGE_HEIGHT));
856         filtered.putInt(
857                 SmsManager.MMS_CONFIG_RECIPIENT_LIMIT,
858                 config.getInt(SmsManager.MMS_CONFIG_RECIPIENT_LIMIT));
859         filtered.putInt(
860                 SmsManager.MMS_CONFIG_ALIAS_MIN_CHARS,
861                 config.getInt(SmsManager.MMS_CONFIG_ALIAS_MIN_CHARS));
862         filtered.putInt(
863                 SmsManager.MMS_CONFIG_ALIAS_MAX_CHARS,
864                 config.getInt(SmsManager.MMS_CONFIG_ALIAS_MAX_CHARS));
865         filtered.putInt(
866                 SmsManager.MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD,
867                 config.getInt(SmsManager.MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD));
868         filtered.putInt(
869                 SmsManager.MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD,
870                 config.getInt(SmsManager.MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD));
871         filtered.putInt(
872                 SmsManager.MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE,
873                 config.getInt(SmsManager.MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE));
874         filtered.putInt(
875                 SmsManager.MMS_CONFIG_SUBJECT_MAX_LENGTH,
876                 config.getInt(SmsManager.MMS_CONFIG_SUBJECT_MAX_LENGTH));
877         filtered.putInt(
878                 SmsManager.MMS_CONFIG_HTTP_SOCKET_TIMEOUT,
879                 config.getInt(SmsManager.MMS_CONFIG_HTTP_SOCKET_TIMEOUT));
880         filtered.putString(
881                 SmsManager.MMS_CONFIG_UA_PROF_TAG_NAME,
882                 config.getString(SmsManager.MMS_CONFIG_UA_PROF_TAG_NAME));
883         filtered.putString(
884                 SmsManager.MMS_CONFIG_USER_AGENT,
885                 config.getString(SmsManager.MMS_CONFIG_USER_AGENT));
886         filtered.putString(
887                 SmsManager.MMS_CONFIG_UA_PROF_URL,
888                 config.getString(SmsManager.MMS_CONFIG_UA_PROF_URL));
889         filtered.putString(
890                 SmsManager.MMS_CONFIG_HTTP_PARAMS,
891                 config.getString(SmsManager.MMS_CONFIG_HTTP_PARAMS));
892         filtered.putString(
893                 SmsManager.MMS_CONFIG_EMAIL_GATEWAY_NUMBER,
894                 config.getString(SmsManager.MMS_CONFIG_EMAIL_GATEWAY_NUMBER));
895         filtered.putString(
896                 SmsManager.MMS_CONFIG_NAI_SUFFIX,
897                 config.getString(SmsManager.MMS_CONFIG_NAI_SUFFIX));
898         filtered.putBoolean(
899                 SmsManager.MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS,
900                 config.getBoolean(SmsManager.MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS));
901         filtered.putBoolean(
902                 SmsManager.MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER,
903                 config.getBoolean(SmsManager.MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER));
904         return filtered;
905     }
906 
907     @Override
createAppSpecificSmsTokenWithPackageInfo( int subId, String callingPkg, String prefixes, PendingIntent intent)908     public String createAppSpecificSmsTokenWithPackageInfo(
909             int subId, String callingPkg, String prefixes, PendingIntent intent) {
910         if (callingPkg == null) {
911             callingPkg = getCallingPackage();
912         }
913 
914         enforceTelephonyFeatureWithException(callingPkg,
915                 "createAppSpecificSmsTokenWithPackageInfo");
916 
917         return getPhone(subId).getAppSmsManager().createAppSpecificSmsTokenWithPackageInfo(
918                 subId, callingPkg, prefixes, intent);
919     }
920 
921     @Override
createAppSpecificSmsToken(int subId, String callingPkg, PendingIntent intent)922     public String createAppSpecificSmsToken(int subId, String callingPkg, PendingIntent intent) {
923         if (callingPkg == null) {
924             callingPkg = getCallingPackage();
925         }
926 
927         enforceTelephonyFeatureWithException(callingPkg, "createAppSpecificSmsToken");
928 
929         return getPhone(subId).getAppSmsManager().createAppSpecificSmsToken(callingPkg, intent);
930     }
931 
932     @Override
setStorageMonitorMemoryStatusOverride(int subId, boolean isStorageAvailable)933     public void setStorageMonitorMemoryStatusOverride(int subId, boolean isStorageAvailable) {
934         Phone phone = getPhone(subId);
935         Context context;
936         if (phone != null) {
937             context = phone.getContext();
938         } else {
939             Rlog.e(LOG_TAG, "Phone Object is Null");
940             return;
941         }
942         // If it doesn't have modify phone state permission
943         // a SecurityException will be thrown.
944         if (context.checkPermission(android.Manifest
945                         .permission.MODIFY_PHONE_STATE, Binder.getCallingPid(),
946                         Binder.getCallingUid()) != PERMISSION_GRANTED) {
947             throw new SecurityException(
948                     "setStorageMonitorMemoryStatusOverride needs MODIFY_PHONE_STATE");
949         }
950         final long identity = Binder.clearCallingIdentity();
951         try {
952             phone.mSmsStorageMonitor.sendMemoryStatusOverride(isStorageAvailable);
953         } finally {
954             Binder.restoreCallingIdentity(identity);
955         }
956     }
957 
958     @Override
clearStorageMonitorMemoryStatusOverride(int subId)959     public void clearStorageMonitorMemoryStatusOverride(int subId) {
960         Phone phone = getPhone(subId);
961         Context context;
962         if (phone != null) {
963             context = phone.getContext();
964         } else {
965             Rlog.e(LOG_TAG, "Phone Object is Null");
966             return;
967         }
968         // If it doesn't have modify phone state permission
969         // a SecurityException will be thrown.
970         if (context.checkPermission(android.Manifest
971                         .permission.MODIFY_PHONE_STATE, Binder.getCallingPid(),
972                         Binder.getCallingUid()) != PERMISSION_GRANTED) {
973             throw new SecurityException(
974                     "clearStorageMonitorMemoryStatusOverride needs MODIFY_PHONE_STATE");
975         }
976         final long identity = Binder.clearCallingIdentity();
977         try {
978             phone.mSmsStorageMonitor.clearMemoryStatusOverride();
979         } finally {
980             Binder.restoreCallingIdentity(identity);
981         }
982     }
983 
984     @Override
checkSmsShortCodeDestination(int subId, String callingPackage, String callingFeatureId, String destAddress, String countryIso)985     public int checkSmsShortCodeDestination(int subId, String callingPackage,
986             String callingFeatureId, String destAddress, String countryIso) {
987         if (callingPackage == null) {
988             callingPackage = getCallingPackage();
989         }
990         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(getPhone(subId).getContext(),
991                 subId, callingPackage, callingFeatureId, "checkSmsShortCodeDestination")) {
992             return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
993         }
994         final long identity = Binder.clearCallingIdentity();
995         try {
996             return getPhone(subId).mSmsUsageMonitor.checkDestination(destAddress, countryIso);
997         } finally {
998             Binder.restoreCallingIdentity(identity);
999         }
1000     }
1001 
1002     /**
1003      * Internal API to send visual voicemail related SMS. This is not exposed outside the phone
1004      * process, and should be called only after verifying that the caller is the default VVM app.
1005      */
sendVisualVoicemailSmsForSubscriber(String callingPackage, int callingUser, String callingAttributionTag, int subId, String number, int port, String text, PendingIntent sentIntent)1006     public void sendVisualVoicemailSmsForSubscriber(String callingPackage, int callingUser,
1007             String callingAttributionTag, int subId, String number, int port, String text,
1008             PendingIntent sentIntent) {
1009         Rlog.d(LOG_TAG, "sendVisualVoicemailSmsForSubscriber caller=" + callingPackage);
1010 
1011         // Do not send non-emergency SMS in ECBM as it forces device to exit ECBM.
1012         if(getPhone(subId).isInEcm()) {
1013             Rlog.d(LOG_TAG, "sendVisualVoicemailSmsForSubscriber: Do not send non-emergency "
1014                     + "SMS in ECBM as it forces device to exit ECBM.");
1015             return;
1016         }
1017 
1018         // Check if user is associated with the subscription
1019         if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
1020                 Binder.getCallingUserHandle(), number)) {
1021             TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId,
1022                     Binder.getCallingUid(), callingPackage);
1023             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_USER_NOT_ALLOWED);
1024             return;
1025         }
1026 
1027         if (port == 0) {
1028             sendTextForSubscriberWithSelfPermissionsInternal(subId, callingPackage, callingUser,
1029                     callingAttributionTag, number, null, text, sentIntent, null, false,
1030                     true /* isForVvm */);
1031         } else {
1032             byte[] data = text.getBytes(StandardCharsets.UTF_8);
1033             sendDataForSubscriberWithSelfPermissionsInternal(subId, callingPackage, callingUser,
1034                     callingAttributionTag, number, null, (short) port, data, sentIntent, null,
1035                     true /* isForVvm */);
1036         }
1037     }
1038 
1039     @Override
getSmscAddressFromIccEfForSubscriber(int subId, String callingPackage)1040     public String getSmscAddressFromIccEfForSubscriber(int subId, String callingPackage) {
1041         if (callingPackage == null) {
1042             callingPackage = getCallingPackage();
1043         }
1044 
1045         enforceTelephonyFeatureWithException(callingPackage,
1046                 "getSmscAddressFromIccEfForSubscriber");
1047 
1048         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
1049         if (iccSmsIntMgr != null) {
1050             return iccSmsIntMgr.getSmscAddressFromIccEf(callingPackage);
1051         } else {
1052             Rlog.e(LOG_TAG, "getSmscAddressFromIccEfForSubscriber iccSmsIntMgr is null"
1053                     + " for Subscription: " + subId);
1054             return null;
1055         }
1056     }
1057 
1058     @Override
setSmscAddressOnIccEfForSubscriber( String smsc, int subId, String callingPackage)1059     public boolean setSmscAddressOnIccEfForSubscriber(
1060             String smsc, int subId, String callingPackage) {
1061         if (callingPackage == null) {
1062             callingPackage = getCallingPackage();
1063         }
1064 
1065         enforceTelephonyFeatureWithException(callingPackage,
1066                 "setSmscAddressOnIccEfForSubscriber");
1067 
1068         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
1069         if (iccSmsIntMgr != null) {
1070             return iccSmsIntMgr.setSmscAddressOnIccEf(callingPackage, smsc);
1071         } else {
1072             Rlog.e(LOG_TAG, "setSmscAddressOnIccEfForSubscriber iccSmsIntMgr is null"
1073                     + " for Subscription: " + subId);
1074             return false;
1075         }
1076     }
1077 
1078     /**
1079      * Triggered by `adb shell dumpsys isms`
1080      */
1081     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1082     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1083         if (!checkDumpPermission(mContext, LOG_TAG, pw)) {
1084             return;
1085         }
1086 
1087         IndentingPrintWriter indentingPW =
1088                 new IndentingPrintWriter(pw, "    " /* singleIndent */);
1089         for (Phone phone : PhoneFactory.getPhones()) {
1090             int subId = phone.getSubId();
1091             indentingPW.println(String.format("SmsManager for subId = %d:", subId));
1092             indentingPW.increaseIndent();
1093             if (getIccSmsInterfaceManager(subId) != null) {
1094                 getIccSmsInterfaceManager(subId).dump(fd, indentingPW, args);
1095             }
1096             indentingPW.decreaseIndent();
1097         }
1098         indentingPW.flush();
1099     }
1100 
1101     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
sendErrorInPendingIntent(@ullable PendingIntent intent, int errorCode)1102     private void sendErrorInPendingIntent(@Nullable PendingIntent intent, int errorCode) {
1103         if (intent != null) {
1104             try {
1105                 intent.send(errorCode);
1106             } catch (PendingIntent.CanceledException ex) {
1107             }
1108         }
1109     }
1110 
1111     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
sendErrorInPendingIntents(List<PendingIntent> intents, int errorCode)1112     private void sendErrorInPendingIntents(List<PendingIntent> intents, int errorCode) {
1113         if (intents == null) {
1114             return;
1115         }
1116 
1117         for (PendingIntent intent : intents) {
1118             sendErrorInPendingIntent(intent, errorCode);
1119         }
1120     }
1121 
1122     /**
1123      * Get sms interface manager object based on subscription.
1124      *
1125      * @return ICC SMS manager
1126      */
1127     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getIccSmsInterfaceManager(int subId)1128     private @Nullable IccSmsInterfaceManager getIccSmsInterfaceManager(int subId) {
1129         return getPhone(subId).getIccSmsInterfaceManager();
1130     }
1131 
getSubscriptionInfo(int subId)1132     private SubscriptionInfo getSubscriptionInfo(int subId) {
1133         SubscriptionManager manager = (SubscriptionManager) mContext
1134                 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
1135         return manager.getActiveSubscriptionInfo(subId);
1136     }
1137 
1138     /**
1139      * Get the capacity count of sms on Icc card.
1140      */
1141     @Override
getSmsCapacityOnIccForSubscriber(int subId)1142     public int getSmsCapacityOnIccForSubscriber(int subId) {
1143         enforceTelephonyFeatureWithException(getCallingPackage(),
1144                 "getSmsCapacityOnIccForSubscriber");
1145 
1146         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
1147 
1148         if (iccSmsIntMgr != null ) {
1149             return iccSmsIntMgr.getSmsCapacityOnIcc(getCallingPackage(), null);
1150         } else {
1151             Rlog.e(LOG_TAG, "iccSmsIntMgr is null for " + " subId: " + subId);
1152             return 0;
1153         }
1154     }
1155 
1156     /**
1157      * Reset all cell broadcast ranges. Previously enabled ranges will become invalid after this.
1158      *
1159      * @param subId Subscription index
1160      * @return {@code true} if succeeded, otherwise {@code false}.
1161      */
1162     @Override
resetAllCellBroadcastRanges(int subId)1163     public boolean resetAllCellBroadcastRanges(int subId) {
1164         enforceTelephonyFeatureWithException(getCallingPackage(),
1165                 "resetAllCellBroadcastRanges");
1166 
1167         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
1168         if (iccSmsIntMgr != null) {
1169             iccSmsIntMgr.resetAllCellBroadcastRanges();
1170             return true;
1171         } else {
1172             Rlog.e(LOG_TAG, "iccSmsIntMgr is null for " + " subId: " + subId);
1173             return false;
1174         }
1175     }
1176 
1177     /**
1178      * Internal API to consistently format the debug log output of the cross-stack message id.
1179      */
formatCrossStackMessageId(long id)1180     public static String formatCrossStackMessageId(long id) {
1181         return "{x-message-id:" + id + "}";
1182     }
1183 
1184     /**
1185      * The following function checks if destination address or smsc is blocked due to FDN.
1186      * @param subId subscription ID
1187      * @param destAddr destination address of the message
1188      * @return true if either destAddr or smscAddr is blocked due to FDN.
1189      */
1190     @VisibleForTesting
isNumberBlockedByFDN(int subId, String destAddr, String callingPackage)1191     public boolean isNumberBlockedByFDN(int subId, String destAddr, String callingPackage) {
1192         int phoneId = SubscriptionManager.getPhoneId(subId);
1193         if (!FdnUtils.isFdnEnabled(phoneId)) {
1194             return false;
1195         }
1196 
1197         // Skip FDN check for emergency numbers
1198         if (!TelephonyCapabilities.supportsTelephonyCalling(mFlags, mContext)) return false;
1199         TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
1200         if (tm != null && tm.isEmergencyNumber(destAddr)) {
1201             return false;
1202         }
1203 
1204         // Check if destAddr is present in FDN list
1205         String defaultCountryIso = tm.getSimCountryIso().toUpperCase(Locale.ENGLISH);
1206         if (FdnUtils.isNumberBlockedByFDN(phoneId, destAddr, defaultCountryIso)) {
1207             return true;
1208         }
1209 
1210         // Get SMSC address for this subscription
1211         IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
1212         String smscAddr;
1213         if (iccSmsIntMgr != null) {
1214             long identity = Binder.clearCallingIdentity();
1215             try {
1216                 smscAddr =  iccSmsIntMgr.getSmscAddressFromIccEf(callingPackage);
1217             } finally {
1218                 Binder.restoreCallingIdentity(identity);
1219             }
1220         } else {
1221             Rlog.e(LOG_TAG, "getSmscAddressFromIccEfForSubscriber iccSmsIntMgr is null"
1222                     + " for Subscription: " + subId);
1223             return true;
1224         }
1225 
1226         // Check if smscAddr is present in FDN list
1227         return FdnUtils.isNumberBlockedByFDN(phoneId, smscAddr, defaultCountryIso);
1228     }
1229 
1230     /**
1231      * Gets the message size of WAP from the cache.
1232      *
1233      * @param locationUrl the location to use as a key for looking up the size in the cache.
1234      * The locationUrl may or may not have the transactionId appended to the url.
1235      *
1236      * @return long representing the message size
1237      * @throws java.util.NoSuchElementException if the WAP push doesn't exist in the cache
1238      * @throws IllegalArgumentException if the locationUrl is empty
1239      */
1240     @Override
getWapMessageSize(@onNull String locationUrl)1241     public long getWapMessageSize(@NonNull String locationUrl) {
1242         byte[] bytes = locationUrl.getBytes(StandardCharsets.ISO_8859_1);
1243         return WapPushCache.getWapMessageSize(bytes);
1244     }
1245 
1246     /**
1247      * Make sure the device has required telephony feature
1248      *
1249      * @throws UnsupportedOperationException if the device does not have required telephony feature
1250      */
enforceTelephonyFeatureWithException(@ullable String callingPackage, @NonNull String methodName)1251     private void enforceTelephonyFeatureWithException(@Nullable String callingPackage,
1252             @NonNull String methodName) {
1253         if (callingPackage == null || mPackageManager == null) {
1254             return;
1255         }
1256 
1257         if (!CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, callingPackage,
1258                 Binder.getCallingUserHandle())
1259                 || mVendorApiLevel < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
1260             // Skip to check associated telephony feature,
1261             // if compatibility change is not enabled for the current process or
1262             // the SDK version of vendor partition is less than Android V.
1263             return;
1264         }
1265 
1266         if (!mPackageManager.hasSystemFeature(FEATURE_TELEPHONY_MESSAGING)) {
1267             throw new UnsupportedOperationException(
1268                     methodName + " is unsupported without " + FEATURE_TELEPHONY_MESSAGING);
1269         }
1270     }
1271 }