1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.telephony; 18 19 import static android.os.PowerWhitelistManager.REASON_EVENT_MMS; 20 import static android.os.PowerWhitelistManager.REASON_EVENT_SMS; 21 import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; 22 import static android.provider.Telephony.Sms.Intents.RESULT_SMS_DATABASE_ERROR; 23 import static android.provider.Telephony.Sms.Intents.RESULT_SMS_DISPATCH_FAILURE; 24 import static android.provider.Telephony.Sms.Intents.RESULT_SMS_INVALID_URI; 25 import static android.provider.Telephony.Sms.Intents.RESULT_SMS_NULL_MESSAGE; 26 import static android.provider.Telephony.Sms.Intents.RESULT_SMS_NULL_PDU; 27 import static android.service.carrier.CarrierMessagingService.RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE; 28 import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA; 29 30 import android.annotation.IntDef; 31 import android.annotation.Nullable; 32 import android.app.Activity; 33 import android.app.AppOpsManager; 34 import android.app.BroadcastOptions; 35 import android.app.Notification; 36 import android.app.NotificationManager; 37 import android.app.PendingIntent; 38 import android.compat.annotation.UnsupportedAppUsage; 39 import android.content.BroadcastReceiver; 40 import android.content.ComponentName; 41 import android.content.ContentResolver; 42 import android.content.ContentUris; 43 import android.content.ContentValues; 44 import android.content.Context; 45 import android.content.Intent; 46 import android.content.IntentFilter; 47 import android.content.pm.IPackageManager; 48 import android.content.pm.PackageManager; 49 import android.database.Cursor; 50 import android.database.SQLException; 51 import android.net.Uri; 52 import android.os.AsyncResult; 53 import android.os.Build; 54 import android.os.Bundle; 55 import android.os.Message; 56 import android.os.PowerManager; 57 import android.os.PowerWhitelistManager; 58 import android.os.RemoteException; 59 import android.os.ServiceManager; 60 import android.os.UserHandle; 61 import android.os.UserManager; 62 import android.os.storage.StorageManager; 63 import android.provider.Telephony; 64 import android.provider.Telephony.Sms.Intents; 65 import android.service.carrier.CarrierMessagingService; 66 import android.telephony.SmsMessage; 67 import android.telephony.SubscriptionManager; 68 import android.telephony.TelephonyManager; 69 import android.util.LocalLog; 70 import android.util.Pair; 71 72 import com.android.internal.R; 73 import com.android.internal.annotations.VisibleForTesting; 74 import com.android.internal.telephony.SmsConstants.MessageClass; 75 import com.android.internal.telephony.metrics.TelephonyMetrics; 76 import com.android.internal.telephony.util.NotificationChannelController; 77 import com.android.internal.telephony.util.TelephonyUtils; 78 import com.android.internal.util.HexDump; 79 import com.android.internal.util.IndentingPrintWriter; 80 import com.android.internal.util.State; 81 import com.android.internal.util.StateMachine; 82 import com.android.telephony.Rlog; 83 84 import java.io.ByteArrayOutputStream; 85 import java.io.FileDescriptor; 86 import java.io.PrintWriter; 87 import java.lang.annotation.Retention; 88 import java.lang.annotation.RetentionPolicy; 89 import java.util.ArrayList; 90 import java.util.Arrays; 91 import java.util.HashMap; 92 import java.util.List; 93 import java.util.ListIterator; 94 import java.util.Map; 95 96 /** 97 * This class broadcasts incoming SMS messages to interested apps after storing them in the 98 * SmsProvider "raw" table and ACKing them to the SMSC. After each message has been broadcast, its 99 * parts are removed from the raw table. If the device crashes after ACKing but before the broadcast 100 * completes, the pending messages will be rebroadcast on the next boot. 101 * 102 * <p>The state machine starts in {@link IdleState} state. When we receive a new SMS from the radio, 103 * the wakelock is acquired, then transition to {@link DeliveringState} state, where the message is 104 * saved to the raw table, then acknowledged to the modem which in turn acknowledges it to the SMSC. 105 * 106 * <p>After saving the SMS, if the message is complete (either single-part or the final segment of a 107 * multi-part SMS), we broadcast the completed PDUs as an ordered broadcast, then transition to 108 * {@link WaitingState} state to wait for the broadcast to complete. When the local 109 * {@link BroadcastReceiver} is called with the result, it sends {@link #EVENT_BROADCAST_COMPLETE} 110 * to the state machine, causing us to either broadcast the next pending message (if one has arrived 111 * while waiting for the broadcast to complete), or to transition back to the halted state after all 112 * messages are processed. Then the wakelock is released and we wait for the next SMS. 113 */ 114 public abstract class InboundSmsHandler extends StateMachine { 115 protected static final boolean DBG = true; 116 protected static final boolean VDBG = false; // STOPSHIP if true, logs user data 117 118 /** Query projection for checking for duplicate message segments. */ 119 private static final String[] PDU_DELETED_FLAG_PROJECTION = { 120 "pdu", 121 "deleted" 122 }; 123 124 /** Mapping from DB COLUMN to PDU_SEQUENCE_PORT PROJECTION index */ 125 private static final Map<Integer, Integer> PDU_DELETED_FLAG_PROJECTION_INDEX_MAPPING = 126 new HashMap<Integer, Integer>() {{ 127 put(PDU_COLUMN, 0); 128 put(DELETED_FLAG_COLUMN, 1); 129 }}; 130 131 /** Query projection for combining concatenated message segments. */ 132 private static final String[] PDU_SEQUENCE_PORT_PROJECTION = { 133 "pdu", 134 "sequence", 135 "destination_port", 136 "display_originating_addr", 137 "date" 138 }; 139 140 /** Mapping from DB COLUMN to PDU_SEQUENCE_PORT PROJECTION index */ 141 private static final Map<Integer, Integer> PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING = 142 new HashMap<Integer, Integer>() {{ 143 put(PDU_COLUMN, 0); 144 put(SEQUENCE_COLUMN, 1); 145 put(DESTINATION_PORT_COLUMN, 2); 146 put(DISPLAY_ADDRESS_COLUMN, 3); 147 put(DATE_COLUMN, 4); 148 }}; 149 150 public static final int PDU_COLUMN = 0; 151 public static final int SEQUENCE_COLUMN = 1; 152 public static final int DESTINATION_PORT_COLUMN = 2; 153 public static final int DATE_COLUMN = 3; 154 public static final int REFERENCE_NUMBER_COLUMN = 4; 155 public static final int COUNT_COLUMN = 5; 156 public static final int ADDRESS_COLUMN = 6; 157 public static final int ID_COLUMN = 7; 158 public static final int MESSAGE_BODY_COLUMN = 8; 159 public static final int DISPLAY_ADDRESS_COLUMN = 9; 160 public static final int DELETED_FLAG_COLUMN = 10; 161 public static final int SUBID_COLUMN = 11; 162 163 public static final String SELECT_BY_ID = "_id=?"; 164 165 /** New SMS received as an AsyncResult. */ 166 public static final int EVENT_NEW_SMS = 1; 167 168 /** Message type containing a {@link InboundSmsTracker} ready to broadcast to listeners. */ 169 public static final int EVENT_BROADCAST_SMS = 2; 170 171 /** Message from resultReceiver notifying {@link WaitingState} of a completed broadcast. */ 172 public static final int EVENT_BROADCAST_COMPLETE = 3; 173 174 /** Sent on exit from {@link WaitingState} to return to idle after sending all broadcasts. */ 175 private static final int EVENT_RETURN_TO_IDLE = 4; 176 177 /** Release wakelock after {@link #mWakeLockTimeout} when returning to idle state. */ 178 private static final int EVENT_RELEASE_WAKELOCK = 5; 179 180 /** Sent by {@link SmsBroadcastUndelivered} after cleaning the raw table. */ 181 public static final int EVENT_START_ACCEPTING_SMS = 6; 182 183 /** New SMS received as an AsyncResult. */ 184 public static final int EVENT_INJECT_SMS = 7; 185 186 /** Update the sms tracker */ 187 public static final int EVENT_UPDATE_TRACKER = 8; 188 189 /** BroadcastReceiver timed out waiting for an intent */ 190 public static final int EVENT_RECEIVER_TIMEOUT = 9; 191 192 /** Wakelock release delay when returning to idle state. */ 193 private static final int WAKELOCK_TIMEOUT = 3000; 194 195 /** Received SMS was not injected. */ 196 public static final int SOURCE_NOT_INJECTED = 0; 197 198 /** Received SMS was received over IMS and injected. */ 199 public static final int SOURCE_INJECTED_FROM_IMS = 1; 200 201 /** Received SMS was injected from source different than IMS. */ 202 public static final int SOURCE_INJECTED_FROM_UNKNOWN = 2; 203 204 @Retention(RetentionPolicy.SOURCE) 205 @IntDef(prefix = {"SOURCE_"}, 206 value = { 207 SOURCE_NOT_INJECTED, 208 SOURCE_INJECTED_FROM_IMS, 209 SOURCE_INJECTED_FROM_UNKNOWN 210 }) 211 public @interface SmsSource {} 212 213 // The notitfication tag used when showing a notification. The combination of notification tag 214 // and notification id should be unique within the phone app. 215 @VisibleForTesting 216 public static final String NOTIFICATION_TAG = "InboundSmsHandler"; 217 @VisibleForTesting 218 public static final int NOTIFICATION_ID_NEW_MESSAGE = 1; 219 220 /** URI for raw table of SMS provider. */ 221 protected static final Uri sRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw"); 222 protected static final Uri sRawUriPermanentDelete = 223 Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete"); 224 225 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 226 protected final Context mContext; 227 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 228 private final ContentResolver mResolver; 229 230 /** Special handler for WAP push messages. */ 231 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 232 private final WapPushOverSms mWapPush; 233 234 /** Wake lock to ensure device stays awake while dispatching the SMS intents. */ 235 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 236 private final PowerManager.WakeLock mWakeLock; 237 238 /** DefaultState throws an exception or logs an error for unhandled message types. */ 239 private final DefaultState mDefaultState = new DefaultState(); 240 241 /** Startup state. Waiting for {@link SmsBroadcastUndelivered} to complete. */ 242 private final StartupState mStartupState = new StartupState(); 243 244 /** Idle state. Waiting for messages to process. */ 245 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 246 private final IdleState mIdleState = new IdleState(); 247 248 /** Delivering state. Saves the PDU in the raw table and acknowledges to SMSC. */ 249 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 250 private final DeliveringState mDeliveringState = new DeliveringState(); 251 252 /** Broadcasting state. Waits for current broadcast to complete before delivering next. */ 253 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 254 private final WaitingState mWaitingState = new WaitingState(); 255 256 /** Helper class to check whether storage is available for incoming messages. */ 257 protected SmsStorageMonitor mStorageMonitor; 258 259 private final boolean mSmsReceiveDisabled; 260 261 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 262 protected Phone mPhone; 263 264 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 265 private UserManager mUserManager; 266 267 protected TelephonyMetrics mMetrics = TelephonyMetrics.getInstance(); 268 269 private LocalLog mLocalLog = new LocalLog(64); 270 private LocalLog mCarrierServiceLocalLog = new LocalLog(10); 271 272 PowerWhitelistManager mPowerWhitelistManager; 273 274 protected CellBroadcastServiceManager mCellBroadcastServiceManager; 275 276 // Delete permanently from raw table 277 private final int DELETE_PERMANENTLY = 1; 278 // Only mark deleted, but keep in db for message de-duping 279 private final int MARK_DELETED = 2; 280 281 private static String ACTION_OPEN_SMS_APP = 282 "com.android.internal.telephony.OPEN_DEFAULT_SMS_APP"; 283 284 /** Timeout for releasing wakelock */ 285 private int mWakeLockTimeout; 286 287 private List<SmsFilter> mSmsFilters; 288 289 /** 290 * Create a new SMS broadcast helper. 291 * @param name the class name for logging 292 * @param context the context of the phone app 293 * @param storageMonitor the SmsStorageMonitor to check for storage availability 294 */ InboundSmsHandler(String name, Context context, SmsStorageMonitor storageMonitor, Phone phone)295 protected InboundSmsHandler(String name, Context context, SmsStorageMonitor storageMonitor, 296 Phone phone) { 297 super(name); 298 299 mContext = context; 300 mStorageMonitor = storageMonitor; 301 mPhone = phone; 302 mResolver = context.getContentResolver(); 303 mWapPush = new WapPushOverSms(context); 304 305 boolean smsCapable = mContext.getResources().getBoolean( 306 com.android.internal.R.bool.config_sms_capable); 307 mSmsReceiveDisabled = !TelephonyManager.from(mContext).getSmsReceiveCapableForPhone( 308 mPhone.getPhoneId(), smsCapable); 309 310 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 311 mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, name); 312 mWakeLock.acquire(); // wake lock released after we enter idle state 313 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 314 mPowerWhitelistManager = 315 (PowerWhitelistManager) mContext.getSystemService(Context.POWER_WHITELIST_MANAGER); 316 mCellBroadcastServiceManager = new CellBroadcastServiceManager(context, phone); 317 318 mSmsFilters = createDefaultSmsFilters(); 319 320 addState(mDefaultState); 321 addState(mStartupState, mDefaultState); 322 addState(mIdleState, mDefaultState); 323 addState(mDeliveringState, mDefaultState); 324 addState(mWaitingState, mDeliveringState); 325 326 setInitialState(mStartupState); 327 if (DBG) log("created InboundSmsHandler"); 328 } 329 330 /** 331 * Tell the state machine to quit after processing all messages. 332 */ dispose()333 public void dispose() { 334 quit(); 335 } 336 337 /** 338 * Dispose of the WAP push object and release the wakelock. 339 */ 340 @Override onQuitting()341 protected void onQuitting() { 342 mWapPush.dispose(); 343 mCellBroadcastServiceManager.disable(); 344 345 while (mWakeLock.isHeld()) { 346 mWakeLock.release(); 347 } 348 } 349 350 // CAF_MSIM Is this used anywhere ? if not remove it 351 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getPhone()352 public Phone getPhone() { 353 return mPhone; 354 } 355 356 @Override getWhatToString(int what)357 protected String getWhatToString(int what) { 358 String whatString; 359 switch (what) { 360 case EVENT_NEW_SMS: 361 whatString = "EVENT_NEW_SMS"; 362 break; 363 case EVENT_BROADCAST_SMS: 364 whatString = "EVENT_BROADCAST_SMS"; 365 break; 366 case EVENT_BROADCAST_COMPLETE: 367 whatString = "EVENT_BROADCAST_COMPLETE"; 368 break; 369 case EVENT_RETURN_TO_IDLE: 370 whatString = "EVENT_RETURN_TO_IDLE"; 371 break; 372 case EVENT_RELEASE_WAKELOCK: 373 whatString = "EVENT_RELEASE_WAKELOCK"; 374 break; 375 case EVENT_START_ACCEPTING_SMS: 376 whatString = "EVENT_START_ACCEPTING_SMS"; 377 break; 378 case EVENT_INJECT_SMS: 379 whatString = "EVENT_INJECT_SMS"; 380 break; 381 case EVENT_UPDATE_TRACKER: 382 whatString = "EVENT_UPDATE_TRACKER"; 383 break; 384 case EVENT_RECEIVER_TIMEOUT: 385 whatString = "EVENT_RECEIVER_TIMEOUT"; 386 break; 387 default: 388 whatString = "UNKNOWN EVENT " + what; 389 } 390 return whatString; 391 } 392 393 /** 394 * This parent state throws an exception (for debug builds) or prints an error for unhandled 395 * message types. 396 */ 397 private class DefaultState extends State { 398 @Override processMessage(Message msg)399 public boolean processMessage(Message msg) { 400 switch (msg.what) { 401 default: { 402 String errorText = "processMessage: unhandled message type " 403 + getWhatToString(msg.what) + " currState=" 404 + getCurrentState().getName(); 405 if (TelephonyUtils.IS_DEBUGGABLE) { 406 loge("---- Dumping InboundSmsHandler ----"); 407 loge("Total records=" + getLogRecCount()); 408 for (int i = Math.max(getLogRecSize() - 20, 0); i < getLogRecSize(); i++) { 409 // getLogRec(i).toString() will call the overridden getWhatToString 410 // method which has more information 411 loge("Rec[%d]: %s\n" + i + getLogRec(i).toString()); 412 } 413 loge("---- Dumped InboundSmsHandler ----"); 414 415 throw new RuntimeException(errorText); 416 } else { 417 loge(errorText); 418 } 419 break; 420 } 421 } 422 return HANDLED; 423 } 424 } 425 426 /** 427 * The Startup state waits for {@link SmsBroadcastUndelivered} to process the raw table and 428 * notify the state machine to broadcast any complete PDUs that might not have been broadcast. 429 */ 430 private class StartupState extends State { 431 @Override enter()432 public void enter() { 433 if (DBG) log("StartupState.enter: entering StartupState"); 434 // Set wakelock timeout to 0 during startup, this will ensure that the wakelock is not 435 // held if there are no pending messages to be handled. 436 setWakeLockTimeout(0); 437 } 438 439 @Override processMessage(Message msg)440 public boolean processMessage(Message msg) { 441 log("StartupState.processMessage: processing " + getWhatToString(msg.what)); 442 switch (msg.what) { 443 case EVENT_NEW_SMS: 444 case EVENT_INJECT_SMS: 445 case EVENT_BROADCAST_SMS: 446 deferMessage(msg); 447 return HANDLED; 448 449 case EVENT_START_ACCEPTING_SMS: 450 transitionTo(mIdleState); 451 return HANDLED; 452 453 case EVENT_BROADCAST_COMPLETE: 454 case EVENT_RETURN_TO_IDLE: 455 case EVENT_RELEASE_WAKELOCK: 456 default: 457 // let DefaultState handle these unexpected message types 458 return NOT_HANDLED; 459 } 460 } 461 } 462 463 /** 464 * In the idle state the wakelock is released until a new SM arrives, then we transition 465 * to Delivering mode to handle it, acquiring the wakelock on exit. 466 */ 467 private class IdleState extends State { 468 @Override enter()469 public void enter() { 470 if (DBG) log("IdleState.enter: entering IdleState"); 471 sendMessageDelayed(EVENT_RELEASE_WAKELOCK, getWakeLockTimeout()); 472 } 473 474 @Override exit()475 public void exit() { 476 mWakeLock.acquire(); 477 if (DBG) log("IdleState.exit: acquired wakelock, leaving IdleState"); 478 } 479 480 @Override processMessage(Message msg)481 public boolean processMessage(Message msg) { 482 if (DBG) log("IdleState.processMessage: processing " + getWhatToString(msg.what)); 483 switch (msg.what) { 484 case EVENT_NEW_SMS: 485 case EVENT_INJECT_SMS: 486 case EVENT_BROADCAST_SMS: 487 deferMessage(msg); 488 transitionTo(mDeliveringState); 489 return HANDLED; 490 491 case EVENT_RELEASE_WAKELOCK: 492 mWakeLock.release(); 493 if (DBG) { 494 if (mWakeLock.isHeld()) { 495 // this is okay as long as we call release() for every acquire() 496 log("IdleState.processMessage: EVENT_RELEASE_WAKELOCK: mWakeLock is " 497 + "still held after release"); 498 } else { 499 log("IdleState.processMessage: EVENT_RELEASE_WAKELOCK: mWakeLock " 500 + "released"); 501 } 502 } 503 return HANDLED; 504 505 case EVENT_RETURN_TO_IDLE: 506 // already in idle state; ignore 507 return HANDLED; 508 509 case EVENT_BROADCAST_COMPLETE: 510 case EVENT_START_ACCEPTING_SMS: 511 default: 512 // let DefaultState handle these unexpected message types 513 return NOT_HANDLED; 514 } 515 } 516 } 517 518 /** 519 * In the delivering state, the inbound SMS is processed and stored in the raw table. 520 * The message is acknowledged before we exit this state. If there is a message to broadcast, 521 * transition to {@link WaitingState} state to send the ordered broadcast and wait for the 522 * results. When all messages have been processed, the halting state will release the wakelock. 523 */ 524 private class DeliveringState extends State { 525 @Override enter()526 public void enter() { 527 if (DBG) log("DeliveringState.enter: entering DeliveringState"); 528 } 529 530 @Override exit()531 public void exit() { 532 if (DBG) log("DeliveringState.exit: leaving DeliveringState"); 533 } 534 535 @Override processMessage(Message msg)536 public boolean processMessage(Message msg) { 537 if (DBG) log("DeliveringState.processMessage: processing " + getWhatToString(msg.what)); 538 switch (msg.what) { 539 case EVENT_NEW_SMS: 540 // handle new SMS from RIL 541 handleNewSms((AsyncResult) msg.obj); 542 sendMessage(EVENT_RETURN_TO_IDLE); 543 return HANDLED; 544 545 case EVENT_INJECT_SMS: 546 // handle new injected SMS 547 handleInjectSms((AsyncResult) msg.obj, msg.arg1 == 1 /* isOverIms */); 548 sendMessage(EVENT_RETURN_TO_IDLE); 549 return HANDLED; 550 551 case EVENT_BROADCAST_SMS: 552 // if any broadcasts were sent, transition to waiting state 553 InboundSmsTracker inboundSmsTracker = (InboundSmsTracker) msg.obj; 554 if (processMessagePart(inboundSmsTracker)) { 555 sendMessage(obtainMessage(EVENT_UPDATE_TRACKER, msg.obj)); 556 transitionTo(mWaitingState); 557 } else { 558 // if event is sent from SmsBroadcastUndelivered.broadcastSms(), and 559 // processMessagePart() returns false, the state machine will be stuck in 560 // DeliveringState until next message is received. Send message to 561 // transition to idle to avoid that so that wakelock can be released 562 log("DeliveringState.processMessage: EVENT_BROADCAST_SMS: No broadcast " 563 + "sent. Return to IdleState"); 564 sendMessage(EVENT_RETURN_TO_IDLE); 565 } 566 return HANDLED; 567 568 case EVENT_RETURN_TO_IDLE: 569 // return to idle after processing all other messages 570 transitionTo(mIdleState); 571 return HANDLED; 572 573 case EVENT_RELEASE_WAKELOCK: 574 mWakeLock.release(); // decrement wakelock from previous entry to Idle 575 if (!mWakeLock.isHeld()) { 576 // wakelock should still be held until 3 seconds after we enter Idle 577 loge("mWakeLock released while delivering/broadcasting!"); 578 } 579 return HANDLED; 580 581 case EVENT_UPDATE_TRACKER: 582 logd("process tracker message in DeliveringState " + msg.arg1); 583 return HANDLED; 584 585 // we shouldn't get this message type in this state, log error and halt. 586 case EVENT_BROADCAST_COMPLETE: 587 case EVENT_START_ACCEPTING_SMS: 588 default: 589 logeWithLocalLog("Unhandled msg in delivering state, msg.what = " 590 + getWhatToString(msg.what)); 591 // let DefaultState handle these unexpected message types 592 return NOT_HANDLED; 593 } 594 } 595 } 596 597 /** 598 * The waiting state delegates handling of new SMS to parent {@link DeliveringState}, but 599 * defers handling of the {@link #EVENT_BROADCAST_SMS} phase until after the current 600 * result receiver sends {@link #EVENT_BROADCAST_COMPLETE}. Before transitioning to 601 * {@link DeliveringState}, {@link #EVENT_RETURN_TO_IDLE} is sent to transition to 602 * {@link IdleState} after any deferred {@link #EVENT_BROADCAST_SMS} messages are handled. 603 */ 604 private class WaitingState extends State { 605 606 private InboundSmsTracker mLastDeliveredSmsTracker; 607 608 @Override enter()609 public void enter() { 610 if (DBG) log("WaitingState.enter: entering WaitingState"); 611 } 612 613 @Override exit()614 public void exit() { 615 if (DBG) log("WaitingState.exit: leaving WaitingState"); 616 // Before moving to idle state, set wakelock timeout to WAKE_LOCK_TIMEOUT milliseconds 617 // to give any receivers time to take their own wake locks 618 setWakeLockTimeout(WAKELOCK_TIMEOUT); 619 mPhone.getIccSmsInterfaceManager().mDispatchersController.sendEmptyMessage( 620 SmsDispatchersController.EVENT_SMS_HANDLER_EXITING_WAITING_STATE); 621 } 622 623 @Override processMessage(Message msg)624 public boolean processMessage(Message msg) { 625 if (DBG) log("WaitingState.processMessage: processing " + getWhatToString(msg.what)); 626 switch (msg.what) { 627 case EVENT_BROADCAST_SMS: 628 // defer until the current broadcast completes 629 if (mLastDeliveredSmsTracker != null) { 630 String str = "Defer sms broadcast due to undelivered sms, " 631 + " messageCount = " + mLastDeliveredSmsTracker.getMessageCount() 632 + " destPort = " + mLastDeliveredSmsTracker.getDestPort() 633 + " timestamp = " + mLastDeliveredSmsTracker.getTimestamp() 634 + " currentTimestamp = " + System.currentTimeMillis(); 635 logWithLocalLog(str, mLastDeliveredSmsTracker.getMessageId()); 636 } 637 deferMessage(msg); 638 return HANDLED; 639 640 case EVENT_RECEIVER_TIMEOUT: 641 logeWithLocalLog("WaitingState.processMessage: received " 642 + "EVENT_RECEIVER_TIMEOUT"); 643 if (mLastDeliveredSmsTracker != null) { 644 mLastDeliveredSmsTracker.getSmsBroadcastReceiver(InboundSmsHandler.this) 645 .fakeNextAction(); 646 } 647 return HANDLED; 648 649 case EVENT_BROADCAST_COMPLETE: 650 mLastDeliveredSmsTracker = null; 651 // return to idle after handling all deferred messages 652 sendMessage(EVENT_RETURN_TO_IDLE); 653 transitionTo(mDeliveringState); 654 return HANDLED; 655 656 case EVENT_RETURN_TO_IDLE: 657 // not ready to return to idle; ignore 658 return HANDLED; 659 660 case EVENT_UPDATE_TRACKER: 661 mLastDeliveredSmsTracker = (InboundSmsTracker) msg.obj; 662 return HANDLED; 663 664 default: 665 // parent state handles the other message types 666 return NOT_HANDLED; 667 } 668 } 669 } 670 671 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) handleNewSms(AsyncResult ar)672 private void handleNewSms(AsyncResult ar) { 673 if (ar.exception != null) { 674 loge("Exception processing incoming SMS: " + ar.exception); 675 return; 676 } 677 678 int result; 679 try { 680 SmsMessage sms = (SmsMessage) ar.result; 681 result = dispatchMessage(sms.mWrappedSmsMessage, SOURCE_NOT_INJECTED); 682 } catch (RuntimeException ex) { 683 loge("Exception dispatching message", ex); 684 result = RESULT_SMS_DISPATCH_FAILURE; 685 } 686 687 // RESULT_OK means that the SMS will be acknowledged by special handling, 688 // e.g. for SMS-PP data download. Any other result, we should ack here. 689 if (result != Activity.RESULT_OK) { 690 boolean handled = (result == Intents.RESULT_SMS_HANDLED); 691 notifyAndAcknowledgeLastIncomingSms(handled, result, null); 692 } 693 } 694 695 /** 696 * This method is called when a new SMS PDU is injected into application framework. 697 * @param ar is the AsyncResult that has the SMS PDU to be injected. 698 */ 699 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) handleInjectSms(AsyncResult ar, boolean isOverIms)700 private void handleInjectSms(AsyncResult ar, boolean isOverIms) { 701 int result; 702 SmsDispatchersController.SmsInjectionCallback callback = null; 703 try { 704 callback = (SmsDispatchersController.SmsInjectionCallback) ar.userObj; 705 SmsMessage sms = (SmsMessage) ar.result; 706 if (sms == null) { 707 loge("Null injected sms"); 708 result = RESULT_SMS_NULL_PDU; 709 } else { 710 @SmsSource int smsSource = 711 isOverIms ? SOURCE_INJECTED_FROM_IMS : SOURCE_INJECTED_FROM_UNKNOWN; 712 result = dispatchMessage(sms.mWrappedSmsMessage, smsSource); 713 } 714 } catch (RuntimeException ex) { 715 loge("Exception dispatching message", ex); 716 result = RESULT_SMS_DISPATCH_FAILURE; 717 } 718 719 if (callback != null) { 720 callback.onSmsInjectedResult(result); 721 } 722 } 723 724 /** 725 * Process an SMS message from the RIL, calling subclass methods to handle 3GPP and 726 * 3GPP2-specific message types. 727 * 728 * @param smsb the SmsMessageBase object from the RIL 729 * @param smsSource the source of the SMS message 730 * @return a result code from {@link android.provider.Telephony.Sms.Intents}, 731 * or {@link Activity#RESULT_OK} for delayed acknowledgment to SMSC 732 */ dispatchMessage(SmsMessageBase smsb, @SmsSource int smsSource)733 private int dispatchMessage(SmsMessageBase smsb, @SmsSource int smsSource) { 734 // If sms is null, there was a parsing error. 735 if (smsb == null) { 736 loge("dispatchSmsMessage: message is null"); 737 return RESULT_SMS_NULL_MESSAGE; 738 } 739 740 if (mSmsReceiveDisabled) { 741 // Device doesn't support receiving SMS, 742 log("Received short message on device which doesn't support " 743 + "receiving SMS. Ignored."); 744 return Intents.RESULT_SMS_HANDLED; 745 } 746 747 // onlyCore indicates if the device is in cryptkeeper 748 boolean onlyCore = false; 749 try { 750 onlyCore = IPackageManager.Stub.asInterface(ServiceManager.getService("package")) 751 .isOnlyCoreApps(); 752 } catch (RemoteException e) { 753 } 754 if (onlyCore) { 755 // Device is unable to receive SMS in encrypted state 756 log("Received a short message in encrypted state. Rejecting."); 757 return Intents.RESULT_SMS_RECEIVED_WHILE_ENCRYPTED; 758 } 759 760 int result = dispatchMessageRadioSpecific(smsb, smsSource); 761 762 // In case of error, add to metrics. This is not required in case of success, as the 763 // data will be tracked when the message is processed (processMessagePart). 764 if (result != Intents.RESULT_SMS_HANDLED && result != Activity.RESULT_OK) { 765 mMetrics.writeIncomingSmsError(mPhone.getPhoneId(), is3gpp2(), smsSource, result); 766 mPhone.getSmsStats().onIncomingSmsError(is3gpp2(), smsSource, result); 767 } 768 return result; 769 } 770 771 /** 772 * Process voicemail notification, SMS-PP data download, CDMA CMAS, CDMA WAP push, and other 773 * 3GPP/3GPP2-specific messages. Regular SMS messages are handled by calling the shared 774 * {@link #dispatchNormalMessage} from this class. 775 * 776 * @param smsb the SmsMessageBase object from the RIL 777 * @param smsSource the source of the SMS message 778 * @return a result code from {@link android.provider.Telephony.Sms.Intents}, 779 * or {@link Activity#RESULT_OK} for delayed acknowledgment to SMSC 780 */ dispatchMessageRadioSpecific(SmsMessageBase smsb, @SmsSource int smsSource)781 protected abstract int dispatchMessageRadioSpecific(SmsMessageBase smsb, 782 @SmsSource int smsSource); 783 784 /** 785 * Send an acknowledge message to the SMSC. 786 * @param success indicates that last message was successfully received. 787 * @param result result code indicating any error 788 * @param response callback message sent when operation completes. 789 */ 790 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) acknowledgeLastIncomingSms(boolean success, int result, Message response)791 protected abstract void acknowledgeLastIncomingSms(boolean success, 792 int result, Message response); 793 794 /** 795 * Notify interested apps if the framework has rejected an incoming SMS, 796 * and send an acknowledge message to the network. 797 * @param success indicates that last message was successfully received. 798 * @param result result code indicating any error 799 * @param response callback message sent when operation completes. 800 */ notifyAndAcknowledgeLastIncomingSms(boolean success, int result, Message response)801 private void notifyAndAcknowledgeLastIncomingSms(boolean success, 802 int result, Message response) { 803 if (!success) { 804 // broadcast SMS_REJECTED_ACTION intent 805 Intent intent = new Intent(Intents.SMS_REJECTED_ACTION); 806 intent.putExtra("result", result); 807 intent.putExtra("subId", mPhone.getSubId()); 808 mContext.sendBroadcast(intent, android.Manifest.permission.RECEIVE_SMS); 809 } 810 acknowledgeLastIncomingSms(success, result, response); 811 } 812 813 /** 814 * Return true if this handler is for 3GPP2 messages; false for 3GPP format. 815 * @return true for the 3GPP2 handler; false for the 3GPP handler 816 */ is3gpp2()817 protected abstract boolean is3gpp2(); 818 819 /** 820 * Dispatch a normal incoming SMS. This is called from {@link #dispatchMessageRadioSpecific} 821 * if no format-specific handling was required. Saves the PDU to the SMS provider raw table, 822 * creates an {@link InboundSmsTracker}, then sends it to the state machine as an 823 * {@link #EVENT_BROADCAST_SMS}. Returns {@link Intents#RESULT_SMS_HANDLED} or an error value. 824 * 825 * @param sms the message to dispatch 826 * @param smsSource the source of the SMS message 827 * @return {@link Intents#RESULT_SMS_HANDLED} if the message was accepted, or an error status 828 */ 829 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) dispatchNormalMessage(SmsMessageBase sms, @SmsSource int smsSource)830 protected int dispatchNormalMessage(SmsMessageBase sms, @SmsSource int smsSource) { 831 SmsHeader smsHeader = sms.getUserDataHeader(); 832 InboundSmsTracker tracker; 833 834 if ((smsHeader == null) || (smsHeader.concatRef == null)) { 835 // Message is not concatenated. 836 int destPort = -1; 837 if (smsHeader != null && smsHeader.portAddrs != null) { 838 // The message was sent to a port. 839 destPort = smsHeader.portAddrs.destPort; 840 if (DBG) log("destination port: " + destPort); 841 } 842 tracker = TelephonyComponentFactory.getInstance() 843 .inject(InboundSmsTracker.class.getName()) 844 .makeInboundSmsTracker(mContext, sms.getPdu(), 845 sms.getTimestampMillis(), destPort, is3gpp2(), false, 846 sms.getOriginatingAddress(), sms.getDisplayOriginatingAddress(), 847 sms.getMessageBody(), sms.getMessageClass() == MessageClass.CLASS_0, 848 mPhone.getSubId(), smsSource); 849 } else { 850 // Create a tracker for this message segment. 851 SmsHeader.ConcatRef concatRef = smsHeader.concatRef; 852 SmsHeader.PortAddrs portAddrs = smsHeader.portAddrs; 853 int destPort = (portAddrs != null ? portAddrs.destPort : -1); 854 tracker = TelephonyComponentFactory.getInstance() 855 .inject(InboundSmsTracker.class.getName()) 856 .makeInboundSmsTracker(mContext, sms.getPdu(), 857 sms.getTimestampMillis(), destPort, is3gpp2(), 858 sms.getOriginatingAddress(), sms.getDisplayOriginatingAddress(), 859 concatRef.refNumber, concatRef.seqNumber, concatRef.msgCount, false, 860 sms.getMessageBody(), sms.getMessageClass() == MessageClass.CLASS_0, 861 mPhone.getSubId(), smsSource); 862 } 863 864 if (VDBG) log("created tracker: " + tracker); 865 866 // de-duping is done only for text messages 867 // destPort = -1 indicates text messages, otherwise it's a data sms 868 return addTrackerToRawTableAndSendMessage(tracker, 869 tracker.getDestPort() == -1 /* de-dup if text message */); 870 } 871 872 /** 873 * Helper to add the tracker to the raw table and then send a message to broadcast it, if 874 * successful. Returns the SMS intent status to return to the SMSC. 875 * @param tracker the tracker to save to the raw table and then deliver 876 * @return {@link Intents#RESULT_SMS_HANDLED} or one of these errors:<br> 877 * <code>RESULT_SMS_UNSUPPORTED</code><br> 878 * <code>RESULT_SMS_DUPLICATED</code><br> 879 * <code>RESULT_SMS_DISPATCH_FAILURE</code><br> 880 * <code>RESULT_SMS_NULL_PDU</code><br> 881 * <code>RESULT_SMS_NULL_MESSAGE</code><br> 882 * <code>RESULT_SMS_RECEIVED_WHILE_ENCRYPTED</code><br> 883 * <code>RESULT_SMS_DATABASE_ERROR</code><br> 884 * <code>RESULT_SMS_INVALID_URI</code><br> 885 */ addTrackerToRawTableAndSendMessage(InboundSmsTracker tracker, boolean deDup)886 protected int addTrackerToRawTableAndSendMessage(InboundSmsTracker tracker, boolean deDup) { 887 int result = addTrackerToRawTable(tracker, deDup); 888 switch(result) { 889 case Intents.RESULT_SMS_HANDLED: 890 sendMessage(EVENT_BROADCAST_SMS, tracker); 891 return Intents.RESULT_SMS_HANDLED; 892 893 case Intents.RESULT_SMS_DUPLICATED: 894 return Intents.RESULT_SMS_HANDLED; 895 896 default: 897 return result; 898 } 899 } 900 901 /** 902 * Process the inbound SMS segment. If the message is complete, send it as an ordered 903 * broadcast to interested receivers and return true. If the message is a segment of an 904 * incomplete multi-part SMS, return false. 905 * @param tracker the tracker containing the message segment to process 906 * @return true if an ordered broadcast was sent; false if waiting for more message segments 907 */ 908 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) processMessagePart(InboundSmsTracker tracker)909 private boolean processMessagePart(InboundSmsTracker tracker) { 910 int messageCount = tracker.getMessageCount(); 911 byte[][] pdus; 912 long[] timestamps; 913 int destPort = tracker.getDestPort(); 914 boolean block = false; 915 String address = tracker.getAddress(); 916 917 // Do not process when the message count is invalid. 918 if (messageCount <= 0) { 919 loge("processMessagePart: returning false due to invalid message count " 920 + messageCount, tracker.getMessageId()); 921 return false; 922 } 923 924 if (messageCount == 1) { 925 // single-part message 926 pdus = new byte[][]{tracker.getPdu()}; 927 timestamps = new long[]{tracker.getTimestamp()}; 928 block = BlockChecker.isBlocked(mContext, tracker.getDisplayAddress(), null); 929 } else { 930 // multi-part message 931 Cursor cursor = null; 932 try { 933 // used by several query selection arguments 934 String refNumber = Integer.toString(tracker.getReferenceNumber()); 935 String count = Integer.toString(tracker.getMessageCount()); 936 937 // query for all segments and broadcast message if we have all the parts 938 String[] whereArgs = {address, refNumber, count}; 939 cursor = mResolver.query(sRawUri, PDU_SEQUENCE_PORT_PROJECTION, 940 tracker.getQueryForSegments(), whereArgs, null); 941 942 int cursorCount = cursor.getCount(); 943 if (cursorCount < messageCount) { 944 // Wait for the other message parts to arrive. It's also possible for the last 945 // segment to arrive before processing the EVENT_BROADCAST_SMS for one of the 946 // earlier segments. In that case, the broadcast will be sent as soon as all 947 // segments are in the table, and any later EVENT_BROADCAST_SMS messages will 948 // get a row count of 0 and return. 949 log("processMessagePart: returning false. Only " + cursorCount + " of " 950 + messageCount + " segments " + " have arrived. refNumber: " 951 + refNumber, tracker.getMessageId()); 952 return false; 953 } 954 955 // All the parts are in place, deal with them 956 pdus = new byte[messageCount][]; 957 timestamps = new long[messageCount]; 958 while (cursor.moveToNext()) { 959 // subtract offset to convert sequence to 0-based array index 960 int index = cursor.getInt(PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING 961 .get(SEQUENCE_COLUMN)) - tracker.getIndexOffset(); 962 963 // The invalid PDUs can be received and stored in the raw table. The range 964 // check ensures the process not crash even if the seqNumber in the 965 // UserDataHeader is invalid. 966 if (index >= pdus.length || index < 0) { 967 loge(String.format( 968 "processMessagePart: invalid seqNumber = %d, messageCount = %d", 969 index + tracker.getIndexOffset(), 970 messageCount), 971 tracker.getMessageId()); 972 continue; 973 } 974 975 pdus[index] = HexDump.hexStringToByteArray(cursor.getString( 976 PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING.get(PDU_COLUMN))); 977 978 // Read the destination port from the first segment (needed for CDMA WAP PDU). 979 // It's not a bad idea to prefer the port from the first segment in other cases. 980 if (index == 0 && !cursor.isNull(PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING 981 .get(DESTINATION_PORT_COLUMN))) { 982 int port = cursor.getInt(PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING 983 .get(DESTINATION_PORT_COLUMN)); 984 // strip format flags and convert to real port number, or -1 985 port = InboundSmsTracker.getRealDestPort(port); 986 if (port != -1) { 987 destPort = port; 988 } 989 } 990 991 timestamps[index] = cursor.getLong( 992 PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING.get(DATE_COLUMN)); 993 994 // check if display address should be blocked or not 995 if (!block) { 996 // Depending on the nature of the gateway, the display origination address 997 // is either derived from the content of the SMS TP-OA field, or the TP-OA 998 // field contains a generic gateway address and the from address is added 999 // at the beginning in the message body. In that case only the first SMS 1000 // (part of Multi-SMS) comes with the display originating address which 1001 // could be used for block checking purpose. 1002 block = BlockChecker.isBlocked(mContext, 1003 cursor.getString(PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING 1004 .get(DISPLAY_ADDRESS_COLUMN)), null); 1005 } 1006 } 1007 log("processMessagePart: all " + messageCount + " segments " 1008 + " received. refNumber: " + refNumber, tracker.getMessageId()); 1009 } catch (SQLException e) { 1010 loge("processMessagePart: Can't access multipart SMS database, " 1011 + SmsController.formatCrossStackMessageId(tracker.getMessageId()), e); 1012 return false; 1013 } finally { 1014 if (cursor != null) { 1015 cursor.close(); 1016 } 1017 } 1018 } 1019 1020 final boolean isWapPush = (destPort == SmsHeader.PORT_WAP_PUSH); 1021 String format = tracker.getFormat(); 1022 1023 // Do not process null pdu(s). Check for that and return false in that case. 1024 List<byte[]> pduList = Arrays.asList(pdus); 1025 if (pduList.size() == 0 || pduList.contains(null)) { 1026 String errorMsg = "processMessagePart: returning false due to " 1027 + (pduList.size() == 0 ? "pduList.size() == 0" : "pduList.contains(null)"); 1028 logeWithLocalLog(errorMsg, tracker.getMessageId()); 1029 mPhone.getSmsStats().onIncomingSmsError( 1030 is3gpp2(), tracker.getSource(), RESULT_SMS_NULL_PDU); 1031 return false; 1032 } 1033 1034 ByteArrayOutputStream output = new ByteArrayOutputStream(); 1035 if (isWapPush) { 1036 for (byte[] pdu : pdus) { 1037 // 3GPP needs to extract the User Data from the PDU; 3GPP2 has already done this 1038 if (format == SmsConstants.FORMAT_3GPP) { 1039 SmsMessage msg = SmsMessage.createFromPdu(pdu, SmsConstants.FORMAT_3GPP); 1040 if (msg != null) { 1041 pdu = msg.getUserData(); 1042 } else { 1043 loge("processMessagePart: SmsMessage.createFromPdu returned null", 1044 tracker.getMessageId()); 1045 mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), tracker.getSource(), 1046 SmsConstants.FORMAT_3GPP, timestamps, false, 1047 tracker.getMessageId()); 1048 mPhone.getSmsStats().onIncomingSmsWapPush(tracker.getSource(), 1049 messageCount, RESULT_SMS_NULL_MESSAGE, tracker.getMessageId()); 1050 return false; 1051 } 1052 } 1053 output.write(pdu, 0, pdu.length); 1054 } 1055 } 1056 1057 SmsBroadcastReceiver resultReceiver = tracker.getSmsBroadcastReceiver(this); 1058 1059 if (!mUserManager.isUserUnlocked()) { 1060 log("processMessagePart: !isUserUnlocked; calling processMessagePartWithUserLocked. " 1061 + "Port: " + destPort, tracker.getMessageId()); 1062 return processMessagePartWithUserLocked( 1063 tracker, 1064 (isWapPush ? new byte[][] {output.toByteArray()} : pdus), 1065 destPort, 1066 resultReceiver, 1067 block); 1068 } 1069 1070 if (isWapPush) { 1071 int result = mWapPush.dispatchWapPdu(output.toByteArray(), resultReceiver, 1072 this, address, tracker.getSubId(), tracker.getMessageId()); 1073 if (DBG) { 1074 log("processMessagePart: dispatchWapPdu() returned " + result, 1075 tracker.getMessageId()); 1076 } 1077 // Add result of WAP-PUSH into metrics. RESULT_SMS_HANDLED indicates that the WAP-PUSH 1078 // needs to be ignored, so treating it as a success case. 1079 boolean wapPushResult = 1080 result == Activity.RESULT_OK || result == Intents.RESULT_SMS_HANDLED; 1081 mMetrics.writeIncomingWapPush(mPhone.getPhoneId(), tracker.getSource(), 1082 format, timestamps, wapPushResult, tracker.getMessageId()); 1083 mPhone.getSmsStats().onIncomingSmsWapPush(tracker.getSource(), messageCount, 1084 result, tracker.getMessageId()); 1085 // result is Activity.RESULT_OK if an ordered broadcast was sent 1086 if (result == Activity.RESULT_OK) { 1087 return true; 1088 } else { 1089 deleteFromRawTable(tracker.getDeleteWhere(), tracker.getDeleteWhereArgs(), 1090 MARK_DELETED); 1091 loge("processMessagePart: returning false as the ordered broadcast for WAP push " 1092 + "was not sent", tracker.getMessageId()); 1093 return false; 1094 } 1095 } 1096 1097 // All parts of SMS are received. Update metrics for incoming SMS. 1098 // The metrics are generated before SMS filters are invoked. 1099 // For messages composed by multiple parts, the metrics are generated considering the 1100 // characteristics of the last one. 1101 mMetrics.writeIncomingSmsSession(mPhone.getPhoneId(), tracker.getSource(), 1102 format, timestamps, block, tracker.getMessageId()); 1103 mPhone.getSmsStats().onIncomingSmsSuccess(is3gpp2(), tracker.getSource(), 1104 messageCount, block, tracker.getMessageId()); 1105 1106 // Always invoke SMS filters, even if the number ends up being blocked, to prevent 1107 // surprising bugs due to blocking numbers that happen to be used for visual voicemail SMS 1108 // or other carrier system messages. 1109 boolean filterInvoked = filterSms( 1110 pdus, destPort, tracker, resultReceiver, true /* userUnlocked */, block); 1111 1112 if (!filterInvoked) { 1113 // Block now if the filter wasn't invoked. Otherwise, it will be the responsibility of 1114 // the filter to delete the SMS once processing completes. 1115 if (block) { 1116 deleteFromRawTable(tracker.getDeleteWhere(), tracker.getDeleteWhereArgs(), 1117 DELETE_PERMANENTLY); 1118 log("processMessagePart: returning false as the phone number is blocked", 1119 tracker.getMessageId()); 1120 return false; 1121 } 1122 1123 dispatchSmsDeliveryIntent(pdus, format, destPort, resultReceiver, 1124 tracker.isClass0(), tracker.getSubId(), tracker.getMessageId()); 1125 } 1126 1127 return true; 1128 } 1129 1130 /** 1131 * Processes the message part while the credential-encrypted storage is still locked. 1132 * 1133 * <p>If the message is a regular MMS, show a new message notification. If the message is a 1134 * SMS, ask the carrier app to filter it and show the new message notification if the carrier 1135 * app asks to keep the message. 1136 * 1137 * @return true if an ordered broadcast was sent to the carrier app; false otherwise. 1138 */ processMessagePartWithUserLocked(InboundSmsTracker tracker, byte[][] pdus, int destPort, SmsBroadcastReceiver resultReceiver, boolean block)1139 private boolean processMessagePartWithUserLocked(InboundSmsTracker tracker, 1140 byte[][] pdus, int destPort, SmsBroadcastReceiver resultReceiver, boolean block) { 1141 if (destPort == SmsHeader.PORT_WAP_PUSH && mWapPush.isWapPushForMms(pdus[0], this)) { 1142 showNewMessageNotification(); 1143 return false; 1144 } 1145 if (destPort == -1) { 1146 // This is a regular SMS - hand it to the carrier or system app for filtering. 1147 boolean filterInvoked = filterSms( 1148 pdus, destPort, tracker, resultReceiver, false /* userUnlocked */, 1149 block); 1150 if (filterInvoked) { 1151 // filter invoked, wait for it to return the result. 1152 return true; 1153 } else if (!block) { 1154 // filter not invoked and message not blocked, show the notification and do nothing 1155 // further. Even if the message is blocked, we keep it in the database so it can be 1156 // reprocessed by filters once credential-encrypted storage is available. 1157 showNewMessageNotification(); 1158 } 1159 } 1160 return false; 1161 } 1162 1163 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) showNewMessageNotification()1164 private void showNewMessageNotification() { 1165 // Do not show the notification on non-FBE devices. 1166 if (!StorageManager.isFileEncryptedNativeOrEmulated()) { 1167 return; 1168 } 1169 log("Show new message notification."); 1170 PendingIntent intent = PendingIntent.getBroadcast( 1171 mContext, 1172 0, 1173 new Intent(ACTION_OPEN_SMS_APP), 1174 PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE); 1175 Notification.Builder mBuilder = new Notification.Builder(mContext) 1176 .setSmallIcon(com.android.internal.R.drawable.sym_action_chat) 1177 .setAutoCancel(true) 1178 .setVisibility(Notification.VISIBILITY_PUBLIC) 1179 .setDefaults(Notification.DEFAULT_ALL) 1180 .setContentTitle(mContext.getString(R.string.new_sms_notification_title)) 1181 .setContentText(mContext.getString(R.string.new_sms_notification_content)) 1182 .setContentIntent(intent) 1183 .setChannelId(NotificationChannelController.CHANNEL_ID_SMS); 1184 NotificationManager mNotificationManager = 1185 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); 1186 mNotificationManager.notify( 1187 NOTIFICATION_TAG, NOTIFICATION_ID_NEW_MESSAGE, mBuilder.build()); 1188 } 1189 cancelNewMessageNotification(Context context)1190 static void cancelNewMessageNotification(Context context) { 1191 NotificationManager mNotificationManager = 1192 (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 1193 mNotificationManager.cancel(InboundSmsHandler.NOTIFICATION_TAG, 1194 InboundSmsHandler.NOTIFICATION_ID_NEW_MESSAGE); 1195 } 1196 1197 /** 1198 * Creates the default filters used to filter SMS messages. 1199 * 1200 * <p>Currently 3 filters exist: the carrier package, the VisualVoicemailSmsFilter, and the 1201 * missed incoming call SMS filter. 1202 * 1203 * <p>Since the carrier filter is asynchronous, if a message passes through the carrier filter, 1204 * the remaining filters will be applied in the callback. 1205 */ createDefaultSmsFilters()1206 private List<SmsFilter> createDefaultSmsFilters() { 1207 List<SmsFilter> smsFilters = new ArrayList<>(3); 1208 smsFilters.add( 1209 (pdus, destPort, tracker, resultReceiver, userUnlocked, block, remainingFilters) 1210 -> { 1211 CarrierServicesSmsFilterCallback filterCallback = 1212 new CarrierServicesSmsFilterCallback( 1213 pdus, destPort, tracker, tracker.getFormat(), resultReceiver, 1214 userUnlocked, 1215 tracker.isClass0(), tracker.getSubId(), tracker.getMessageId(), 1216 block, remainingFilters); 1217 CarrierServicesSmsFilter carrierServicesFilter = new CarrierServicesSmsFilter( 1218 mContext, mPhone, pdus, destPort, tracker.getFormat(), 1219 filterCallback, getName() + "::CarrierServicesSmsFilter", 1220 mCarrierServiceLocalLog, tracker.getMessageId()); 1221 if (carrierServicesFilter.filter()) { 1222 log("SMS is being handled by carrier service", tracker.getMessageId()); 1223 return true; 1224 } else { 1225 return false; 1226 } 1227 }); 1228 smsFilters.add( 1229 (pdus, destPort, tracker, resultReceiver, userUnlocked, block, remainingFilters) 1230 -> { 1231 if (VisualVoicemailSmsFilter.filter( 1232 mContext, pdus, tracker.getFormat(), destPort, tracker.getSubId())) { 1233 logWithLocalLog("Visual voicemail SMS dropped", tracker.getMessageId()); 1234 dropFilteredSms(tracker, resultReceiver, block); 1235 return true; 1236 } 1237 return false; 1238 }); 1239 smsFilters.add( 1240 (pdus, destPort, tracker, resultReceiver, userUnlocked, block, remainingFilters) 1241 -> { 1242 MissedIncomingCallSmsFilter missedIncomingCallSmsFilter = 1243 new MissedIncomingCallSmsFilter(mPhone); 1244 if (missedIncomingCallSmsFilter.filter(pdus, tracker.getFormat())) { 1245 logWithLocalLog("Missed incoming call SMS received", 1246 tracker.getMessageId()); 1247 dropFilteredSms(tracker, resultReceiver, block); 1248 return true; 1249 } 1250 return false; 1251 }); 1252 return smsFilters; 1253 } 1254 dropFilteredSms( InboundSmsTracker tracker, SmsBroadcastReceiver resultReceiver, boolean block)1255 private void dropFilteredSms( 1256 InboundSmsTracker tracker, SmsBroadcastReceiver resultReceiver, boolean block) { 1257 if (block) { 1258 deleteFromRawTable( 1259 tracker.getDeleteWhere(), tracker.getDeleteWhereArgs(), 1260 DELETE_PERMANENTLY); 1261 sendMessage(EVENT_BROADCAST_COMPLETE); 1262 } else { 1263 dropSms(resultReceiver); 1264 } 1265 } 1266 1267 /** 1268 * Filters the SMS. 1269 * 1270 * <p>Each filter in {@link #mSmsFilters} is invoked sequentially. If any filter returns true, 1271 * this method returns true and subsequent filters are ignored. 1272 * 1273 * @return true if a filter is invoked and the SMS processing flow is diverted, false otherwise. 1274 */ filterSms(byte[][] pdus, int destPort, InboundSmsTracker tracker, SmsBroadcastReceiver resultReceiver, boolean userUnlocked, boolean block)1275 private boolean filterSms(byte[][] pdus, int destPort, 1276 InboundSmsTracker tracker, SmsBroadcastReceiver resultReceiver, boolean userUnlocked, 1277 boolean block) { 1278 return filterSms(pdus, destPort, tracker, resultReceiver, userUnlocked, block, mSmsFilters); 1279 } 1280 filterSms(byte[][] pdus, int destPort, InboundSmsTracker tracker, SmsBroadcastReceiver resultReceiver, boolean userUnlocked, boolean block, List<SmsFilter> filters)1281 private static boolean filterSms(byte[][] pdus, int destPort, 1282 InboundSmsTracker tracker, SmsBroadcastReceiver resultReceiver, boolean userUnlocked, 1283 boolean block, List<SmsFilter> filters) { 1284 ListIterator<SmsFilter> iterator = filters.listIterator(); 1285 while (iterator.hasNext()) { 1286 SmsFilter smsFilter = iterator.next(); 1287 if (smsFilter.filterSms(pdus, destPort, tracker, resultReceiver, userUnlocked, block, 1288 filters.subList(iterator.nextIndex(), filters.size()))) { 1289 return true; 1290 } 1291 } 1292 return false; 1293 } 1294 1295 /** 1296 * Dispatch the intent with the specified permission, appOp, and result receiver, using 1297 * this state machine's handler thread to run the result receiver. 1298 * 1299 * @param intent the intent to broadcast 1300 * @param permission receivers are required to have this permission 1301 * @param appOp app op that is being performed when dispatching to a receiver 1302 * @param user user to deliver the intent to 1303 */ 1304 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) dispatchIntent(Intent intent, String permission, String appOp, Bundle opts, SmsBroadcastReceiver resultReceiver, UserHandle user, int subId)1305 public void dispatchIntent(Intent intent, String permission, String appOp, 1306 Bundle opts, SmsBroadcastReceiver resultReceiver, UserHandle user, int subId) { 1307 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 1308 final String action = intent.getAction(); 1309 if (Intents.SMS_DELIVER_ACTION.equals(action) 1310 || Intents.SMS_RECEIVED_ACTION.equals(action) 1311 || Intents.WAP_PUSH_DELIVER_ACTION.equals(action) 1312 || Intents.WAP_PUSH_RECEIVED_ACTION.equals(action)) { 1313 // Some intents need to be delivered with high priority: 1314 // SMS_DELIVER, SMS_RECEIVED, WAP_PUSH_DELIVER, WAP_PUSH_RECEIVED 1315 // In some situations, like after boot up or system under load, normal 1316 // intent delivery could take a long time. 1317 // This flag should only be set for intents for visible, timely operations 1318 // which is true for the intents above. 1319 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 1320 } 1321 SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId()); 1322 1323 // override the subId value in the intent with the values from tracker as they can be 1324 // different, specifically if the message is coming from SmsBroadcastUndelivered 1325 if (SubscriptionManager.isValidSubscriptionId(subId)) { 1326 SubscriptionManager.putSubscriptionIdExtra(intent, subId); 1327 } 1328 1329 if (user.equals(UserHandle.ALL)) { 1330 // Get a list of currently started users. 1331 int[] users = null; 1332 final List<UserHandle> userHandles = mUserManager.getUserHandles(false); 1333 final List<UserHandle> runningUserHandles = new ArrayList(); 1334 for (UserHandle handle : userHandles) { 1335 if (mUserManager.isUserRunning(handle)) { 1336 runningUserHandles.add(handle); 1337 } else { 1338 if (handle.equals(UserHandle.SYSTEM)) { 1339 logeWithLocalLog("dispatchIntent: SYSTEM user is not running", 1340 resultReceiver.mInboundSmsTracker.getMessageId()); 1341 } 1342 } 1343 } 1344 if (runningUserHandles.isEmpty()) { 1345 users = new int[] {user.getIdentifier()}; 1346 } else { 1347 users = new int[runningUserHandles.size()]; 1348 for (int i = 0; i < runningUserHandles.size(); i++) { 1349 users[i] = runningUserHandles.get(i).getIdentifier(); 1350 } 1351 } 1352 // Deliver the broadcast only to those running users that are permitted 1353 // by user policy. 1354 for (int i = users.length - 1; i >= 0; i--) { 1355 UserHandle targetUser = UserHandle.of(users[i]); 1356 if (users[i] != UserHandle.SYSTEM.getIdentifier()) { 1357 // Is the user not allowed to use SMS? 1358 if (hasUserRestriction(UserManager.DISALLOW_SMS, targetUser)) { 1359 continue; 1360 } 1361 // Skip unknown users and managed profiles as well 1362 if (mUserManager.isManagedProfile(users[i])) { 1363 continue; 1364 } 1365 } 1366 // Only pass in the resultReceiver when the user SYSTEM is processed. 1367 try { 1368 if (users[i] == UserHandle.SYSTEM.getIdentifier()) { 1369 resultReceiver.setWaitingForIntent(intent); 1370 } 1371 mContext.createPackageContextAsUser(mContext.getPackageName(), 0, targetUser) 1372 .sendOrderedBroadcast(intent, Activity.RESULT_OK, permission, appOp, 1373 users[i] == UserHandle.SYSTEM.getIdentifier() 1374 ? resultReceiver : null, getHandler(), 1375 null /* initialData */, null /* initialExtras */, opts); 1376 } catch (PackageManager.NameNotFoundException ignored) { 1377 } 1378 } 1379 } else { 1380 try { 1381 resultReceiver.setWaitingForIntent(intent); 1382 mContext.createPackageContextAsUser(mContext.getPackageName(), 0, user) 1383 .sendOrderedBroadcast(intent, Activity.RESULT_OK, permission, appOp, 1384 resultReceiver, getHandler(), null /* initialData */, 1385 null /* initialExtras */, opts); 1386 } catch (PackageManager.NameNotFoundException ignored) { 1387 } 1388 } 1389 } 1390 hasUserRestriction(String restrictionKey, UserHandle userHandle)1391 private boolean hasUserRestriction(String restrictionKey, UserHandle userHandle) { 1392 final List<UserManager.EnforcingUser> sources = mUserManager 1393 .getUserRestrictionSources(restrictionKey, userHandle); 1394 return (sources != null && !sources.isEmpty()); 1395 } 1396 1397 /** 1398 * Helper for {@link SmsBroadcastUndelivered} to delete an old message in the raw table. 1399 */ 1400 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) deleteFromRawTable(String deleteWhere, String[] deleteWhereArgs, int deleteType)1401 private void deleteFromRawTable(String deleteWhere, String[] deleteWhereArgs, 1402 int deleteType) { 1403 Uri uri = deleteType == DELETE_PERMANENTLY ? sRawUriPermanentDelete : sRawUri; 1404 int rows = mResolver.delete(uri, deleteWhere, deleteWhereArgs); 1405 if (rows == 0) { 1406 loge("No rows were deleted from raw table!"); 1407 } else if (DBG) { 1408 log("Deleted " + rows + " rows from raw table."); 1409 } 1410 } 1411 1412 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) handleSmsWhitelisting(ComponentName target, boolean bgActivityStartAllowed)1413 private Bundle handleSmsWhitelisting(ComponentName target, boolean bgActivityStartAllowed) { 1414 String pkgName; 1415 String reason; 1416 if (target != null) { 1417 pkgName = target.getPackageName(); 1418 reason = "sms-app"; 1419 } else { 1420 pkgName = mContext.getPackageName(); 1421 reason = "sms-broadcast"; 1422 } 1423 BroadcastOptions bopts = null; 1424 Bundle bundle = null; 1425 if (bgActivityStartAllowed) { 1426 bopts = BroadcastOptions.makeBasic(); 1427 bopts.setBackgroundActivityStartsAllowed(true); 1428 bundle = bopts.toBundle(); 1429 } 1430 long duration = mPowerWhitelistManager.whitelistAppTemporarilyForEvent( 1431 pkgName, PowerWhitelistManager.EVENT_SMS, REASON_EVENT_SMS, reason); 1432 if (bopts == null) bopts = BroadcastOptions.makeBasic(); 1433 bopts.setTemporaryAppAllowlist(duration, 1434 TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, 1435 REASON_EVENT_SMS, 1436 ""); 1437 bundle = bopts.toBundle(); 1438 1439 return bundle; 1440 } 1441 1442 /** 1443 * Creates and dispatches the intent to the default SMS app, appropriate port or via the {@link 1444 * AppSmsManager}. 1445 * 1446 * @param pdus message pdus 1447 * @param format the message format, typically "3gpp" or "3gpp2" 1448 * @param destPort the destination port 1449 * @param resultReceiver the receiver handling the delivery result 1450 */ dispatchSmsDeliveryIntent(byte[][] pdus, String format, int destPort, SmsBroadcastReceiver resultReceiver, boolean isClass0, int subId, long messageId)1451 private void dispatchSmsDeliveryIntent(byte[][] pdus, String format, int destPort, 1452 SmsBroadcastReceiver resultReceiver, boolean isClass0, int subId, long messageId) { 1453 Intent intent = new Intent(); 1454 intent.putExtra("pdus", pdus); 1455 intent.putExtra("format", format); 1456 if (messageId != 0L) { 1457 intent.putExtra("messageId", messageId); 1458 } 1459 1460 if (destPort == -1) { 1461 intent.setAction(Intents.SMS_DELIVER_ACTION); 1462 // Direct the intent to only the default SMS app. If we can't find a default SMS app 1463 // then sent it to all broadcast receivers. 1464 // We are deliberately delivering to the primary user's default SMS App. 1465 ComponentName componentName = SmsApplication.getDefaultSmsApplication(mContext, true); 1466 if (componentName != null) { 1467 // Deliver SMS message only to this receiver. 1468 intent.setComponent(componentName); 1469 logWithLocalLog("Delivering SMS to: " + componentName.getPackageName() 1470 + " " + componentName.getClassName(), messageId); 1471 } else { 1472 intent.setComponent(null); 1473 } 1474 1475 // Handle app specific sms messages. 1476 AppSmsManager appManager = mPhone.getAppSmsManager(); 1477 if (appManager.handleSmsReceivedIntent(intent)) { 1478 // The AppSmsManager handled this intent, we're done. 1479 dropSms(resultReceiver); 1480 return; 1481 } 1482 } else { 1483 intent.setAction(Intents.DATA_SMS_RECEIVED_ACTION); 1484 Uri uri = Uri.parse("sms://localhost:" + destPort); 1485 intent.setData(uri); 1486 intent.setComponent(null); 1487 } 1488 1489 Bundle options = handleSmsWhitelisting(intent.getComponent(), isClass0); 1490 dispatchIntent(intent, android.Manifest.permission.RECEIVE_SMS, 1491 AppOpsManager.OPSTR_RECEIVE_SMS, options, resultReceiver, UserHandle.SYSTEM, subId); 1492 } 1493 1494 /** 1495 * Function to detect and handle duplicate messages. If the received message should replace an 1496 * existing message in the raw db, this function deletes the existing message. If an existing 1497 * message takes priority (for eg, existing message has already been broadcast), then this new 1498 * message should be dropped. 1499 * @return true if the message represented by the passed in tracker should be dropped, 1500 * false otherwise 1501 */ checkAndHandleDuplicate(InboundSmsTracker tracker)1502 private boolean checkAndHandleDuplicate(InboundSmsTracker tracker) throws SQLException { 1503 Pair<String, String[]> exactMatchQuery = tracker.getExactMatchDupDetectQuery(); 1504 1505 Cursor cursor = null; 1506 try { 1507 // Check for duplicate message segments 1508 cursor = mResolver.query(sRawUri, PDU_DELETED_FLAG_PROJECTION, exactMatchQuery.first, 1509 exactMatchQuery.second, null); 1510 1511 // moveToNext() returns false if no duplicates were found 1512 if (cursor != null && cursor.moveToNext()) { 1513 if (cursor.getCount() != 1) { 1514 logeWithLocalLog("checkAndHandleDuplicate: Exact match query returned " 1515 + cursor.getCount() + " rows", tracker.getMessageId()); 1516 } 1517 1518 // if the exact matching row is marked deleted, that means this message has already 1519 // been received and processed, and can be discarded as dup 1520 if (cursor.getInt( 1521 PDU_DELETED_FLAG_PROJECTION_INDEX_MAPPING.get(DELETED_FLAG_COLUMN)) == 1) { 1522 logWithLocalLog("checkAndHandleDuplicate: Discarding duplicate " 1523 + "message/segment: " + tracker); 1524 logDupPduMismatch(cursor, tracker); 1525 return true; // reject message 1526 } else { 1527 // exact match duplicate is not marked deleted. If it is a multi-part segment, 1528 // the code below for inexact match will take care of it. If it is a single 1529 // part message, handle it here. 1530 if (tracker.getMessageCount() == 1) { 1531 // delete the old message segment permanently 1532 deleteFromRawTable(exactMatchQuery.first, exactMatchQuery.second, 1533 DELETE_PERMANENTLY); 1534 logWithLocalLog("checkAndHandleDuplicate: Replacing duplicate message: " 1535 + tracker); 1536 logDupPduMismatch(cursor, tracker); 1537 } 1538 } 1539 } 1540 } finally { 1541 if (cursor != null) { 1542 cursor.close(); 1543 } 1544 } 1545 1546 // The code above does an exact match. Multi-part message segments need an additional check 1547 // on top of that: if there is a message segment that conflicts this new one (may not be an 1548 // exact match), replace the old message segment with this one. 1549 if (tracker.getMessageCount() > 1) { 1550 Pair<String, String[]> inexactMatchQuery = tracker.getInexactMatchDupDetectQuery(); 1551 cursor = null; 1552 try { 1553 // Check for duplicate message segments 1554 cursor = mResolver.query(sRawUri, PDU_DELETED_FLAG_PROJECTION, 1555 inexactMatchQuery.first, inexactMatchQuery.second, null); 1556 1557 // moveToNext() returns false if no duplicates were found 1558 if (cursor != null && cursor.moveToNext()) { 1559 if (cursor.getCount() != 1) { 1560 logeWithLocalLog("checkAndHandleDuplicate: Inexact match query returned " 1561 + cursor.getCount() + " rows", tracker.getMessageId()); 1562 } 1563 // delete the old message segment permanently 1564 deleteFromRawTable(inexactMatchQuery.first, inexactMatchQuery.second, 1565 DELETE_PERMANENTLY); 1566 logWithLocalLog("checkAndHandleDuplicate: Replacing duplicate message segment: " 1567 + tracker); 1568 logDupPduMismatch(cursor, tracker); 1569 } 1570 } finally { 1571 if (cursor != null) { 1572 cursor.close(); 1573 } 1574 } 1575 } 1576 1577 return false; 1578 } 1579 logDupPduMismatch(Cursor cursor, InboundSmsTracker tracker)1580 private void logDupPduMismatch(Cursor cursor, InboundSmsTracker tracker) { 1581 String oldPduString = cursor.getString( 1582 PDU_DELETED_FLAG_PROJECTION_INDEX_MAPPING.get(PDU_COLUMN)); 1583 byte[] pdu = tracker.getPdu(); 1584 byte[] oldPdu = HexDump.hexStringToByteArray(oldPduString); 1585 if (!Arrays.equals(oldPdu, tracker.getPdu())) { 1586 logeWithLocalLog("Warning: dup message PDU of length " + pdu.length 1587 + " is different from existing PDU of length " + oldPdu.length, 1588 tracker.getMessageId()); 1589 } 1590 } 1591 1592 /** 1593 * Insert a message PDU into the raw table so we can acknowledge it immediately. 1594 * If the device crashes before the broadcast to listeners completes, it will be delivered 1595 * from the raw table on the next device boot. For single-part messages, the deleteWhere 1596 * and deleteWhereArgs fields of the tracker will be set to delete the correct row after 1597 * the ordered broadcast completes. 1598 * 1599 * @param tracker the tracker to add to the raw table 1600 * @return true on success; false on failure to write to database 1601 */ addTrackerToRawTable(InboundSmsTracker tracker, boolean deDup)1602 private int addTrackerToRawTable(InboundSmsTracker tracker, boolean deDup) { 1603 if (deDup) { 1604 try { 1605 if (checkAndHandleDuplicate(tracker)) { 1606 return Intents.RESULT_SMS_DUPLICATED; // reject message 1607 } 1608 } catch (SQLException e) { 1609 loge("addTrackerToRawTable: Can't access SMS database, " 1610 + SmsController.formatCrossStackMessageId(tracker.getMessageId()), e); 1611 return RESULT_SMS_DATABASE_ERROR; // reject message 1612 } 1613 } else { 1614 log("addTrackerToRawTable: Skipped message de-duping logic", tracker.getMessageId()); 1615 } 1616 1617 String address = tracker.getAddress(); 1618 String refNumber = Integer.toString(tracker.getReferenceNumber()); 1619 String count = Integer.toString(tracker.getMessageCount()); 1620 ContentValues values = tracker.getContentValues(); 1621 1622 if (VDBG) { 1623 log("addTrackerToRawTable: adding content values to raw table: " + values.toString(), 1624 tracker.getMessageId()); 1625 } 1626 Uri newUri = mResolver.insert(sRawUri, values); 1627 if (DBG) log("addTrackerToRawTable: URI of new row: " + newUri, tracker.getMessageId()); 1628 1629 try { 1630 long rowId = ContentUris.parseId(newUri); 1631 if (tracker.getMessageCount() == 1) { 1632 // set the delete selection args for single-part message 1633 tracker.setDeleteWhere(SELECT_BY_ID, new String[]{Long.toString(rowId)}); 1634 } else { 1635 // set the delete selection args for multi-part message 1636 String[] deleteWhereArgs = {address, refNumber, count}; 1637 tracker.setDeleteWhere(tracker.getQueryForSegments(), deleteWhereArgs); 1638 } 1639 return Intents.RESULT_SMS_HANDLED; 1640 } catch (Exception e) { 1641 loge("addTrackerToRawTable: error parsing URI for new row: " + newUri 1642 + " " + SmsController.formatCrossStackMessageId(tracker.getMessageId()), e); 1643 return RESULT_SMS_INVALID_URI; 1644 } 1645 } 1646 1647 /** 1648 * Returns whether the default message format for the current radio technology is 3GPP2. 1649 * @return true if the radio technology uses 3GPP2 format by default, false for 3GPP format 1650 */ isCurrentFormat3gpp2()1651 static boolean isCurrentFormat3gpp2() { 1652 int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(); 1653 return (PHONE_TYPE_CDMA == activePhone); 1654 } 1655 1656 @VisibleForTesting 1657 public static int sTimeoutDurationMillis = 10 * 60 * 1000; // 10 minutes 1658 1659 /** 1660 * Handler for an {@link InboundSmsTracker} broadcast. Deletes PDUs from the raw table and 1661 * logs the broadcast duration (as an error if the other receivers were especially slow). 1662 */ 1663 public final class SmsBroadcastReceiver extends BroadcastReceiver { 1664 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 1665 private final String mDeleteWhere; 1666 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 1667 private final String[] mDeleteWhereArgs; 1668 private long mBroadcastTimeMillis; 1669 public Intent mWaitingForIntent; 1670 private final InboundSmsTracker mInboundSmsTracker; 1671 1672 /** 1673 * This method must be called anytime an ordered broadcast is sent that is expected to be 1674 * received by this receiver. 1675 */ setWaitingForIntent(Intent intent)1676 public synchronized void setWaitingForIntent(Intent intent) { 1677 mWaitingForIntent = intent; 1678 mBroadcastTimeMillis = System.currentTimeMillis(); 1679 removeMessages(EVENT_RECEIVER_TIMEOUT); 1680 sendMessageDelayed(EVENT_RECEIVER_TIMEOUT, sTimeoutDurationMillis); 1681 } 1682 SmsBroadcastReceiver(InboundSmsTracker tracker)1683 public SmsBroadcastReceiver(InboundSmsTracker tracker) { 1684 mDeleteWhere = tracker.getDeleteWhere(); 1685 mDeleteWhereArgs = tracker.getDeleteWhereArgs(); 1686 mInboundSmsTracker = tracker; 1687 } 1688 1689 /** 1690 * This method is called if the expected intent (mWaitingForIntent) is not received and 1691 * the timer for it expires. It fakes the receipt of the intent to unblock the state 1692 * machine. 1693 */ fakeNextAction()1694 public void fakeNextAction() { 1695 if (mWaitingForIntent != null) { 1696 logeWithLocalLog("fakeNextAction: " + mWaitingForIntent.getAction(), 1697 mInboundSmsTracker.getMessageId()); 1698 handleAction(mWaitingForIntent, false); 1699 } else { 1700 logeWithLocalLog("fakeNextAction: mWaitingForIntent is null", 1701 mInboundSmsTracker.getMessageId()); 1702 } 1703 } 1704 1705 @Override onReceive(Context context, Intent intent)1706 public void onReceive(Context context, Intent intent) { 1707 handleAction(intent, true); 1708 } 1709 handleAction(Intent intent, boolean onReceive)1710 private synchronized void handleAction(Intent intent, boolean onReceive) { 1711 String action = intent.getAction(); 1712 if (mWaitingForIntent == null || !mWaitingForIntent.getAction().equals(action)) { 1713 logeWithLocalLog("handleAction: Received " + action + " when expecting " 1714 + mWaitingForIntent == null ? "none" : mWaitingForIntent.getAction(), 1715 mInboundSmsTracker.getMessageId()); 1716 return; 1717 } 1718 1719 if (onReceive) { 1720 int durationMillis = (int) (System.currentTimeMillis() - mBroadcastTimeMillis); 1721 if (durationMillis >= 5000) { 1722 loge("Slow ordered broadcast completion time for " + action + ": " 1723 + durationMillis + " ms"); 1724 } else if (DBG) { 1725 log("Ordered broadcast completed for " + action + " in: " 1726 + durationMillis + " ms"); 1727 } 1728 } 1729 1730 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 1731 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 1732 if (action.equals(Intents.SMS_DELIVER_ACTION)) { 1733 // Now dispatch the notification only intent 1734 intent.setAction(Intents.SMS_RECEIVED_ACTION); 1735 // Allow registered broadcast receivers to get this intent even 1736 // when they are in the background. 1737 intent.setComponent(null); 1738 // All running users will be notified of the received sms. 1739 Bundle options = handleSmsWhitelisting(null, false /* bgActivityStartAllowed */); 1740 1741 setWaitingForIntent(intent); 1742 dispatchIntent(intent, android.Manifest.permission.RECEIVE_SMS, 1743 AppOpsManager.OPSTR_RECEIVE_SMS, 1744 options, this, UserHandle.ALL, subId); 1745 } else if (action.equals(Intents.WAP_PUSH_DELIVER_ACTION)) { 1746 // Now dispatch the notification only intent 1747 intent.setAction(Intents.WAP_PUSH_RECEIVED_ACTION); 1748 intent.setComponent(null); 1749 // Only the primary user will receive notification of incoming mms. 1750 // That app will do the actual downloading of the mms. 1751 long duration = mPowerWhitelistManager.whitelistAppTemporarilyForEvent( 1752 mContext.getPackageName(), 1753 PowerWhitelistManager.EVENT_MMS, 1754 REASON_EVENT_MMS, 1755 "mms-broadcast"); 1756 BroadcastOptions bopts = BroadcastOptions.makeBasic(); 1757 bopts.setTemporaryAppAllowlist(duration, 1758 TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, 1759 REASON_EVENT_MMS, 1760 ""); 1761 Bundle options = bopts.toBundle(); 1762 1763 String mimeType = intent.getType(); 1764 1765 setWaitingForIntent(intent); 1766 dispatchIntent(intent, WapPushOverSms.getPermissionForType(mimeType), 1767 WapPushOverSms.getAppOpsStringPermissionForIntent(mimeType), options, this, 1768 UserHandle.SYSTEM, subId); 1769 } else { 1770 // Now that the intents have been deleted we can clean up the PDU data. 1771 if (!Intents.DATA_SMS_RECEIVED_ACTION.equals(action) 1772 && !Intents.SMS_RECEIVED_ACTION.equals(action) 1773 && !Intents.WAP_PUSH_RECEIVED_ACTION.equals(action)) { 1774 loge("unexpected BroadcastReceiver action: " + action); 1775 } 1776 1777 if (onReceive) { 1778 int rc = getResultCode(); 1779 if ((rc != Activity.RESULT_OK) && (rc != Intents.RESULT_SMS_HANDLED)) { 1780 loge("a broadcast receiver set the result code to " + rc 1781 + ", deleting from raw table anyway!"); 1782 } else if (DBG) { 1783 log("successful broadcast, deleting from raw table."); 1784 } 1785 } 1786 1787 deleteFromRawTable(mDeleteWhere, mDeleteWhereArgs, MARK_DELETED); 1788 mWaitingForIntent = null; 1789 removeMessages(EVENT_RECEIVER_TIMEOUT); 1790 sendMessage(EVENT_BROADCAST_COMPLETE); 1791 } 1792 } 1793 } 1794 1795 /** 1796 * Callback that handles filtering results by carrier services. 1797 */ 1798 private final class CarrierServicesSmsFilterCallback implements 1799 CarrierServicesSmsFilter.CarrierServicesSmsFilterCallbackInterface { 1800 private final byte[][] mPdus; 1801 private final int mDestPort; 1802 private final InboundSmsTracker mTracker; 1803 private final String mSmsFormat; 1804 private final SmsBroadcastReceiver mSmsBroadcastReceiver; 1805 private final boolean mUserUnlocked; 1806 private final boolean mIsClass0; 1807 private final int mSubId; 1808 private final long mMessageId; 1809 private final boolean mBlock; 1810 private final List<SmsFilter> mRemainingFilters; 1811 CarrierServicesSmsFilterCallback(byte[][] pdus, int destPort, InboundSmsTracker tracker, String smsFormat, SmsBroadcastReceiver smsBroadcastReceiver, boolean userUnlocked, boolean isClass0, int subId, long messageId, boolean block, List<SmsFilter> remainingFilters)1812 CarrierServicesSmsFilterCallback(byte[][] pdus, int destPort, InboundSmsTracker tracker, 1813 String smsFormat, SmsBroadcastReceiver smsBroadcastReceiver, boolean userUnlocked, 1814 boolean isClass0, int subId, long messageId, boolean block, 1815 List<SmsFilter> remainingFilters) { 1816 mPdus = pdus; 1817 mDestPort = destPort; 1818 mTracker = tracker; 1819 mSmsFormat = smsFormat; 1820 mSmsBroadcastReceiver = smsBroadcastReceiver; 1821 mUserUnlocked = userUnlocked; 1822 mIsClass0 = isClass0; 1823 mSubId = subId; 1824 mMessageId = messageId; 1825 mBlock = block; 1826 mRemainingFilters = remainingFilters; 1827 } 1828 1829 @Override onFilterComplete(int result)1830 public void onFilterComplete(int result) { 1831 log("onFilterComplete: result is " + result, mTracker.getMessageId()); 1832 1833 boolean carrierRequestedDrop = 1834 (result & CarrierMessagingService.RECEIVE_OPTIONS_DROP) != 0; 1835 if (carrierRequestedDrop) { 1836 // Carrier app asked the platform to drop the SMS. Drop it from the database and 1837 // complete processing. 1838 dropFilteredSms(mTracker, mSmsBroadcastReceiver, mBlock); 1839 return; 1840 } 1841 1842 boolean filterInvoked = filterSms(mPdus, mDestPort, mTracker, mSmsBroadcastReceiver, 1843 mUserUnlocked, mBlock, mRemainingFilters); 1844 if (filterInvoked) { 1845 // A remaining filter has assumed responsibility for further message processing. 1846 return; 1847 } 1848 1849 // Now that all filters have been invoked, drop the message if it is blocked. 1850 if (mBlock) { 1851 // Only delete the message if the user is unlocked. Otherwise, we should reprocess 1852 // the message after unlock so the filter has a chance to run while credential- 1853 // encrypted storage is available. 1854 if (mUserUnlocked) { 1855 log("onFilterComplete: dropping message as the sender is blocked", 1856 mTracker.getMessageId()); 1857 dropFilteredSms(mTracker, mSmsBroadcastReceiver, mBlock); 1858 } else { 1859 // Just complete handling of the message without dropping it. 1860 sendMessage(EVENT_BROADCAST_COMPLETE); 1861 } 1862 return; 1863 } 1864 1865 // Message matched no filters and is not blocked, so complete processing. 1866 if (mUserUnlocked) { 1867 dispatchSmsDeliveryIntent( 1868 mPdus, mSmsFormat, mDestPort, mSmsBroadcastReceiver, mIsClass0, mSubId, 1869 mMessageId); 1870 } else { 1871 // Don't do anything further, leave the message in the raw table if the 1872 // credential-encrypted storage is still locked and show the new message 1873 // notification if the message is visible to the user. 1874 if (!isSkipNotifyFlagSet(result)) { 1875 showNewMessageNotification(); 1876 } 1877 sendMessage(EVENT_BROADCAST_COMPLETE); 1878 } 1879 } 1880 } 1881 dropSms(SmsBroadcastReceiver receiver)1882 private void dropSms(SmsBroadcastReceiver receiver) { 1883 // Needs phone package permissions. 1884 deleteFromRawTable(receiver.mDeleteWhere, receiver.mDeleteWhereArgs, MARK_DELETED); 1885 sendMessage(EVENT_BROADCAST_COMPLETE); 1886 } 1887 1888 /** Checks whether the flag to skip new message notification is set in the bitmask returned 1889 * from the carrier app. 1890 */ 1891 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) isSkipNotifyFlagSet(int callbackResult)1892 private boolean isSkipNotifyFlagSet(int callbackResult) { 1893 return (callbackResult 1894 & RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE) > 0; 1895 } 1896 1897 /** 1898 * Log with debug level in logcat and LocalLog 1899 * @param logMsg msg to log 1900 */ logWithLocalLog(String logMsg)1901 protected void logWithLocalLog(String logMsg) { 1902 log(logMsg); 1903 mLocalLog.log(logMsg); 1904 } 1905 1906 /** 1907 * Log with debug level in logcat and LocalLog 1908 * @param logMsg msg to log 1909 * @param id unique message id 1910 */ logWithLocalLog(String logMsg, long id)1911 protected void logWithLocalLog(String logMsg, long id) { 1912 log(logMsg, id); 1913 mLocalLog.log(logMsg + ", " + SmsController.formatCrossStackMessageId(id)); 1914 } 1915 1916 /** 1917 * Log with error level in logcat and LocalLog 1918 * @param logMsg msg to log 1919 */ logeWithLocalLog(String logMsg)1920 protected void logeWithLocalLog(String logMsg) { 1921 loge(logMsg); 1922 mLocalLog.log(logMsg); 1923 } 1924 1925 /** 1926 * Log with error level in logcat and LocalLog 1927 * @param logMsg msg to log 1928 * @param id unique message id 1929 */ logeWithLocalLog(String logMsg, long id)1930 protected void logeWithLocalLog(String logMsg, long id) { 1931 loge(logMsg, id); 1932 mLocalLog.log(logMsg + ", " + SmsController.formatCrossStackMessageId(id)); 1933 } 1934 1935 /** 1936 * Log with debug level. 1937 * @param s the string to log 1938 */ 1939 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 1940 @Override log(String s)1941 protected void log(String s) { 1942 Rlog.d(getName(), s); 1943 } 1944 1945 /** 1946 * Log with debug level. 1947 * @param s the string to log 1948 * @param id unique message id 1949 */ log(String s, long id)1950 protected void log(String s, long id) { 1951 log(s + ", " + SmsController.formatCrossStackMessageId(id)); 1952 } 1953 1954 /** 1955 * Log with error level. 1956 * @param s the string to log 1957 */ 1958 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 1959 @Override loge(String s)1960 protected void loge(String s) { 1961 Rlog.e(getName(), s); 1962 } 1963 1964 /** 1965 * Log with error level. 1966 * @param s the string to log 1967 * @param id unique message id 1968 */ loge(String s, long id)1969 protected void loge(String s, long id) { 1970 loge(s + ", " + SmsController.formatCrossStackMessageId(id)); 1971 } 1972 1973 /** 1974 * Log with error level. 1975 * @param s the string to log 1976 * @param e is a Throwable which logs additional information. 1977 */ 1978 @Override loge(String s, Throwable e)1979 protected void loge(String s, Throwable e) { 1980 Rlog.e(getName(), s, e); 1981 } 1982 1983 /** 1984 * Build up the SMS message body from the SmsMessage array of received SMS 1985 * 1986 * @param msgs The SmsMessage array of the received SMS 1987 * @return The text message body 1988 */ buildMessageBodyFromPdus(SmsMessage[] msgs)1989 private static String buildMessageBodyFromPdus(SmsMessage[] msgs) { 1990 if (msgs.length == 1) { 1991 // There is only one part, so grab the body directly. 1992 return replaceFormFeeds(msgs[0].getDisplayMessageBody()); 1993 } else { 1994 // Build up the body from the parts. 1995 StringBuilder body = new StringBuilder(); 1996 for (SmsMessage msg: msgs) { 1997 // getDisplayMessageBody() can NPE if mWrappedMessage inside is null. 1998 body.append(msg.getDisplayMessageBody()); 1999 } 2000 return replaceFormFeeds(body.toString()); 2001 } 2002 } 2003 2004 @Override dump(FileDescriptor fd, PrintWriter printWriter, String[] args)2005 public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { 2006 IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); 2007 pw.println(getName() + " extends StateMachine:"); 2008 pw.increaseIndent(); 2009 super.dump(fd, pw, args); 2010 if (mCellBroadcastServiceManager != null) { 2011 mCellBroadcastServiceManager.dump(fd, pw, args); 2012 } 2013 pw.println("mLocalLog:"); 2014 pw.increaseIndent(); 2015 mLocalLog.dump(fd, pw, args); 2016 pw.decreaseIndent(); 2017 pw.println("mCarrierServiceLocalLog:"); 2018 pw.increaseIndent(); 2019 mCarrierServiceLocalLog.dump(fd, pw, args); 2020 pw.decreaseIndent(); 2021 pw.decreaseIndent(); 2022 } 2023 2024 // Some providers send formfeeds in their messages. Convert those formfeeds to newlines. replaceFormFeeds(String s)2025 private static String replaceFormFeeds(String s) { 2026 return s == null ? "" : s.replace('\f', '\n'); 2027 } 2028 2029 @VisibleForTesting getWakeLock()2030 public PowerManager.WakeLock getWakeLock() { 2031 return mWakeLock; 2032 } 2033 2034 @VisibleForTesting getWakeLockTimeout()2035 public int getWakeLockTimeout() { 2036 return mWakeLockTimeout; 2037 } 2038 2039 /** 2040 * Sets the wakelock timeout to {@link timeOut} milliseconds 2041 */ setWakeLockTimeout(int timeOut)2042 private void setWakeLockTimeout(int timeOut) { 2043 mWakeLockTimeout = timeOut; 2044 } 2045 2046 /** 2047 * Set the SMS filters used by {@link #filterSms} for testing purposes. 2048 * 2049 * @param smsFilters List of SMS filters, or null to restore the default filters. 2050 */ 2051 @VisibleForTesting setSmsFiltersForTesting(@ullable List<SmsFilter> smsFilters)2052 public void setSmsFiltersForTesting(@Nullable List<SmsFilter> smsFilters) { 2053 if (smsFilters == null) { 2054 mSmsFilters = createDefaultSmsFilters(); 2055 } else { 2056 mSmsFilters = smsFilters; 2057 } 2058 } 2059 2060 /** 2061 * Handler for the broadcast sent when the new message notification is clicked. It launches the 2062 * default SMS app. 2063 */ 2064 private static class NewMessageNotificationActionReceiver extends BroadcastReceiver { 2065 @Override onReceive(Context context, Intent intent)2066 public void onReceive(Context context, Intent intent) { 2067 if (ACTION_OPEN_SMS_APP.equals(intent.getAction())) { 2068 // do nothing if the user had not unlocked the device yet 2069 UserManager userManager = 2070 (UserManager) context.getSystemService(Context.USER_SERVICE); 2071 if (userManager.isUserUnlocked()) { 2072 context.startActivity(context.getPackageManager().getLaunchIntentForPackage( 2073 Telephony.Sms.getDefaultSmsPackage(context))); 2074 } 2075 } 2076 } 2077 } 2078 decodeHexString(String hexString)2079 protected byte[] decodeHexString(String hexString) { 2080 if (hexString == null || hexString.length() % 2 == 1) { 2081 return null; 2082 } 2083 byte[] bytes = new byte[hexString.length() / 2]; 2084 for (int i = 0; i < hexString.length(); i += 2) { 2085 bytes[i / 2] = hexToByte(hexString.substring(i, i + 2)); 2086 } 2087 return bytes; 2088 } 2089 hexToByte(String hexString)2090 private byte hexToByte(String hexString) { 2091 int firstDigit = toDigit(hexString.charAt(0)); 2092 int secondDigit = toDigit(hexString.charAt(1)); 2093 return (byte) ((firstDigit << 4) + secondDigit); 2094 } 2095 toDigit(char hexChar)2096 private int toDigit(char hexChar) { 2097 int digit = Character.digit(hexChar, 16); 2098 if (digit == -1) { 2099 return 0; 2100 } 2101 return digit; 2102 } 2103 2104 2105 /** 2106 * Registers the broadcast receiver to launch the default SMS app when the user clicks the 2107 * new message notification. 2108 */ registerNewMessageNotificationActionHandler(Context context)2109 static void registerNewMessageNotificationActionHandler(Context context) { 2110 IntentFilter userFilter = new IntentFilter(); 2111 userFilter.addAction(ACTION_OPEN_SMS_APP); 2112 context.registerReceiver(new NewMessageNotificationActionReceiver(), userFilter); 2113 } 2114 2115 protected abstract class CbTestBroadcastReceiver extends BroadcastReceiver { 2116 handleTestAction(Intent intent)2117 protected abstract void handleTestAction(Intent intent); 2118 2119 protected final String mTestAction; 2120 CbTestBroadcastReceiver(String testAction)2121 public CbTestBroadcastReceiver(String testAction) { 2122 mTestAction = testAction; 2123 } 2124 2125 @Override onReceive(Context context, Intent intent)2126 public void onReceive(Context context, Intent intent) { 2127 logd("Received test intent action=" + intent.getAction()); 2128 if (intent.getAction().equals(mTestAction)) { 2129 // Return early if phone_id is explicilty included and does not match mPhone. 2130 // If phone_id extra is not included, continue. 2131 int phoneId = mPhone.getPhoneId(); 2132 if (intent.getIntExtra("phone_id", phoneId) != phoneId) { 2133 return; 2134 } 2135 handleTestAction(intent); 2136 } 2137 } 2138 } 2139 2140 /** A filter for incoming messages allowing the normal processing flow to be skipped. */ 2141 @VisibleForTesting 2142 public interface SmsFilter { 2143 /** 2144 * Returns true if a filter is invoked and the SMS processing flow should be diverted, false 2145 * otherwise. 2146 * 2147 * <p>If the filter can immediately determine that the message matches, it must call 2148 * {@link #dropFilteredSms} to drop the message from the database once it has been 2149 * processed. 2150 * 2151 * <p>If the filter must perform some asynchronous work to determine if the message matches, 2152 * it should return true to defer processing. Once it has made a determination, if it finds 2153 * the message matches, it must call {@link #dropFilteredSms}. If the message does not 2154 * match, it must be passed through {@code remainingFilters} and either dropped if the 2155 * remaining filters all return false or if {@code block} is true, or else it must be 2156 * broadcast. 2157 */ filterSms(byte[][] pdus, int destPort, InboundSmsTracker tracker, SmsBroadcastReceiver resultReceiver, boolean userUnlocked, boolean block, List<SmsFilter> remainingFilters)2158 boolean filterSms(byte[][] pdus, int destPort, InboundSmsTracker tracker, 2159 SmsBroadcastReceiver resultReceiver, boolean userUnlocked, boolean block, 2160 List<SmsFilter> remainingFilters); 2161 } 2162 } 2163