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