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