1 /* 2 * Copyright (C) 2007 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.server; 18 19 import android.app.ActivityManager; 20 import android.app.AppOpsManager; 21 import android.content.BroadcastReceiver; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.IntentFilter; 25 import android.content.pm.PackageManager; 26 import android.net.LinkProperties; 27 import android.net.NetworkCapabilities; 28 import android.os.Binder; 29 import android.os.Bundle; 30 import android.os.Handler; 31 import android.os.IBinder; 32 import android.os.Message; 33 import android.os.RemoteException; 34 import android.os.UserHandle; 35 import android.telephony.CellInfo; 36 import android.telephony.CellLocation; 37 import android.telephony.DisconnectCause; 38 import android.telephony.PhoneStateListener; 39 import android.telephony.PreciseCallState; 40 import android.telephony.PreciseDataConnectionState; 41 import android.telephony.PreciseDisconnectCause; 42 import android.telephony.Rlog; 43 import android.telephony.ServiceState; 44 import android.telephony.SignalStrength; 45 import android.telephony.SubscriptionManager; 46 import android.telephony.TelephonyManager; 47 import android.telephony.VoLteServiceState; 48 import android.text.TextUtils; 49 import android.util.LocalLog; 50 51 import com.android.internal.app.IBatteryStats; 52 import com.android.internal.telephony.IOnSubscriptionsChangedListener; 53 import com.android.internal.telephony.IPhoneStateListener; 54 import com.android.internal.telephony.ITelephonyRegistry; 55 import com.android.internal.telephony.PhoneConstantConversions; 56 import com.android.internal.telephony.PhoneConstants; 57 import com.android.internal.telephony.TelephonyIntents; 58 import com.android.internal.util.DumpUtils; 59 import com.android.internal.util.IndentingPrintWriter; 60 import com.android.server.am.BatteryStatsService; 61 62 import java.io.FileDescriptor; 63 import java.io.PrintWriter; 64 import java.util.ArrayList; 65 import java.util.Arrays; 66 import java.util.List; 67 68 /** 69 * Since phone process can be restarted, this class provides a centralized place 70 * that applications can register and be called back from. 71 * 72 * Change-Id: I450c968bda93767554b5188ee63e10c9f43c5aa4 fixes bugs 16148026 73 * and 15973975 by saving the phoneId of the registrant and then using the 74 * phoneId when deciding to to make a callback. This is necessary because 75 * a subId changes from to a dummy value when a SIM is removed and thus won't 76 * compare properly. Because SubscriptionManager.getPhoneId(int subId) handles 77 * the dummy value conversion we properly do the callbacks. 78 * 79 * Eventually we may want to remove the notion of dummy value but for now this 80 * looks like the best approach. 81 */ 82 class TelephonyRegistry extends ITelephonyRegistry.Stub { 83 private static final String TAG = "TelephonyRegistry"; 84 private static final boolean DBG = false; // STOPSHIP if true 85 private static final boolean DBG_LOC = false; // STOPSHIP if true 86 private static final boolean VDBG = false; // STOPSHIP if true 87 88 private static class Record { 89 String callingPackage; 90 91 IBinder binder; 92 93 IPhoneStateListener callback; 94 IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback; 95 96 int callerUserId; 97 98 int events; 99 100 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 101 102 int phoneId = SubscriptionManager.INVALID_PHONE_INDEX; 103 104 boolean canReadPhoneState; 105 106 boolean matchPhoneStateListenerEvent(int events) { 107 return (callback != null) && ((events & this.events) != 0); 108 } 109 110 boolean matchOnSubscriptionsChangedListener() { 111 return (onSubscriptionsChangedListenerCallback != null); 112 } 113 114 @Override 115 public String toString() { 116 return "{callingPackage=" + callingPackage + " binder=" + binder 117 + " callback=" + callback 118 + " onSubscriptionsChangedListenererCallback=" 119 + onSubscriptionsChangedListenerCallback 120 + " callerUserId=" + callerUserId + " subId=" + subId + " phoneId=" + phoneId 121 + " events=" + Integer.toHexString(events) 122 + " canReadPhoneState=" + canReadPhoneState + "}"; 123 } 124 } 125 126 private final Context mContext; 127 128 // access should be inside synchronized (mRecords) for these two fields 129 private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>(); 130 private final ArrayList<Record> mRecords = new ArrayList<Record>(); 131 132 private final IBatteryStats mBatteryStats; 133 134 private final AppOpsManager mAppOps; 135 136 private boolean hasNotifySubscriptionInfoChangedOccurred = false; 137 138 private int mNumPhones; 139 140 private int[] mCallState; 141 142 private String[] mCallIncomingNumber; 143 144 private ServiceState[] mServiceState; 145 146 private int[] mVoiceActivationState; 147 148 private int[] mDataActivationState; 149 150 private SignalStrength[] mSignalStrength; 151 152 private boolean[] mMessageWaiting; 153 154 private boolean[] mCallForwarding; 155 156 private int[] mDataActivity; 157 158 private int[] mDataConnectionState; 159 160 private ArrayList<String>[] mConnectedApns; 161 162 private LinkProperties[] mDataConnectionLinkProperties; 163 164 private NetworkCapabilities[] mDataConnectionNetworkCapabilities; 165 166 private Bundle[] mCellLocation; 167 168 private int[] mDataConnectionNetworkType; 169 170 private int mOtaspMode = TelephonyManager.OTASP_UNKNOWN; 171 172 private ArrayList<List<CellInfo>> mCellInfo = null; 173 174 private VoLteServiceState mVoLteServiceState = new VoLteServiceState(); 175 176 private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 177 178 private int mDefaultPhoneId = SubscriptionManager.INVALID_PHONE_INDEX; 179 180 private int mRingingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE; 181 182 private int mForegroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE; 183 184 private int mBackgroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE; 185 186 private PreciseCallState mPreciseCallState = new PreciseCallState(); 187 188 private boolean mCarrierNetworkChangeState = false; 189 190 private final LocalLog mLocalLog = new LocalLog(100); 191 192 private PreciseDataConnectionState mPreciseDataConnectionState = 193 new PreciseDataConnectionState(); 194 195 static final int ENFORCE_PHONE_STATE_PERMISSION_MASK = 196 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR | 197 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR | 198 PhoneStateListener.LISTEN_VOLTE_STATE; 199 200 static final int CHECK_PHONE_STATE_PERMISSION_MASK = 201 PhoneStateListener.LISTEN_CALL_STATE | 202 PhoneStateListener.LISTEN_DATA_ACTIVITY | 203 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE; 204 205 static final int PRECISE_PHONE_STATE_PERMISSION_MASK = 206 PhoneStateListener.LISTEN_PRECISE_CALL_STATE | 207 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE; 208 209 private static final int MSG_USER_SWITCHED = 1; 210 private static final int MSG_UPDATE_DEFAULT_SUB = 2; 211 212 private final Handler mHandler = new Handler() { 213 @Override 214 public void handleMessage(Message msg) { 215 switch (msg.what) { 216 case MSG_USER_SWITCHED: { 217 if (VDBG) log("MSG_USER_SWITCHED userId=" + msg.arg1); 218 int numPhones = TelephonyManager.getDefault().getPhoneCount(); 219 for (int sub = 0; sub < numPhones; sub++) { 220 TelephonyRegistry.this.notifyCellLocationForSubscriber(sub, 221 mCellLocation[sub]); 222 } 223 break; 224 } 225 case MSG_UPDATE_DEFAULT_SUB: { 226 int newDefaultPhoneId = msg.arg1; 227 int newDefaultSubId = (Integer)(msg.obj); 228 if (VDBG) { 229 log("MSG_UPDATE_DEFAULT_SUB:current mDefaultSubId=" + mDefaultSubId 230 + " current mDefaultPhoneId=" + mDefaultPhoneId + " newDefaultSubId= " 231 + newDefaultSubId + " newDefaultPhoneId=" + newDefaultPhoneId); 232 } 233 234 //Due to possible risk condition,(notify call back using the new 235 //defaultSubId comes before new defaultSubId update) we need to recall all 236 //possible missed notify callback 237 synchronized (mRecords) { 238 for (Record r : mRecords) { 239 if(r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { 240 checkPossibleMissNotify(r, newDefaultPhoneId); 241 } 242 } 243 handleRemoveListLocked(); 244 } 245 mDefaultSubId = newDefaultSubId; 246 mDefaultPhoneId = newDefaultPhoneId; 247 } 248 } 249 } 250 }; 251 252 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 253 @Override 254 public void onReceive(Context context, Intent intent) { 255 String action = intent.getAction(); 256 if (VDBG) log("mBroadcastReceiver: action=" + action); 257 if (Intent.ACTION_USER_SWITCHED.equals(action)) { 258 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 259 if (DBG) log("onReceive: userHandle=" + userHandle); 260 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED, userHandle, 0)); 261 } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_SUBSCRIPTION_CHANGED)) { 262 Integer newDefaultSubIdObj = new Integer(intent.getIntExtra( 263 PhoneConstants.SUBSCRIPTION_KEY, 264 SubscriptionManager.getDefaultSubscriptionId())); 265 int newDefaultPhoneId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 266 SubscriptionManager.getPhoneId(mDefaultSubId)); 267 if (DBG) { 268 log("onReceive:current mDefaultSubId=" + mDefaultSubId 269 + " current mDefaultPhoneId=" + mDefaultPhoneId + " newDefaultSubId= " 270 + newDefaultSubIdObj + " newDefaultPhoneId=" + newDefaultPhoneId); 271 } 272 273 if(validatePhoneId(newDefaultPhoneId) && (!newDefaultSubIdObj.equals(mDefaultSubId) 274 || (newDefaultPhoneId != mDefaultPhoneId))) { 275 mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_DEFAULT_SUB, 276 newDefaultPhoneId, 0, newDefaultSubIdObj)); 277 } 278 } 279 } 280 }; 281 282 // we keep a copy of all of the state so we can send it out when folks 283 // register for it 284 // 285 // In these calls we call with the lock held. This is safe becasuse remote 286 // calls go through a oneway interface and local calls going through a 287 // handler before they get to app code. 288 289 TelephonyRegistry(Context context) { 290 CellLocation location = CellLocation.getEmpty(); 291 292 mContext = context; 293 mBatteryStats = BatteryStatsService.getService(); 294 295 int numPhones = TelephonyManager.getDefault().getPhoneCount(); 296 if (DBG) log("TelephonyRegistor: ctor numPhones=" + numPhones); 297 mNumPhones = numPhones; 298 mConnectedApns = new ArrayList[numPhones]; 299 mCallState = new int[numPhones]; 300 mDataActivity = new int[numPhones]; 301 mDataConnectionState = new int[numPhones]; 302 mDataConnectionNetworkType = new int[numPhones]; 303 mCallIncomingNumber = new String[numPhones]; 304 mServiceState = new ServiceState[numPhones]; 305 mVoiceActivationState = new int[numPhones]; 306 mDataActivationState = new int[numPhones]; 307 mSignalStrength = new SignalStrength[numPhones]; 308 mMessageWaiting = new boolean[numPhones]; 309 mCallForwarding = new boolean[numPhones]; 310 mCellLocation = new Bundle[numPhones]; 311 mDataConnectionLinkProperties = new LinkProperties[numPhones]; 312 mDataConnectionNetworkCapabilities = new NetworkCapabilities[numPhones]; 313 mCellInfo = new ArrayList<List<CellInfo>>(); 314 for (int i = 0; i < numPhones; i++) { 315 mCallState[i] = TelephonyManager.CALL_STATE_IDLE; 316 mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE; 317 mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN; 318 mVoiceActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; 319 mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; 320 mCallIncomingNumber[i] = ""; 321 mServiceState[i] = new ServiceState(); 322 mSignalStrength[i] = new SignalStrength(); 323 mMessageWaiting[i] = false; 324 mCallForwarding[i] = false; 325 mCellLocation[i] = new Bundle(); 326 mCellInfo.add(i, null); 327 mConnectedApns[i] = new ArrayList<String>(); 328 } 329 330 // Note that location can be null for non-phone builds like 331 // like the generic one. 332 if (location != null) { 333 for (int i = 0; i < numPhones; i++) { 334 location.fillInNotifierBundle(mCellLocation[i]); 335 } 336 } 337 338 mAppOps = mContext.getSystemService(AppOpsManager.class); 339 } 340 341 public void systemRunning() { 342 // Watch for interesting updates 343 final IntentFilter filter = new IntentFilter(); 344 filter.addAction(Intent.ACTION_USER_SWITCHED); 345 filter.addAction(Intent.ACTION_USER_REMOVED); 346 filter.addAction(TelephonyIntents.ACTION_DEFAULT_SUBSCRIPTION_CHANGED); 347 log("systemRunning register for intents"); 348 mContext.registerReceiver(mBroadcastReceiver, filter); 349 } 350 351 @Override 352 public void addOnSubscriptionsChangedListener(String callingPackage, 353 IOnSubscriptionsChangedListener callback) { 354 int callerUserId = UserHandle.getCallingUserId(); 355 if (VDBG) { 356 log("listen oscl: E pkg=" + callingPackage + " myUserId=" + UserHandle.myUserId() 357 + " callerUserId=" + callerUserId + " callback=" + callback 358 + " callback.asBinder=" + callback.asBinder()); 359 } 360 361 try { 362 mContext.enforceCallingOrSelfPermission( 363 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 364 "addOnSubscriptionsChangedListener"); 365 // SKIP checking for run-time permission since caller or self has PRIVILEGED permission 366 } catch (SecurityException e) { 367 mContext.enforceCallingOrSelfPermission( 368 android.Manifest.permission.READ_PHONE_STATE, 369 "addOnSubscriptionsChangedListener"); 370 371 if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(), 372 callingPackage) != AppOpsManager.MODE_ALLOWED) { 373 return; 374 } 375 } 376 377 Record r; 378 379 synchronized (mRecords) { 380 // register 381 find_and_add: { 382 IBinder b = callback.asBinder(); 383 final int N = mRecords.size(); 384 for (int i = 0; i < N; i++) { 385 r = mRecords.get(i); 386 if (b == r.binder) { 387 break find_and_add; 388 } 389 } 390 r = new Record(); 391 r.binder = b; 392 mRecords.add(r); 393 if (DBG) log("listen oscl: add new record"); 394 } 395 396 r.onSubscriptionsChangedListenerCallback = callback; 397 r.callingPackage = callingPackage; 398 r.callerUserId = callerUserId; 399 r.events = 0; 400 r.canReadPhoneState = true; // permission has been enforced above 401 if (DBG) { 402 log("listen oscl: Register r=" + r); 403 } 404 // Always notify when registration occurs if there has been a notification. 405 if (hasNotifySubscriptionInfoChangedOccurred) { 406 try { 407 if (VDBG) log("listen oscl: send to r=" + r); 408 r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged(); 409 if (VDBG) log("listen oscl: sent to r=" + r); 410 } catch (RemoteException e) { 411 if (VDBG) log("listen oscl: remote exception sending to r=" + r + " e=" + e); 412 remove(r.binder); 413 } 414 } else { 415 log("listen oscl: hasNotifySubscriptionInfoChangedOccurred==false no callback"); 416 } 417 } 418 } 419 420 @Override 421 public void removeOnSubscriptionsChangedListener(String pkgForDebug, 422 IOnSubscriptionsChangedListener callback) { 423 if (DBG) log("listen oscl: Unregister"); 424 remove(callback.asBinder()); 425 } 426 427 @Override 428 public void notifySubscriptionInfoChanged() { 429 if (VDBG) log("notifySubscriptionInfoChanged:"); 430 synchronized (mRecords) { 431 if (!hasNotifySubscriptionInfoChangedOccurred) { 432 log("notifySubscriptionInfoChanged: first invocation mRecords.size=" 433 + mRecords.size()); 434 } 435 hasNotifySubscriptionInfoChangedOccurred = true; 436 mRemoveList.clear(); 437 for (Record r : mRecords) { 438 if (r.matchOnSubscriptionsChangedListener()) { 439 try { 440 if (VDBG) log("notifySubscriptionInfoChanged: call osc to r=" + r); 441 r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged(); 442 if (VDBG) log("notifySubscriptionInfoChanged: done osc to r=" + r); 443 } catch (RemoteException ex) { 444 if (VDBG) log("notifySubscriptionInfoChanged: RemoteException r=" + r); 445 mRemoveList.add(r.binder); 446 } 447 } 448 } 449 handleRemoveListLocked(); 450 } 451 } 452 453 @Override 454 public void listen(String pkgForDebug, IPhoneStateListener callback, int events, 455 boolean notifyNow) { 456 listenForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, pkgForDebug, callback, 457 events, notifyNow); 458 } 459 460 @Override 461 public void listenForSubscriber(int subId, String pkgForDebug, IPhoneStateListener callback, 462 int events, boolean notifyNow) { 463 listen(pkgForDebug, callback, events, notifyNow, subId); 464 } 465 466 private void listen(String callingPackage, IPhoneStateListener callback, int events, 467 boolean notifyNow, int subId) { 468 int callerUserId = UserHandle.getCallingUserId(); 469 if (VDBG) { 470 log("listen: E pkg=" + callingPackage + " events=0x" + Integer.toHexString(events) 471 + " notifyNow=" + notifyNow + " subId=" + subId + " myUserId=" 472 + UserHandle.myUserId() + " callerUserId=" + callerUserId); 473 } 474 475 if (events != PhoneStateListener.LISTEN_NONE) { 476 /* Checks permission and throws Security exception */ 477 checkListenerPermission(events); 478 479 if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) { 480 try { 481 mContext.enforceCallingOrSelfPermission( 482 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); 483 // SKIP checking for run-time permission since caller or self has PRIVILEGED 484 // permission 485 } catch (SecurityException e) { 486 if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(), 487 callingPackage) != AppOpsManager.MODE_ALLOWED) { 488 return; 489 } 490 } 491 } 492 493 synchronized (mRecords) { 494 // register 495 Record r; 496 find_and_add: { 497 IBinder b = callback.asBinder(); 498 final int N = mRecords.size(); 499 for (int i = 0; i < N; i++) { 500 r = mRecords.get(i); 501 if (b == r.binder) { 502 break find_and_add; 503 } 504 } 505 r = new Record(); 506 r.binder = b; 507 mRecords.add(r); 508 if (DBG) log("listen: add new record"); 509 } 510 511 r.callback = callback; 512 r.callingPackage = callingPackage; 513 r.callerUserId = callerUserId; 514 boolean isPhoneStateEvent = (events & (CHECK_PHONE_STATE_PERMISSION_MASK 515 | ENFORCE_PHONE_STATE_PERMISSION_MASK)) != 0; 516 r.canReadPhoneState = isPhoneStateEvent && canReadPhoneState(callingPackage); 517 // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID, 518 // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID 519 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 520 r.subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; 521 } else {//APP specify subID 522 r.subId = subId; 523 } 524 r.phoneId = SubscriptionManager.getPhoneId(r.subId); 525 526 int phoneId = r.phoneId; 527 r.events = events; 528 if (DBG) { 529 log("listen: Register r=" + r + " r.subId=" + r.subId + " phoneId=" + phoneId); 530 } 531 if (notifyNow && validatePhoneId(phoneId)) { 532 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { 533 try { 534 if (VDBG) log("listen: call onSSC state=" + mServiceState[phoneId]); 535 r.callback.onServiceStateChanged( 536 new ServiceState(mServiceState[phoneId])); 537 } catch (RemoteException ex) { 538 remove(r.binder); 539 } 540 } 541 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { 542 try { 543 int gsmSignalStrength = mSignalStrength[phoneId] 544 .getGsmSignalStrength(); 545 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 546 : gsmSignalStrength)); 547 } catch (RemoteException ex) { 548 remove(r.binder); 549 } 550 } 551 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { 552 try { 553 r.callback.onMessageWaitingIndicatorChanged( 554 mMessageWaiting[phoneId]); 555 } catch (RemoteException ex) { 556 remove(r.binder); 557 } 558 } 559 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { 560 try { 561 r.callback.onCallForwardingIndicatorChanged( 562 mCallForwarding[phoneId]); 563 } catch (RemoteException ex) { 564 remove(r.binder); 565 } 566 } 567 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { 568 try { 569 if (DBG_LOC) log("listen: mCellLocation = " 570 + mCellLocation[phoneId]); 571 r.callback.onCellLocationChanged( 572 new Bundle(mCellLocation[phoneId])); 573 } catch (RemoteException ex) { 574 remove(r.binder); 575 } 576 } 577 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) { 578 try { 579 r.callback.onCallStateChanged(mCallState[phoneId], 580 getCallIncomingNumber(r, phoneId)); 581 } catch (RemoteException ex) { 582 remove(r.binder); 583 } 584 } 585 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { 586 try { 587 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], 588 mDataConnectionNetworkType[phoneId]); 589 } catch (RemoteException ex) { 590 remove(r.binder); 591 } 592 } 593 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) { 594 try { 595 r.callback.onDataActivity(mDataActivity[phoneId]); 596 } catch (RemoteException ex) { 597 remove(r.binder); 598 } 599 } 600 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { 601 try { 602 r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]); 603 } catch (RemoteException ex) { 604 remove(r.binder); 605 } 606 } 607 if ((events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) { 608 try { 609 r.callback.onOtaspChanged(mOtaspMode); 610 } catch (RemoteException ex) { 611 remove(r.binder); 612 } 613 } 614 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) { 615 try { 616 if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = " 617 + mCellInfo.get(phoneId)); 618 r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); 619 } catch (RemoteException ex) { 620 remove(r.binder); 621 } 622 } 623 if ((events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) { 624 try { 625 r.callback.onPreciseCallStateChanged(mPreciseCallState); 626 } catch (RemoteException ex) { 627 remove(r.binder); 628 } 629 } 630 if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { 631 try { 632 r.callback.onPreciseDataConnectionStateChanged( 633 mPreciseDataConnectionState); 634 } catch (RemoteException ex) { 635 remove(r.binder); 636 } 637 } 638 if ((events & PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) != 0) { 639 try { 640 r.callback.onCarrierNetworkChange(mCarrierNetworkChangeState); 641 } catch (RemoteException ex) { 642 remove(r.binder); 643 } 644 } 645 if ((events & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) !=0) { 646 try { 647 r.callback.onVoiceActivationStateChanged(mVoiceActivationState[phoneId]); 648 } catch (RemoteException ex) { 649 remove(r.binder); 650 } 651 } 652 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) !=0) { 653 try { 654 r.callback.onDataActivationStateChanged(mDataActivationState[phoneId]); 655 } catch (RemoteException ex) { 656 remove(r.binder); 657 } 658 } 659 } 660 } 661 } else { 662 if(DBG) log("listen: Unregister"); 663 remove(callback.asBinder()); 664 } 665 } 666 667 private boolean canReadPhoneState(String callingPackage) { 668 if (mContext.checkCallingOrSelfPermission( 669 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) == 670 PackageManager.PERMISSION_GRANTED) { 671 // SKIP checking for run-time permission since caller or self has PRIVILEGED permission 672 return true; 673 } 674 boolean canReadPhoneState = mContext.checkCallingOrSelfPermission( 675 android.Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED; 676 if (canReadPhoneState && 677 mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(), 678 callingPackage) != AppOpsManager.MODE_ALLOWED) { 679 return false; 680 } 681 return canReadPhoneState; 682 } 683 684 private String getCallIncomingNumber(Record record, int phoneId) { 685 // Hide the number if record's process has no READ_PHONE_STATE permission 686 return record.canReadPhoneState ? mCallIncomingNumber[phoneId] : ""; 687 } 688 689 private void remove(IBinder binder) { 690 synchronized (mRecords) { 691 final int recordCount = mRecords.size(); 692 for (int i = 0; i < recordCount; i++) { 693 if (mRecords.get(i).binder == binder) { 694 if (DBG) { 695 Record r = mRecords.get(i); 696 log("remove: binder=" + binder + "r.callingPackage" + r.callingPackage 697 + "r.callback" + r.callback); 698 } 699 mRecords.remove(i); 700 return; 701 } 702 } 703 } 704 } 705 706 public void notifyCallState(int state, String incomingNumber) { 707 if (!checkNotifyPermission("notifyCallState()")) { 708 return; 709 } 710 711 if (VDBG) { 712 log("notifyCallState: state=" + state + " incomingNumber=" + incomingNumber); 713 } 714 715 synchronized (mRecords) { 716 for (Record r : mRecords) { 717 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) && 718 (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { 719 try { 720 String incomingNumberOrEmpty = r.canReadPhoneState ? incomingNumber : ""; 721 r.callback.onCallStateChanged(state, incomingNumberOrEmpty); 722 } catch (RemoteException ex) { 723 mRemoveList.add(r.binder); 724 } 725 } 726 } 727 handleRemoveListLocked(); 728 } 729 730 // Called only by Telecomm to communicate call state across different phone accounts. So 731 // there is no need to add a valid subId or slotId. 732 broadcastCallStateChanged(state, incomingNumber, 733 SubscriptionManager.INVALID_PHONE_INDEX, 734 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 735 } 736 737 public void notifyCallStateForPhoneId(int phoneId, int subId, int state, 738 String incomingNumber) { 739 if (!checkNotifyPermission("notifyCallState()")) { 740 return; 741 } 742 if (VDBG) { 743 log("notifyCallStateForPhoneId: subId=" + subId 744 + " state=" + state + " incomingNumber=" + incomingNumber); 745 } 746 synchronized (mRecords) { 747 if (validatePhoneId(phoneId)) { 748 mCallState[phoneId] = state; 749 mCallIncomingNumber[phoneId] = incomingNumber; 750 for (Record r : mRecords) { 751 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) && 752 (r.subId == subId) && 753 (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { 754 try { 755 String incomingNumberOrEmpty = getCallIncomingNumber(r, phoneId); 756 r.callback.onCallStateChanged(state, incomingNumberOrEmpty); 757 } catch (RemoteException ex) { 758 mRemoveList.add(r.binder); 759 } 760 } 761 } 762 } 763 handleRemoveListLocked(); 764 } 765 broadcastCallStateChanged(state, incomingNumber, phoneId, subId); 766 } 767 768 public void notifyServiceStateForPhoneId(int phoneId, int subId, ServiceState state) { 769 if (!checkNotifyPermission("notifyServiceState()")){ 770 return; 771 } 772 773 synchronized (mRecords) { 774 String str = "notifyServiceStateForSubscriber: subId=" + subId + " phoneId=" + phoneId 775 + " state=" + state; 776 if (VDBG) { 777 log(str); 778 } 779 mLocalLog.log(str); 780 if (validatePhoneId(phoneId)) { 781 mServiceState[phoneId] = state; 782 783 for (Record r : mRecords) { 784 if (VDBG) { 785 log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId 786 + " phoneId=" + phoneId + " state=" + state); 787 } 788 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SERVICE_STATE) && 789 idMatch(r.subId, subId, phoneId)) { 790 try { 791 if (DBG) { 792 log("notifyServiceStateForSubscriber: callback.onSSC r=" + r 793 + " subId=" + subId + " phoneId=" + phoneId 794 + " state=" + state); 795 } 796 r.callback.onServiceStateChanged(new ServiceState(state)); 797 } catch (RemoteException ex) { 798 mRemoveList.add(r.binder); 799 } 800 } 801 } 802 } else { 803 log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId); 804 } 805 handleRemoveListLocked(); 806 } 807 broadcastServiceStateChanged(state, phoneId, subId); 808 } 809 810 public void notifySimActivationStateChangedForPhoneId(int phoneId, int subId, 811 int activationType, int activationState) { 812 if (!checkNotifyPermission("notifySimActivationState()")){ 813 return; 814 } 815 if (VDBG) { 816 log("notifySimActivationStateForPhoneId: subId=" + subId + " phoneId=" + phoneId 817 + "type=" + activationType + " state=" + activationState); 818 } 819 synchronized (mRecords) { 820 if (validatePhoneId(phoneId)) { 821 switch (activationType) { 822 case PhoneConstants.SIM_ACTIVATION_TYPE_VOICE: 823 mVoiceActivationState[phoneId] = activationState; 824 break; 825 case PhoneConstants.SIM_ACTIVATION_TYPE_DATA: 826 mDataActivationState[phoneId] = activationState; 827 break; 828 default: 829 return; 830 } 831 for (Record r : mRecords) { 832 if (VDBG) { 833 log("notifySimActivationStateForPhoneId: r=" + r + " subId=" + subId 834 + " phoneId=" + phoneId + "type=" + activationType 835 + " state=" + activationState); 836 } 837 try { 838 if ((activationType == PhoneConstants.SIM_ACTIVATION_TYPE_VOICE) && 839 r.matchPhoneStateListenerEvent( 840 PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) && 841 idMatch(r.subId, subId, phoneId)) { 842 if (DBG) { 843 log("notifyVoiceActivationStateForPhoneId: callback.onVASC r=" + r 844 + " subId=" + subId + " phoneId=" + phoneId 845 + " state=" + activationState); 846 } 847 r.callback.onVoiceActivationStateChanged(activationState); 848 } 849 if ((activationType == PhoneConstants.SIM_ACTIVATION_TYPE_DATA) && 850 r.matchPhoneStateListenerEvent( 851 PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) && 852 idMatch(r.subId, subId, phoneId)) { 853 if (DBG) { 854 log("notifyDataActivationStateForPhoneId: callback.onDASC r=" + r 855 + " subId=" + subId + " phoneId=" + phoneId 856 + " state=" + activationState); 857 } 858 r.callback.onDataActivationStateChanged(activationState); 859 } 860 } catch (RemoteException ex) { 861 mRemoveList.add(r.binder); 862 } 863 } 864 } else { 865 log("notifySimActivationStateForPhoneId: INVALID phoneId=" + phoneId); 866 } 867 handleRemoveListLocked(); 868 } 869 } 870 871 public void notifySignalStrengthForPhoneId(int phoneId, int subId, 872 SignalStrength signalStrength) { 873 if (!checkNotifyPermission("notifySignalStrength()")) { 874 return; 875 } 876 if (VDBG) { 877 log("notifySignalStrengthForPhoneId: subId=" + subId 878 +" phoneId=" + phoneId + " signalStrength=" + signalStrength); 879 } 880 881 synchronized (mRecords) { 882 if (validatePhoneId(phoneId)) { 883 if (VDBG) log("notifySignalStrengthForPhoneId: valid phoneId=" + phoneId); 884 mSignalStrength[phoneId] = signalStrength; 885 for (Record r : mRecords) { 886 if (VDBG) { 887 log("notifySignalStrengthForPhoneId: r=" + r + " subId=" + subId 888 + " phoneId=" + phoneId + " ss=" + signalStrength); 889 } 890 if (r.matchPhoneStateListenerEvent( 891 PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) && 892 idMatch(r.subId, subId, phoneId)) { 893 try { 894 if (DBG) { 895 log("notifySignalStrengthForPhoneId: callback.onSsS r=" + r 896 + " subId=" + subId + " phoneId=" + phoneId 897 + " ss=" + signalStrength); 898 } 899 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); 900 } catch (RemoteException ex) { 901 mRemoveList.add(r.binder); 902 } 903 } 904 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTH) && 905 idMatch(r.subId, subId, phoneId)){ 906 try { 907 int gsmSignalStrength = signalStrength.getGsmSignalStrength(); 908 int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); 909 if (DBG) { 910 log("notifySignalStrengthForPhoneId: callback.onSS r=" + r 911 + " subId=" + subId + " phoneId=" + phoneId 912 + " gsmSS=" + gsmSignalStrength + " ss=" + ss); 913 } 914 r.callback.onSignalStrengthChanged(ss); 915 } catch (RemoteException ex) { 916 mRemoveList.add(r.binder); 917 } 918 } 919 } 920 } else { 921 log("notifySignalStrengthForPhoneId: invalid phoneId=" + phoneId); 922 } 923 handleRemoveListLocked(); 924 } 925 broadcastSignalStrengthChanged(signalStrength, phoneId, subId); 926 } 927 928 @Override 929 public void notifyCarrierNetworkChange(boolean active) { 930 enforceNotifyPermissionOrCarrierPrivilege("notifyCarrierNetworkChange()"); 931 932 if (VDBG) { 933 log("notifyCarrierNetworkChange: active=" + active); 934 } 935 936 synchronized (mRecords) { 937 mCarrierNetworkChangeState = active; 938 for (Record r : mRecords) { 939 if (r.matchPhoneStateListenerEvent( 940 PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE)) { 941 try { 942 r.callback.onCarrierNetworkChange(active); 943 } catch (RemoteException ex) { 944 mRemoveList.add(r.binder); 945 } 946 } 947 } 948 handleRemoveListLocked(); 949 } 950 } 951 952 public void notifyCellInfo(List<CellInfo> cellInfo) { 953 notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellInfo); 954 } 955 956 public void notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo) { 957 if (!checkNotifyPermission("notifyCellInfo()")) { 958 return; 959 } 960 if (VDBG) { 961 log("notifyCellInfoForSubscriber: subId=" + subId 962 + " cellInfo=" + cellInfo); 963 } 964 965 synchronized (mRecords) { 966 int phoneId = SubscriptionManager.getPhoneId(subId); 967 if (validatePhoneId(phoneId)) { 968 mCellInfo.set(phoneId, cellInfo); 969 for (Record r : mRecords) { 970 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) && 971 idMatch(r.subId, subId, phoneId)) { 972 try { 973 if (DBG_LOC) { 974 log("notifyCellInfo: mCellInfo=" + cellInfo + " r=" + r); 975 } 976 r.callback.onCellInfoChanged(cellInfo); 977 } catch (RemoteException ex) { 978 mRemoveList.add(r.binder); 979 } 980 } 981 } 982 } 983 handleRemoveListLocked(); 984 } 985 } 986 987 @Override 988 public void notifyMessageWaitingChangedForPhoneId(int phoneId, int subId, boolean mwi) { 989 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) { 990 return; 991 } 992 if (VDBG) { 993 log("notifyMessageWaitingChangedForSubscriberPhoneID: subId=" + phoneId 994 + " mwi=" + mwi); 995 } 996 synchronized (mRecords) { 997 if (validatePhoneId(phoneId)) { 998 mMessageWaiting[phoneId] = mwi; 999 for (Record r : mRecords) { 1000 if (r.matchPhoneStateListenerEvent( 1001 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) && 1002 idMatch(r.subId, subId, phoneId)) { 1003 try { 1004 r.callback.onMessageWaitingIndicatorChanged(mwi); 1005 } catch (RemoteException ex) { 1006 mRemoveList.add(r.binder); 1007 } 1008 } 1009 } 1010 } 1011 handleRemoveListLocked(); 1012 } 1013 } 1014 1015 public void notifyCallForwardingChanged(boolean cfi) { 1016 notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cfi); 1017 } 1018 1019 public void notifyCallForwardingChangedForSubscriber(int subId, boolean cfi) { 1020 if (!checkNotifyPermission("notifyCallForwardingChanged()")) { 1021 return; 1022 } 1023 if (VDBG) { 1024 log("notifyCallForwardingChangedForSubscriber: subId=" + subId 1025 + " cfi=" + cfi); 1026 } 1027 synchronized (mRecords) { 1028 int phoneId = SubscriptionManager.getPhoneId(subId); 1029 if (validatePhoneId(phoneId)) { 1030 mCallForwarding[phoneId] = cfi; 1031 for (Record r : mRecords) { 1032 if (r.matchPhoneStateListenerEvent( 1033 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) && 1034 idMatch(r.subId, subId, phoneId)) { 1035 try { 1036 r.callback.onCallForwardingIndicatorChanged(cfi); 1037 } catch (RemoteException ex) { 1038 mRemoveList.add(r.binder); 1039 } 1040 } 1041 } 1042 } 1043 handleRemoveListLocked(); 1044 } 1045 } 1046 1047 public void notifyDataActivity(int state) { 1048 notifyDataActivityForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state); 1049 } 1050 1051 public void notifyDataActivityForSubscriber(int subId, int state) { 1052 if (!checkNotifyPermission("notifyDataActivity()" )) { 1053 return; 1054 } 1055 synchronized (mRecords) { 1056 int phoneId = SubscriptionManager.getPhoneId(subId); 1057 if (validatePhoneId(phoneId)) { 1058 mDataActivity[phoneId] = state; 1059 for (Record r : mRecords) { 1060 // Notify by correct subId. 1061 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_DATA_ACTIVITY) && 1062 idMatch(r.subId, subId, phoneId)) { 1063 try { 1064 r.callback.onDataActivity(state); 1065 } catch (RemoteException ex) { 1066 mRemoveList.add(r.binder); 1067 } 1068 } 1069 } 1070 } 1071 handleRemoveListLocked(); 1072 } 1073 } 1074 1075 public void notifyDataConnection(int state, boolean isDataAllowed, 1076 String reason, String apn, String apnType, LinkProperties linkProperties, 1077 NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { 1078 notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state, 1079 isDataAllowed,reason, apn, apnType, linkProperties, 1080 networkCapabilities, networkType, roaming); 1081 } 1082 1083 public void notifyDataConnectionForSubscriber(int subId, int state, 1084 boolean isDataAllowed, String reason, String apn, String apnType, 1085 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 1086 int networkType, boolean roaming) { 1087 if (!checkNotifyPermission("notifyDataConnection()" )) { 1088 return; 1089 } 1090 if (VDBG) { 1091 log("notifyDataConnectionForSubscriber: subId=" + subId 1092 + " state=" + state + " isDataAllowed=" + isDataAllowed 1093 + " reason='" + reason 1094 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType 1095 + " mRecords.size()=" + mRecords.size()); 1096 } 1097 synchronized (mRecords) { 1098 int phoneId = SubscriptionManager.getPhoneId(subId); 1099 if (validatePhoneId(phoneId)) { 1100 boolean modified = false; 1101 if (state == TelephonyManager.DATA_CONNECTED) { 1102 if (!mConnectedApns[phoneId].contains(apnType)) { 1103 mConnectedApns[phoneId].add(apnType); 1104 if (mDataConnectionState[phoneId] != state) { 1105 mDataConnectionState[phoneId] = state; 1106 modified = true; 1107 } 1108 } 1109 } else { 1110 if (mConnectedApns[phoneId].remove(apnType)) { 1111 if (mConnectedApns[phoneId].isEmpty()) { 1112 mDataConnectionState[phoneId] = state; 1113 modified = true; 1114 } else { 1115 // leave mDataConnectionState as is and 1116 // send out the new status for the APN in question. 1117 } 1118 } 1119 } 1120 mDataConnectionLinkProperties[phoneId] = linkProperties; 1121 mDataConnectionNetworkCapabilities[phoneId] = networkCapabilities; 1122 if (mDataConnectionNetworkType[phoneId] != networkType) { 1123 mDataConnectionNetworkType[phoneId] = networkType; 1124 // need to tell registered listeners about the new network type 1125 modified = true; 1126 } 1127 if (modified) { 1128 String str = "onDataConnectionStateChanged(" + mDataConnectionState[phoneId] 1129 + ", " + mDataConnectionNetworkType[phoneId] + ")"; 1130 log(str); 1131 mLocalLog.log(str); 1132 for (Record r : mRecords) { 1133 if (r.matchPhoneStateListenerEvent( 1134 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) && 1135 idMatch(r.subId, subId, phoneId)) { 1136 try { 1137 if (DBG) { 1138 log("Notify data connection state changed on sub: " + subId); 1139 } 1140 r.callback.onDataConnectionStateChanged( 1141 mDataConnectionState[phoneId], 1142 mDataConnectionNetworkType[phoneId]); 1143 } catch (RemoteException ex) { 1144 mRemoveList.add(r.binder); 1145 } 1146 } 1147 } 1148 handleRemoveListLocked(); 1149 } 1150 mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType, 1151 apnType, apn, reason, linkProperties, ""); 1152 for (Record r : mRecords) { 1153 if (r.matchPhoneStateListenerEvent( 1154 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { 1155 try { 1156 r.callback.onPreciseDataConnectionStateChanged( 1157 mPreciseDataConnectionState); 1158 } catch (RemoteException ex) { 1159 mRemoveList.add(r.binder); 1160 } 1161 } 1162 } 1163 } 1164 handleRemoveListLocked(); 1165 } 1166 broadcastDataConnectionStateChanged(state, isDataAllowed, reason, apn, 1167 apnType, linkProperties, networkCapabilities, roaming, subId); 1168 broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, reason, 1169 linkProperties, ""); 1170 } 1171 1172 public void notifyDataConnectionFailed(String reason, String apnType) { 1173 notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, 1174 reason, apnType); 1175 } 1176 1177 public void notifyDataConnectionFailedForSubscriber(int subId, 1178 String reason, String apnType) { 1179 if (!checkNotifyPermission("notifyDataConnectionFailed()")) { 1180 return; 1181 } 1182 if (VDBG) { 1183 log("notifyDataConnectionFailedForSubscriber: subId=" + subId 1184 + " reason=" + reason + " apnType=" + apnType); 1185 } 1186 synchronized (mRecords) { 1187 mPreciseDataConnectionState = new PreciseDataConnectionState( 1188 TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN, 1189 apnType, "", reason, null, ""); 1190 for (Record r : mRecords) { 1191 if (r.matchPhoneStateListenerEvent( 1192 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { 1193 try { 1194 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 1195 } catch (RemoteException ex) { 1196 mRemoveList.add(r.binder); 1197 } 1198 } 1199 } 1200 handleRemoveListLocked(); 1201 } 1202 broadcastDataConnectionFailed(reason, apnType, subId); 1203 broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN, 1204 TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", reason, null, ""); 1205 } 1206 1207 public void notifyCellLocation(Bundle cellLocation) { 1208 notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation); 1209 } 1210 1211 public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) { 1212 log("notifyCellLocationForSubscriber: subId=" + subId 1213 + " cellLocation=" + cellLocation); 1214 if (!checkNotifyPermission("notifyCellLocation()")) { 1215 return; 1216 } 1217 if (VDBG) { 1218 log("notifyCellLocationForSubscriber: subId=" + subId 1219 + " cellLocation=" + cellLocation); 1220 } 1221 synchronized (mRecords) { 1222 int phoneId = SubscriptionManager.getPhoneId(subId); 1223 if (validatePhoneId(phoneId)) { 1224 mCellLocation[phoneId] = cellLocation; 1225 for (Record r : mRecords) { 1226 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) && 1227 idMatch(r.subId, subId, phoneId)) { 1228 try { 1229 if (DBG_LOC) { 1230 log("notifyCellLocation: cellLocation=" + cellLocation 1231 + " r=" + r); 1232 } 1233 r.callback.onCellLocationChanged(new Bundle(cellLocation)); 1234 } catch (RemoteException ex) { 1235 mRemoveList.add(r.binder); 1236 } 1237 } 1238 } 1239 } 1240 handleRemoveListLocked(); 1241 } 1242 } 1243 1244 public void notifyOtaspChanged(int otaspMode) { 1245 if (!checkNotifyPermission("notifyOtaspChanged()" )) { 1246 return; 1247 } 1248 synchronized (mRecords) { 1249 mOtaspMode = otaspMode; 1250 for (Record r : mRecords) { 1251 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_OTASP_CHANGED)) { 1252 try { 1253 r.callback.onOtaspChanged(otaspMode); 1254 } catch (RemoteException ex) { 1255 mRemoveList.add(r.binder); 1256 } 1257 } 1258 } 1259 handleRemoveListLocked(); 1260 } 1261 } 1262 1263 public void notifyPreciseCallState(int ringingCallState, int foregroundCallState, 1264 int backgroundCallState) { 1265 if (!checkNotifyPermission("notifyPreciseCallState()")) { 1266 return; 1267 } 1268 synchronized (mRecords) { 1269 mRingingCallState = ringingCallState; 1270 mForegroundCallState = foregroundCallState; 1271 mBackgroundCallState = backgroundCallState; 1272 mPreciseCallState = new PreciseCallState(ringingCallState, foregroundCallState, 1273 backgroundCallState, 1274 DisconnectCause.NOT_VALID, 1275 PreciseDisconnectCause.NOT_VALID); 1276 for (Record r : mRecords) { 1277 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_PRECISE_CALL_STATE)) { 1278 try { 1279 r.callback.onPreciseCallStateChanged(mPreciseCallState); 1280 } catch (RemoteException ex) { 1281 mRemoveList.add(r.binder); 1282 } 1283 } 1284 } 1285 handleRemoveListLocked(); 1286 } 1287 broadcastPreciseCallStateChanged(ringingCallState, foregroundCallState, backgroundCallState, 1288 DisconnectCause.NOT_VALID, 1289 PreciseDisconnectCause.NOT_VALID); 1290 } 1291 1292 public void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause) { 1293 if (!checkNotifyPermission("notifyDisconnectCause()")) { 1294 return; 1295 } 1296 synchronized (mRecords) { 1297 mPreciseCallState = new PreciseCallState(mRingingCallState, mForegroundCallState, 1298 mBackgroundCallState, disconnectCause, preciseDisconnectCause); 1299 for (Record r : mRecords) { 1300 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_PRECISE_CALL_STATE)) { 1301 try { 1302 r.callback.onPreciseCallStateChanged(mPreciseCallState); 1303 } catch (RemoteException ex) { 1304 mRemoveList.add(r.binder); 1305 } 1306 } 1307 } 1308 handleRemoveListLocked(); 1309 } 1310 broadcastPreciseCallStateChanged(mRingingCallState, mForegroundCallState, 1311 mBackgroundCallState, disconnectCause, preciseDisconnectCause); 1312 } 1313 1314 public void notifyPreciseDataConnectionFailed(String reason, String apnType, 1315 String apn, String failCause) { 1316 if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) { 1317 return; 1318 } 1319 synchronized (mRecords) { 1320 mPreciseDataConnectionState = new PreciseDataConnectionState( 1321 TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN, 1322 apnType, apn, reason, null, failCause); 1323 for (Record r : mRecords) { 1324 if (r.matchPhoneStateListenerEvent( 1325 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { 1326 try { 1327 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 1328 } catch (RemoteException ex) { 1329 mRemoveList.add(r.binder); 1330 } 1331 } 1332 } 1333 handleRemoveListLocked(); 1334 } 1335 broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN, 1336 TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause); 1337 } 1338 1339 public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) { 1340 if (!checkNotifyPermission("notifyVoLteServiceStateChanged()")) { 1341 return; 1342 } 1343 synchronized (mRecords) { 1344 mVoLteServiceState = lteState; 1345 for (Record r : mRecords) { 1346 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_VOLTE_STATE)) { 1347 try { 1348 r.callback.onVoLteServiceStateChanged( 1349 new VoLteServiceState(mVoLteServiceState)); 1350 } catch (RemoteException ex) { 1351 mRemoveList.add(r.binder); 1352 } 1353 } 1354 } 1355 handleRemoveListLocked(); 1356 } 1357 } 1358 1359 public void notifyOemHookRawEventForSubscriber(int subId, byte[] rawData) { 1360 if (!checkNotifyPermission("notifyOemHookRawEventForSubscriber")) { 1361 return; 1362 } 1363 1364 synchronized (mRecords) { 1365 for (Record r : mRecords) { 1366 if (VDBG) { 1367 log("notifyOemHookRawEventForSubscriber: r=" + r + " subId=" + subId); 1368 } 1369 if ((r.matchPhoneStateListenerEvent( 1370 PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT)) && 1371 ((r.subId == subId) || 1372 (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID))) { 1373 try { 1374 r.callback.onOemHookRawEvent(rawData); 1375 } catch (RemoteException ex) { 1376 mRemoveList.add(r.binder); 1377 } 1378 } 1379 } 1380 handleRemoveListLocked(); 1381 } 1382 } 1383 1384 @Override 1385 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 1386 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 1387 1388 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 1389 1390 synchronized (mRecords) { 1391 final int recordCount = mRecords.size(); 1392 pw.println("last known state:"); 1393 pw.increaseIndent(); 1394 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 1395 pw.println("Phone Id=" + i); 1396 pw.increaseIndent(); 1397 pw.println("mCallState=" + mCallState[i]); 1398 pw.println("mCallIncomingNumber=" + mCallIncomingNumber[i]); 1399 pw.println("mServiceState=" + mServiceState[i]); 1400 pw.println("mVoiceActivationState= " + mVoiceActivationState[i]); 1401 pw.println("mDataActivationState= " + mDataActivationState[i]); 1402 pw.println("mSignalStrength=" + mSignalStrength[i]); 1403 pw.println("mMessageWaiting=" + mMessageWaiting[i]); 1404 pw.println("mCallForwarding=" + mCallForwarding[i]); 1405 pw.println("mDataActivity=" + mDataActivity[i]); 1406 pw.println("mDataConnectionState=" + mDataConnectionState[i]); 1407 pw.println("mDataConnectionLinkProperties=" + mDataConnectionLinkProperties[i]); 1408 pw.println("mDataConnectionNetworkCapabilities=" + 1409 mDataConnectionNetworkCapabilities[i]); 1410 pw.println("mCellLocation=" + mCellLocation[i]); 1411 pw.println("mCellInfo=" + mCellInfo.get(i)); 1412 pw.decreaseIndent(); 1413 } 1414 pw.println("mConnectedApns=" + Arrays.toString(mConnectedApns)); 1415 pw.println("mPreciseDataConnectionState=" + mPreciseDataConnectionState); 1416 pw.println("mPreciseCallState=" + mPreciseCallState); 1417 pw.println("mCarrierNetworkChangeState=" + mCarrierNetworkChangeState); 1418 pw.println("mRingingCallState=" + mRingingCallState); 1419 pw.println("mForegroundCallState=" + mForegroundCallState); 1420 pw.println("mBackgroundCallState=" + mBackgroundCallState); 1421 pw.println("mVoLteServiceState=" + mVoLteServiceState); 1422 1423 pw.decreaseIndent(); 1424 1425 pw.println("local logs:"); 1426 pw.increaseIndent(); 1427 mLocalLog.dump(fd, pw, args); 1428 pw.decreaseIndent(); 1429 pw.println("registrations: count=" + recordCount); 1430 pw.increaseIndent(); 1431 for (Record r : mRecords) { 1432 pw.println(r); 1433 } 1434 pw.decreaseIndent(); 1435 } 1436 } 1437 1438 // 1439 // the legacy intent broadcasting 1440 // 1441 1442 private void broadcastServiceStateChanged(ServiceState state, int phoneId, int subId) { 1443 long ident = Binder.clearCallingIdentity(); 1444 try { 1445 mBatteryStats.notePhoneState(state.getState()); 1446 } catch (RemoteException re) { 1447 // Can't do much 1448 } finally { 1449 Binder.restoreCallingIdentity(ident); 1450 } 1451 1452 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); 1453 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 1454 Bundle data = new Bundle(); 1455 state.fillInNotifierBundle(data); 1456 intent.putExtras(data); 1457 // Pass the subscription along with the intent. 1458 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1459 intent.putExtra(PhoneConstants.SLOT_KEY, phoneId); 1460 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1461 } 1462 1463 private void broadcastSignalStrengthChanged(SignalStrength signalStrength, int phoneId, 1464 int subId) { 1465 long ident = Binder.clearCallingIdentity(); 1466 try { 1467 mBatteryStats.notePhoneSignalStrength(signalStrength); 1468 } catch (RemoteException e) { 1469 /* The remote entity disappeared, we can safely ignore the exception. */ 1470 } finally { 1471 Binder.restoreCallingIdentity(ident); 1472 } 1473 1474 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED); 1475 Bundle data = new Bundle(); 1476 signalStrength.fillInNotifierBundle(data); 1477 intent.putExtras(data); 1478 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1479 intent.putExtra(PhoneConstants.SLOT_KEY, phoneId); 1480 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1481 } 1482 1483 /** 1484 * Broadcasts an intent notifying apps of a phone state change. {@code subId} can be 1485 * a valid subId, in which case this function fires a subId-specific intent, or it 1486 * can be {@code SubscriptionManager.INVALID_SUBSCRIPTION_ID}, in which case we send 1487 * a global state change broadcast ({@code TelephonyManager.ACTION_PHONE_STATE_CHANGED}). 1488 */ 1489 private void broadcastCallStateChanged(int state, String incomingNumber, int phoneId, 1490 int subId) { 1491 long ident = Binder.clearCallingIdentity(); 1492 try { 1493 if (state == TelephonyManager.CALL_STATE_IDLE) { 1494 mBatteryStats.notePhoneOff(); 1495 } else { 1496 mBatteryStats.notePhoneOn(); 1497 } 1498 } catch (RemoteException e) { 1499 /* The remote entity disappeared, we can safely ignore the exception. */ 1500 } finally { 1501 Binder.restoreCallingIdentity(ident); 1502 } 1503 1504 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED); 1505 intent.putExtra(PhoneConstants.STATE_KEY, 1506 PhoneConstantConversions.convertCallState(state).toString()); 1507 if (!TextUtils.isEmpty(incomingNumber)) { 1508 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber); 1509 } 1510 1511 // If a valid subId was specified, we should fire off a subId-specific state 1512 // change intent and include the subId. 1513 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 1514 intent.setAction(PhoneConstants.ACTION_SUBSCRIPTION_PHONE_STATE_CHANGED); 1515 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1516 } 1517 // If the phoneId is invalid, the broadcast is for overall call state. 1518 if (phoneId != SubscriptionManager.INVALID_PHONE_INDEX) { 1519 intent.putExtra(PhoneConstants.SLOT_KEY, phoneId); 1520 } 1521 1522 // Wakeup apps for the (SUBSCRIPTION_)PHONE_STATE broadcast. 1523 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 1524 1525 // Send broadcast twice, once for apps that have PRIVILEGED permission and once for those 1526 // that have the runtime one 1527 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1528 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE); 1529 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1530 android.Manifest.permission.READ_PHONE_STATE, 1531 AppOpsManager.OP_READ_PHONE_STATE); 1532 } 1533 1534 private void broadcastDataConnectionStateChanged(int state, 1535 boolean isDataAllowed, 1536 String reason, String apn, String apnType, LinkProperties linkProperties, 1537 NetworkCapabilities networkCapabilities, boolean roaming, int subId) { 1538 // Note: not reporting to the battery stats service here, because the 1539 // status bar takes care of that after taking into account all of the 1540 // required info. 1541 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); 1542 intent.putExtra(PhoneConstants.STATE_KEY, 1543 PhoneConstantConversions.convertDataState(state).toString()); 1544 if (!isDataAllowed) { 1545 intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true); 1546 } 1547 if (reason != null) { 1548 intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); 1549 } 1550 if (linkProperties != null) { 1551 intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties); 1552 String iface = linkProperties.getInterfaceName(); 1553 if (iface != null) { 1554 intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface); 1555 } 1556 } 1557 if (networkCapabilities != null) { 1558 intent.putExtra(PhoneConstants.DATA_NETWORK_CAPABILITIES_KEY, networkCapabilities); 1559 } 1560 if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true); 1561 1562 intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); 1563 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1564 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1565 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1566 } 1567 1568 private void broadcastDataConnectionFailed(String reason, String apnType, 1569 int subId) { 1570 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED); 1571 intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason); 1572 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1573 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1574 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1575 } 1576 1577 private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState, 1578 int backgroundCallState, int disconnectCause, int preciseDisconnectCause) { 1579 Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED); 1580 intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState); 1581 intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState); 1582 intent.putExtra(TelephonyManager.EXTRA_BACKGROUND_CALL_STATE, backgroundCallState); 1583 intent.putExtra(TelephonyManager.EXTRA_DISCONNECT_CAUSE, disconnectCause); 1584 intent.putExtra(TelephonyManager.EXTRA_PRECISE_DISCONNECT_CAUSE, preciseDisconnectCause); 1585 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1586 android.Manifest.permission.READ_PRECISE_PHONE_STATE); 1587 } 1588 1589 private void broadcastPreciseDataConnectionStateChanged(int state, int networkType, 1590 String apnType, String apn, String reason, LinkProperties linkProperties, 1591 String failCause) { 1592 Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED); 1593 intent.putExtra(PhoneConstants.STATE_KEY, state); 1594 intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType); 1595 if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); 1596 if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1597 if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); 1598 if (linkProperties != null) { 1599 intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY,linkProperties); 1600 } 1601 if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause); 1602 1603 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1604 android.Manifest.permission.READ_PRECISE_PHONE_STATE); 1605 } 1606 1607 private void enforceNotifyPermissionOrCarrierPrivilege(String method) { 1608 if (checkNotifyPermission()) { 1609 return; 1610 } 1611 1612 enforceCarrierPrivilege(); 1613 } 1614 1615 private boolean checkNotifyPermission(String method) { 1616 if (checkNotifyPermission()) { 1617 return true; 1618 } 1619 String msg = "Modify Phone State Permission Denial: " + method + " from pid=" 1620 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid(); 1621 if (DBG) log(msg); 1622 return false; 1623 } 1624 1625 private boolean checkNotifyPermission() { 1626 return mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) 1627 == PackageManager.PERMISSION_GRANTED; 1628 } 1629 1630 private void enforceCarrierPrivilege() { 1631 TelephonyManager tm = TelephonyManager.getDefault(); 1632 String[] pkgs = mContext.getPackageManager().getPackagesForUid(Binder.getCallingUid()); 1633 for (String pkg : pkgs) { 1634 if (tm.checkCarrierPrivilegesForPackage(pkg) == 1635 TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 1636 return; 1637 } 1638 } 1639 1640 String msg = "Carrier Privilege Permission Denial: from pid=" + Binder.getCallingPid() 1641 + ", uid=" + Binder.getCallingUid(); 1642 if (DBG) log(msg); 1643 throw new SecurityException(msg); 1644 } 1645 1646 private void checkListenerPermission(int events) { 1647 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { 1648 mContext.enforceCallingOrSelfPermission( 1649 android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 1650 1651 } 1652 1653 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) { 1654 mContext.enforceCallingOrSelfPermission( 1655 android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 1656 1657 } 1658 1659 if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) { 1660 try { 1661 mContext.enforceCallingOrSelfPermission( 1662 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); 1663 // SKIP checking for run-time permission since caller or self has PRIVILEGED 1664 // permission 1665 } catch (SecurityException e) { 1666 mContext.enforceCallingOrSelfPermission( 1667 android.Manifest.permission.READ_PHONE_STATE, null); 1668 } 1669 } 1670 1671 if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) { 1672 mContext.enforceCallingOrSelfPermission( 1673 android.Manifest.permission.READ_PRECISE_PHONE_STATE, null); 1674 1675 } 1676 1677 if ((events & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) { 1678 mContext.enforceCallingOrSelfPermission( 1679 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); 1680 } 1681 } 1682 1683 private void handleRemoveListLocked() { 1684 int size = mRemoveList.size(); 1685 if (VDBG) log("handleRemoveListLocked: mRemoveList.size()=" + size); 1686 if (size > 0) { 1687 for (IBinder b: mRemoveList) { 1688 remove(b); 1689 } 1690 mRemoveList.clear(); 1691 } 1692 } 1693 1694 private boolean validateEventsAndUserLocked(Record r, int events) { 1695 int foregroundUser; 1696 long callingIdentity = Binder.clearCallingIdentity(); 1697 boolean valid = false; 1698 try { 1699 foregroundUser = ActivityManager.getCurrentUser(); 1700 valid = r.callerUserId == foregroundUser && r.matchPhoneStateListenerEvent(events); 1701 if (DBG | DBG_LOC) { 1702 log("validateEventsAndUserLocked: valid=" + valid 1703 + " r.callerUserId=" + r.callerUserId + " foregroundUser=" + foregroundUser 1704 + " r.events=" + r.events + " events=" + events); 1705 } 1706 } finally { 1707 Binder.restoreCallingIdentity(callingIdentity); 1708 } 1709 return valid; 1710 } 1711 1712 private boolean validatePhoneId(int phoneId) { 1713 boolean valid = (phoneId >= 0) && (phoneId < mNumPhones); 1714 if (VDBG) log("validatePhoneId: " + valid); 1715 return valid; 1716 } 1717 1718 private static void log(String s) { 1719 Rlog.d(TAG, s); 1720 } 1721 1722 boolean idMatch(int rSubId, int subId, int phoneId) { 1723 1724 if(subId < 0) { 1725 // Invalid case, we need compare phoneId with default one. 1726 return (mDefaultPhoneId == phoneId); 1727 } 1728 if(rSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { 1729 return (subId == mDefaultSubId); 1730 } else { 1731 return (rSubId == subId); 1732 } 1733 } 1734 1735 private void checkPossibleMissNotify(Record r, int phoneId) { 1736 int events = r.events; 1737 1738 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { 1739 try { 1740 if (VDBG) log("checkPossibleMissNotify: onServiceStateChanged state=" + 1741 mServiceState[phoneId]); 1742 r.callback.onServiceStateChanged( 1743 new ServiceState(mServiceState[phoneId])); 1744 } catch (RemoteException ex) { 1745 mRemoveList.add(r.binder); 1746 } 1747 } 1748 1749 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { 1750 try { 1751 SignalStrength signalStrength = mSignalStrength[phoneId]; 1752 if (DBG) { 1753 log("checkPossibleMissNotify: onSignalStrengthsChanged SS=" + signalStrength); 1754 } 1755 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); 1756 } catch (RemoteException ex) { 1757 mRemoveList.add(r.binder); 1758 } 1759 } 1760 1761 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { 1762 try { 1763 int gsmSignalStrength = mSignalStrength[phoneId] 1764 .getGsmSignalStrength(); 1765 if (DBG) { 1766 log("checkPossibleMissNotify: onSignalStrengthChanged SS=" + 1767 gsmSignalStrength); 1768 } 1769 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 1770 : gsmSignalStrength)); 1771 } catch (RemoteException ex) { 1772 mRemoveList.add(r.binder); 1773 } 1774 } 1775 1776 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) { 1777 try { 1778 if (DBG_LOC) { 1779 log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = " 1780 + mCellInfo.get(phoneId)); 1781 } 1782 r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); 1783 } catch (RemoteException ex) { 1784 mRemoveList.add(r.binder); 1785 } 1786 } 1787 1788 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { 1789 try { 1790 if (VDBG) { 1791 log("checkPossibleMissNotify: onMessageWaitingIndicatorChanged phoneId=" 1792 + phoneId + " mwi=" + mMessageWaiting[phoneId]); 1793 } 1794 r.callback.onMessageWaitingIndicatorChanged( 1795 mMessageWaiting[phoneId]); 1796 } catch (RemoteException ex) { 1797 mRemoveList.add(r.binder); 1798 } 1799 } 1800 1801 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { 1802 try { 1803 if (VDBG) { 1804 log("checkPossibleMissNotify: onCallForwardingIndicatorChanged phoneId=" 1805 + phoneId + " cfi=" + mCallForwarding[phoneId]); 1806 } 1807 r.callback.onCallForwardingIndicatorChanged( 1808 mCallForwarding[phoneId]); 1809 } catch (RemoteException ex) { 1810 mRemoveList.add(r.binder); 1811 } 1812 } 1813 1814 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { 1815 try { 1816 if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = " 1817 + mCellLocation[phoneId]); 1818 r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId])); 1819 } catch (RemoteException ex) { 1820 mRemoveList.add(r.binder); 1821 } 1822 } 1823 1824 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { 1825 try { 1826 if (DBG) { 1827 log("checkPossibleMissNotify: onDataConnectionStateChanged(mDataConnectionState" 1828 + "=" + mDataConnectionState[phoneId] 1829 + ", mDataConnectionNetworkType=" + mDataConnectionNetworkType[phoneId] 1830 + ")"); 1831 } 1832 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], 1833 mDataConnectionNetworkType[phoneId]); 1834 } catch (RemoteException ex) { 1835 mRemoveList.add(r.binder); 1836 } 1837 } 1838 } 1839 } 1840