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