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