TelephonyRegistry.java revision 2d1ee982276f5dbd0e035778b731b48e4ef34515
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.SubscriptionInfo; 38import android.telephony.SubscriptionListener; 39import android.telephony.TelephonyManager; 40import android.telephony.SubscriptionManager; 41import android.telephony.PhoneStateListener; 42import android.telephony.ServiceState; 43import android.telephony.SignalStrength; 44import android.telephony.CellInfo; 45import android.telephony.VoLteServiceState; 46import android.telephony.TelephonyManager; 47import android.telephony.DisconnectCause; 48import android.telephony.PreciseCallState; 49import android.telephony.PreciseDataConnectionState; 50import android.telephony.PreciseDisconnectCause; 51import android.text.TextUtils; 52import android.text.format.Time; 53 54import java.util.ArrayList; 55import java.util.Calendar; 56import java.util.List; 57import java.io.FileDescriptor; 58import java.io.PrintWriter; 59 60import com.android.internal.app.IBatteryStats; 61import com.android.internal.telephony.ISubscriptionListener; 62import com.android.internal.telephony.ITelephonyRegistry; 63import com.android.internal.telephony.IPhoneStateListener; 64import com.android.internal.telephony.DefaultPhoneNotifier; 65import com.android.internal.telephony.PhoneConstants; 66import com.android.internal.telephony.ServiceStateTracker; 67import com.android.internal.telephony.TelephonyIntents; 68import com.android.server.am.BatteryStatsService; 69 70/** 71 * Since phone process can be restarted, this class provides a centralized place 72 * that applications can register and be called back from. 73 * 74 * Change-Id: I450c968bda93767554b5188ee63e10c9f43c5aa4 fixes bugs 16148026 75 * and 15973975 by saving the phoneId of the registrant and then using the 76 * phoneId when deciding to to make a callback. This is necessary because 77 * a subId changes from to a dummy value when a SIM is removed and thus won't 78 * compare properly. Because SubscriptionManager.getPhoneId(int subId) handles 79 * the dummy value conversion we properly do the callbacks. 80 * 81 * Eventually we may want to remove the notion of dummy value but for now this 82 * looks like the best approach. 83 */ 84class TelephonyRegistry extends ITelephonyRegistry.Stub { 85 private static final String TAG = "TelephonyRegistry"; 86 private static final boolean DBG = false; // STOPSHIP if true 87 private static final boolean DBG_LOC = false; // STOPSHIP if true 88 private static final boolean VDBG = false; // STOPSHIP if true 89 90 private static class Record { 91 String pkgForDebug; 92 93 IBinder binder; 94 95 IPhoneStateListener callback; 96 ISubscriptionListener subscriptionListenerCallback; 97 98 int callerUid; 99 100 int events; 101 102 int subId = SubscriptionManager.INVALID_SUB_ID; 103 104 int phoneId = SubscriptionManager.INVALID_PHONE_ID; 105 106 boolean matchPhoneStateListenerEvent(int events) { 107 return (callback != null) && ((events & this.events) != 0); 108 } 109 110 boolean matchSubscriptionListenerEvent(int events) { 111 return (subscriptionListenerCallback != null) && ((events & this.events) != 0); 112 } 113 114 @Override 115 public String toString() { 116 return "{pkgForDebug=" + pkgForDebug + " binder=" + binder + " callback=" + callback 117 + " subscriptionListenererCallback=" + subscriptionListenerCallback 118 + " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId 119 + " events=" + Integer.toHexString(events) + "}"; 120 } 121 } 122 123 private final Context mContext; 124 125 // access should be inside synchronized (mRecords) for these two fields 126 private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>(); 127 private final ArrayList<Record> mRecords = new ArrayList<Record>(); 128 129 private final IBatteryStats mBatteryStats; 130 131 private int mNumPhones; 132 133 private int[] mCallState; 134 135 private String[] mCallIncomingNumber; 136 137 private ServiceState[] mServiceState; 138 139 private SignalStrength[] mSignalStrength; 140 141 private boolean[] mMessageWaiting; 142 143 private boolean[] mCallForwarding; 144 145 private int[] mDataActivity; 146 147 private int[] mDataConnectionState; 148 149 private boolean[] mDataConnectionPossible; 150 151 private String[] mDataConnectionReason; 152 153 private String[] mDataConnectionApn; 154 155 private ArrayList<String> mConnectedApns; 156 157 private LinkProperties[] mDataConnectionLinkProperties; 158 159 private NetworkCapabilities[] mDataConnectionNetworkCapabilities; 160 161 private Bundle[] mCellLocation; 162 163 private int[] mDataConnectionNetworkType; 164 165 private int mOtaspMode = ServiceStateTracker.OTASP_UNKNOWN; 166 167 private ArrayList<List<CellInfo>> mCellInfo = null; 168 169 private VoLteServiceState mVoLteServiceState = new VoLteServiceState(); 170 171 private int mDefaultSubId = SubscriptionManager.INVALID_SUB_ID; 172 173 private int mDefaultPhoneId = SubscriptionManager.INVALID_PHONE_ID; 174 175 private DataConnectionRealTimeInfo mDcRtInfo = new DataConnectionRealTimeInfo(); 176 177 private int mRingingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE; 178 179 private int mForegroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE; 180 181 private int mBackgroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE; 182 183 private PreciseCallState mPreciseCallState = new PreciseCallState(); 184 185 private PreciseDataConnectionState mPreciseDataConnectionState = 186 new PreciseDataConnectionState(); 187 188 static final int PHONE_STATE_PERMISSION_MASK = 189 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR | 190 PhoneStateListener.LISTEN_CALL_STATE | 191 PhoneStateListener.LISTEN_DATA_ACTIVITY | 192 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE | 193 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR | 194 PhoneStateListener.LISTEN_VOLTE_STATE;; 195 196 static final int PRECISE_PHONE_STATE_PERMISSION_MASK = 197 PhoneStateListener.LISTEN_PRECISE_CALL_STATE | 198 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE; 199 200 private static final int MSG_USER_SWITCHED = 1; 201 private static final int MSG_UPDATE_DEFAULT_SUB = 2; 202 203 private final Handler mHandler = new Handler() { 204 @Override 205 public void handleMessage(Message msg) { 206 switch (msg.what) { 207 case MSG_USER_SWITCHED: { 208 if (VDBG) log("MSG_USER_SWITCHED userId=" + msg.arg1); 209 int numPhones = TelephonyManager.getDefault().getPhoneCount(); 210 for (int sub = 0; sub < numPhones; sub++) { 211 TelephonyRegistry.this.notifyCellLocationForSubscriber(sub, 212 mCellLocation[sub]); 213 } 214 break; 215 } 216 case MSG_UPDATE_DEFAULT_SUB: { 217 int newDefaultPhoneId = msg.arg1; 218 int newDefaultSubId = (Integer)(msg.obj); 219 if (VDBG) { 220 log("MSG_UPDATE_DEFAULT_SUB:current mDefaultSubId=" + mDefaultSubId 221 + " current mDefaultPhoneId=" + mDefaultPhoneId + " newDefaultSubId= " 222 + newDefaultSubId + " newDefaultPhoneId=" + newDefaultPhoneId); 223 } 224 225 //Due to possible risk condition,(notify call back using the new 226 //defaultSubId comes before new defaultSubId update) we need to recall all 227 //possible missed notify callback 228 synchronized (mRecords) { 229 for (Record r : mRecords) { 230 if(r.subId == SubscriptionManager.DEFAULT_SUB_ID) { 231 checkPossibleMissNotify(r, newDefaultPhoneId); 232 } 233 } 234 handleRemoveListLocked(); 235 } 236 mDefaultSubId = newDefaultSubId; 237 mDefaultPhoneId = newDefaultPhoneId; 238 } 239 } 240 } 241 }; 242 243 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 244 @Override 245 public void onReceive(Context context, Intent intent) { 246 String action = intent.getAction(); 247 if (VDBG) log("mBroadcastReceiver: action=" + action); 248 if (Intent.ACTION_USER_SWITCHED.equals(action)) { 249 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 250 if (DBG) log("onReceive: userHandle=" + userHandle); 251 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED, userHandle, 0)); 252 } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_SUBSCRIPTION_CHANGED)) { 253 Integer newDefaultSubIdObj = new Integer(intent.getIntExtra( 254 PhoneConstants.SUBSCRIPTION_KEY, SubscriptionManager.getDefaultSubId())); 255 int newDefaultPhoneId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 256 SubscriptionManager.getPhoneId(mDefaultSubId)); 257 if (DBG) { 258 log("onReceive:current mDefaultSubId=" + mDefaultSubId 259 + " current mDefaultPhoneId=" + mDefaultPhoneId + " newDefaultSubId= " 260 + newDefaultSubIdObj + " newDefaultPhoneId=" + newDefaultPhoneId); 261 } 262 263 if(validatePhoneId(newDefaultPhoneId) && (newDefaultSubIdObj.equals(mDefaultSubId) 264 || (newDefaultPhoneId != mDefaultPhoneId))) { 265 mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_DEFAULT_SUB, 266 newDefaultPhoneId, 0, newDefaultSubIdObj)); 267 } 268 } 269 } 270 }; 271 272 // we keep a copy of all of the state so we can send it out when folks 273 // register for it 274 // 275 // In these calls we call with the lock held. This is safe becasuse remote 276 // calls go through a oneway interface and local calls going through a 277 // handler before they get to app code. 278 279 TelephonyRegistry(Context context) { 280 CellLocation location = CellLocation.getEmpty(); 281 282 mContext = context; 283 mBatteryStats = BatteryStatsService.getService(); 284 mConnectedApns = new ArrayList<String>(); 285 286 int numPhones = TelephonyManager.getDefault().getPhoneCount(); 287 if (DBG) log("TelephonyRegistor: ctor numPhones=" + numPhones); 288 mNumPhones = numPhones; 289 mCallState = new int[numPhones]; 290 mDataActivity = new int[numPhones]; 291 mDataConnectionState = new int[numPhones]; 292 mDataConnectionNetworkType = new int[numPhones]; 293 mCallIncomingNumber = new String[numPhones]; 294 mServiceState = new ServiceState[numPhones]; 295 mSignalStrength = new SignalStrength[numPhones]; 296 mMessageWaiting = new boolean[numPhones]; 297 mDataConnectionPossible = new boolean[numPhones]; 298 mDataConnectionReason = new String[numPhones]; 299 mDataConnectionApn = new String[numPhones]; 300 mCallForwarding = new boolean[numPhones]; 301 mCellLocation = new Bundle[numPhones]; 302 mDataConnectionLinkProperties = new LinkProperties[numPhones]; 303 mDataConnectionNetworkCapabilities = new NetworkCapabilities[numPhones]; 304 mCellInfo = new ArrayList<List<CellInfo>>(); 305 for (int i = 0; i < numPhones; i++) { 306 mCallState[i] = TelephonyManager.CALL_STATE_IDLE; 307 mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE; 308 mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN; 309 mCallIncomingNumber[i] = ""; 310 mServiceState[i] = new ServiceState(); 311 mSignalStrength[i] = new SignalStrength(); 312 mMessageWaiting[i] = false; 313 mCallForwarding[i] = false; 314 mDataConnectionPossible[i] = false; 315 mDataConnectionReason[i] = ""; 316 mDataConnectionApn[i] = ""; 317 mCellLocation[i] = new Bundle(); 318 mCellInfo.add(i, null); 319 } 320 321 // Note that location can be null for non-phone builds like 322 // like the generic one. 323 if (location != null) { 324 for (int i = 0; i < numPhones; i++) { 325 location.fillInNotifierBundle(mCellLocation[i]); 326 } 327 } 328 mConnectedApns = new ArrayList<String>(); 329 } 330 331 public void systemRunning() { 332 // Watch for interesting updates 333 final IntentFilter filter = new IntentFilter(); 334 filter.addAction(Intent.ACTION_USER_SWITCHED); 335 filter.addAction(Intent.ACTION_USER_REMOVED); 336 filter.addAction(TelephonyIntents.ACTION_DEFAULT_SUBSCRIPTION_CHANGED); 337 log("systemRunning register for intents"); 338 mContext.registerReceiver(mBroadcastReceiver, filter); 339 } 340 341 @Override 342 public void registerSubscriptionListener(String pkgForDebug, ISubscriptionListener callback, 343 int events) { 344 int callerUid = UserHandle.getCallingUserId(); 345 int myUid = UserHandle.myUserId(); 346 if (VDBG) { 347 log("listen sl: E pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events) 348 + " myUid=" + myUid + " callerUid=" + callerUid + " callback=" + callback 349 + " callback.asBinder=" + callback.asBinder()); 350 } 351 352 if (events != 0) { 353 /* Checks permission and throws Security exception */ 354 checkSubscriptionListenerPermission(events); 355 Record r = null; 356 357 synchronized (mRecords) { 358 // register 359 find_and_add: { 360 IBinder b = callback.asBinder(); 361 final int N = mRecords.size(); 362 for (int i = 0; i < N; i++) { 363 r = mRecords.get(i); 364 if (b == r.binder) { 365 break find_and_add; 366 } 367 } 368 r = new Record(); 369 r.binder = b; 370 mRecords.add(r); 371 if (DBG) log("listen sl: add new record"); 372 } 373 374 r.subscriptionListenerCallback = callback; 375 r.pkgForDebug = pkgForDebug; 376 r.callerUid = callerUid; 377 r.events = events; 378 if (DBG) { 379 log("listen sl: Register r=" + r); 380 } 381 } 382 383 // Always notify when a listen is established. 384 if (r.matchSubscriptionListenerEvent( 385 SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED)) { 386 try { 387 if (VDBG) log("listen sl: send to r=" + r); 388 r.subscriptionListenerCallback.onSubscriptionInfoChanged(); 389 if (VDBG) log("listen sl: sent to r=" + r); 390 } catch (RemoteException e) { 391 if (VDBG) log("listen sl: remote exception sending to r=" + r + " e=" + e); 392 remove(r.binder); 393 } 394 } 395 } else { 396 if (DBG) log("listen sl: Unregister as event is LISTEN_NONE"); 397 unregisterSubscriptionListener(pkgForDebug, callback); 398 } 399 } 400 401 @Override 402 public void unregisterSubscriptionListener(String pkgForDebug, ISubscriptionListener callback) { 403 if (DBG) log("listen sl: Unregister as event is LISTEN_NONE"); 404 remove(callback.asBinder()); 405 } 406 407 private void checkSubscriptionListenerPermission(int events) { 408 if ((events & SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED) != 0) { 409 mContext.enforceCallingOrSelfPermission( 410 SubscriptionListener.PERMISSION_LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED, null); 411 } 412 } 413 414 @Override 415 public void notifySubscriptionInfoChanged() { 416 if (VDBG) log("notifySubscriptionInfoChanged:"); 417 synchronized (mRecords) { 418 mRemoveList.clear(); 419 for (Record r : mRecords) { 420 if (r.matchSubscriptionListenerEvent( 421 SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED)) { 422 try { 423 if (VDBG) log("notifySubscriptionInfoChanged: send to r=" + r); 424 r.subscriptionListenerCallback.onSubscriptionInfoChanged(); 425 if (VDBG) log("notifySubscriptionInfoChanged: sent to r=" + r); 426 } catch (RemoteException ex) { 427 if (VDBG) log("notifySubscriptionInfoChanged: RemoteException r=" + r); 428 mRemoveList.add(r.binder); 429 } 430 } 431 } 432 handleRemoveListLocked(); 433 } 434 } 435 436 @Override 437 public void listen(String pkgForDebug, IPhoneStateListener callback, int events, 438 boolean notifyNow) { 439 listenForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, pkgForDebug, callback, events, 440 notifyNow); 441 } 442 443 @Override 444 public void listenForSubscriber(int subId, String pkgForDebug, IPhoneStateListener callback, 445 int events, boolean notifyNow) { 446 listen(pkgForDebug, callback, events, notifyNow, subId); 447 } 448 449 private void listen(String pkgForDebug, IPhoneStateListener callback, int events, 450 boolean notifyNow, int subId) { 451 int callerUid = UserHandle.getCallingUserId(); 452 int myUid = UserHandle.myUserId(); 453 if (VDBG) { 454 log("listen: E pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events) 455 + " notifyNow=" + notifyNow + " subId=" + subId + " myUid=" + myUid 456 + " callerUid=" + callerUid); 457 } 458 459 if (events != PhoneStateListener.LISTEN_NONE) { 460 /* Checks permission and throws Security exception */ 461 checkListenerPermission(events); 462 synchronized (mRecords) { 463 // register 464 Record r = null; 465 find_and_add: { 466 IBinder b = callback.asBinder(); 467 final int N = mRecords.size(); 468 for (int i = 0; i < N; i++) { 469 r = mRecords.get(i); 470 if (b == r.binder) { 471 break find_and_add; 472 } 473 } 474 r = new Record(); 475 r.binder = b; 476 mRecords.add(r); 477 if (DBG) log("listen: add new record"); 478 } 479 480 r.callback = callback; 481 r.pkgForDebug = pkgForDebug; 482 r.callerUid = callerUid; 483 // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID, 484 // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID 485 if (!SubscriptionManager.isValidSubId(subId)) { 486 r.subId = SubscriptionManager.DEFAULT_SUB_ID; 487 } else {//APP specify subID 488 r.subId = subId; 489 } 490 r.phoneId = SubscriptionManager.getPhoneId(r.subId); 491 492 int phoneId = r.phoneId; 493 r.events = events; 494 if (DBG) { 495 log("listen: Register r=" + r + " r.subId=" + r.subId + " phoneId=" + phoneId); 496 } 497 if (VDBG) toStringLogSSC("listen"); 498 if (notifyNow && validatePhoneId(phoneId)) { 499 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { 500 try { 501 if (VDBG) log("listen: call onSSC state=" + mServiceState[phoneId]); 502 r.callback.onServiceStateChanged( 503 new ServiceState(mServiceState[phoneId])); 504 } catch (RemoteException ex) { 505 remove(r.binder); 506 } 507 } 508 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { 509 try { 510 int gsmSignalStrength = mSignalStrength[phoneId] 511 .getGsmSignalStrength(); 512 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 513 : gsmSignalStrength)); 514 } catch (RemoteException ex) { 515 remove(r.binder); 516 } 517 } 518 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { 519 try { 520 r.callback.onMessageWaitingIndicatorChanged( 521 mMessageWaiting[phoneId]); 522 } catch (RemoteException ex) { 523 remove(r.binder); 524 } 525 } 526 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { 527 try { 528 r.callback.onCallForwardingIndicatorChanged( 529 mCallForwarding[phoneId]); 530 } catch (RemoteException ex) { 531 remove(r.binder); 532 } 533 } 534 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { 535 try { 536 if (DBG_LOC) log("listen: mCellLocation = " 537 + mCellLocation[phoneId]); 538 r.callback.onCellLocationChanged( 539 new Bundle(mCellLocation[phoneId])); 540 } catch (RemoteException ex) { 541 remove(r.binder); 542 } 543 } 544 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) { 545 try { 546 r.callback.onCallStateChanged(mCallState[phoneId], 547 mCallIncomingNumber[phoneId]); 548 } catch (RemoteException ex) { 549 remove(r.binder); 550 } 551 } 552 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { 553 try { 554 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], 555 mDataConnectionNetworkType[phoneId]); 556 } catch (RemoteException ex) { 557 remove(r.binder); 558 } 559 } 560 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) { 561 try { 562 r.callback.onDataActivity(mDataActivity[phoneId]); 563 } catch (RemoteException ex) { 564 remove(r.binder); 565 } 566 } 567 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { 568 try { 569 r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]); 570 } catch (RemoteException ex) { 571 remove(r.binder); 572 } 573 } 574 if ((events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) { 575 try { 576 r.callback.onOtaspChanged(mOtaspMode); 577 } catch (RemoteException ex) { 578 remove(r.binder); 579 } 580 } 581 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) { 582 try { 583 if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = " 584 + mCellInfo.get(phoneId)); 585 r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); 586 } catch (RemoteException ex) { 587 remove(r.binder); 588 } 589 } 590 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO) != 0) { 591 try { 592 r.callback.onDataConnectionRealTimeInfoChanged(mDcRtInfo); 593 } catch (RemoteException ex) { 594 remove(r.binder); 595 } 596 } 597 if ((events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) { 598 try { 599 r.callback.onPreciseCallStateChanged(mPreciseCallState); 600 } catch (RemoteException ex) { 601 remove(r.binder); 602 } 603 } 604 if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { 605 try { 606 r.callback.onPreciseDataConnectionStateChanged( 607 mPreciseDataConnectionState); 608 } catch (RemoteException ex) { 609 remove(r.binder); 610 } 611 } 612 } 613 } 614 } else { 615 if(DBG) log("listen: Unregister"); 616 remove(callback.asBinder()); 617 } 618 } 619 620 private void remove(IBinder binder) { 621 synchronized (mRecords) { 622 final int recordCount = mRecords.size(); 623 for (int i = 0; i < recordCount; i++) { 624 if (mRecords.get(i).binder == binder) { 625 if (VDBG) log("remove: binder=" + binder); 626 mRecords.remove(i); 627 return; 628 } 629 } 630 } 631 } 632 633 public void notifyCallState(int state, String incomingNumber) { 634 if (!checkNotifyPermission("notifyCallState()")) { 635 return; 636 } 637 638 if (VDBG) { 639 log("notifyCallState: state=" + state + " incomingNumber=" + incomingNumber); 640 } 641 642 synchronized (mRecords) { 643 for (Record r : mRecords) { 644 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) && 645 (r.subId == SubscriptionManager.DEFAULT_SUB_ID)) { 646 try { 647 r.callback.onCallStateChanged(state, incomingNumber); 648 } catch (RemoteException ex) { 649 mRemoveList.add(r.binder); 650 } 651 } 652 } 653 handleRemoveListLocked(); 654 } 655 broadcastCallStateChanged(state, incomingNumber, SubscriptionManager.DEFAULT_SUB_ID); 656 } 657 658 public void notifyCallStateForSubscriber(int subId, int state, String incomingNumber) { 659 if (!checkNotifyPermission("notifyCallState()")) { 660 return; 661 } 662 if (VDBG) { 663 log("notifyCallStateForSubscriber: subId=" + subId 664 + " state=" + state + " incomingNumber=" + incomingNumber); 665 } 666 synchronized (mRecords) { 667 int phoneId = SubscriptionManager.getPhoneId(subId); 668 if (validatePhoneId(phoneId)) { 669 mCallState[phoneId] = state; 670 mCallIncomingNumber[phoneId] = incomingNumber; 671 for (Record r : mRecords) { 672 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) && 673 (r.subId == subId) && 674 (r.subId != SubscriptionManager.DEFAULT_SUB_ID)) { 675 try { 676 r.callback.onCallStateChanged(state, incomingNumber); 677 } catch (RemoteException ex) { 678 mRemoveList.add(r.binder); 679 } 680 } 681 } 682 } 683 handleRemoveListLocked(); 684 } 685 broadcastCallStateChanged(state, incomingNumber, subId); 686 } 687 688 public void notifyServiceStateForPhoneId(int phoneId, int subId, ServiceState state) { 689 if (!checkNotifyPermission("notifyServiceState()")){ 690 return; 691 } 692 693 synchronized (mRecords) { 694 if (VDBG) { 695 log("notifyServiceStateForSubscriber: subId=" + subId + " phoneId=" + phoneId 696 + " state=" + state); 697 } 698 if (validatePhoneId(phoneId)) { 699 mServiceState[phoneId] = state; 700 logServiceStateChanged("notifyServiceStateForSubscriber", subId, phoneId, state); 701 if (VDBG) toStringLogSSC("notifyServiceStateForSubscriber"); 702 703 for (Record r : mRecords) { 704 if (VDBG) { 705 log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId 706 + " phoneId=" + phoneId + " state=" + state); 707 } 708 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SERVICE_STATE) && 709 idMatch(r.subId, subId, phoneId)) { 710 try { 711 if (DBG) { 712 log("notifyServiceStateForSubscriber: callback.onSSC r=" + r 713 + " subId=" + subId + " phoneId=" + phoneId 714 + " state=" + state); 715 } 716 r.callback.onServiceStateChanged(new ServiceState(state)); 717 } catch (RemoteException ex) { 718 mRemoveList.add(r.binder); 719 } 720 } 721 } 722 } else { 723 log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId); 724 } 725 handleRemoveListLocked(); 726 } 727 broadcastServiceStateChanged(state, subId); 728 } 729 730 public void notifySignalStrength(SignalStrength signalStrength) { 731 notifySignalStrengthForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, signalStrength); 732 } 733 734 public void notifySignalStrengthForSubscriber(int subId, SignalStrength signalStrength) { 735 if (!checkNotifyPermission("notifySignalStrength()")) { 736 return; 737 } 738 if (VDBG) { 739 log("notifySignalStrengthForSubscriber: subId=" + subId 740 + " signalStrength=" + signalStrength); 741 toStringLogSSC("notifySignalStrengthForSubscriber"); 742 } 743 synchronized (mRecords) { 744 int phoneId = SubscriptionManager.getPhoneId(subId); 745 if (validatePhoneId(phoneId)) { 746 if (VDBG) log("notifySignalStrengthForSubscriber: valid phoneId=" + phoneId); 747 mSignalStrength[phoneId] = signalStrength; 748 for (Record r : mRecords) { 749 if (VDBG) { 750 log("notifySignalStrengthForSubscriber: r=" + r + " subId=" + subId 751 + " phoneId=" + phoneId + " ss=" + signalStrength); 752 } 753 if (r.matchPhoneStateListenerEvent( 754 PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) && 755 idMatch(r.subId, subId, phoneId)) { 756 try { 757 if (DBG) { 758 log("notifySignalStrengthForSubscriber: callback.onSsS r=" + r 759 + " subId=" + subId + " phoneId=" + phoneId 760 + " ss=" + signalStrength); 761 } 762 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); 763 } catch (RemoteException ex) { 764 mRemoveList.add(r.binder); 765 } 766 } 767 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTH) && 768 idMatch(r.subId, subId, phoneId)){ 769 try { 770 int gsmSignalStrength = signalStrength.getGsmSignalStrength(); 771 int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); 772 if (DBG) { 773 log("notifySignalStrengthForSubscriber: callback.onSS r=" + r 774 + " subId=" + subId + " phoneId=" + phoneId 775 + " gsmSS=" + gsmSignalStrength + " ss=" + ss); 776 } 777 r.callback.onSignalStrengthChanged(ss); 778 } catch (RemoteException ex) { 779 mRemoveList.add(r.binder); 780 } 781 } 782 } 783 } else { 784 log("notifySignalStrengthForSubscriber: invalid phoneId=" + phoneId); 785 } 786 handleRemoveListLocked(); 787 } 788 broadcastSignalStrengthChanged(signalStrength, subId); 789 } 790 791 public void notifyCellInfo(List<CellInfo> cellInfo) { 792 notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cellInfo); 793 } 794 795 public void notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo) { 796 if (!checkNotifyPermission("notifyCellInfo()")) { 797 return; 798 } 799 if (VDBG) { 800 log("notifyCellInfoForSubscriber: subId=" + subId 801 + " cellInfo=" + cellInfo); 802 } 803 804 synchronized (mRecords) { 805 int phoneId = SubscriptionManager.getPhoneId(subId); 806 if (validatePhoneId(phoneId)) { 807 mCellInfo.set(phoneId, cellInfo); 808 for (Record r : mRecords) { 809 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) && 810 idMatch(r.subId, subId, phoneId)) { 811 try { 812 if (DBG_LOC) { 813 log("notifyCellInfo: mCellInfo=" + cellInfo + " r=" + r); 814 } 815 r.callback.onCellInfoChanged(cellInfo); 816 } catch (RemoteException ex) { 817 mRemoveList.add(r.binder); 818 } 819 } 820 } 821 } 822 handleRemoveListLocked(); 823 } 824 } 825 826 public void notifyDataConnectionRealTimeInfo(DataConnectionRealTimeInfo dcRtInfo) { 827 if (!checkNotifyPermission("notifyDataConnectionRealTimeInfo()")) { 828 return; 829 } 830 831 synchronized (mRecords) { 832 mDcRtInfo = dcRtInfo; 833 for (Record r : mRecords) { 834 if (validateEventsAndUserLocked(r, 835 PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO)) { 836 try { 837 if (DBG_LOC) { 838 log("notifyDataConnectionRealTimeInfo: mDcRtInfo=" 839 + mDcRtInfo + " r=" + r); 840 } 841 r.callback.onDataConnectionRealTimeInfoChanged(mDcRtInfo); 842 } catch (RemoteException ex) { 843 mRemoveList.add(r.binder); 844 } 845 } 846 } 847 handleRemoveListLocked(); 848 } 849 } 850 851 @Override 852 public void notifyMessageWaitingChangedForPhoneId(int phoneId, int subId, boolean mwi) { 853 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) { 854 return; 855 } 856 if (VDBG) { 857 log("notifyMessageWaitingChangedForSubscriberPhoneID: subId=" + phoneId 858 + " mwi=" + mwi); 859 } 860 synchronized (mRecords) { 861 if (validatePhoneId(phoneId)) { 862 mMessageWaiting[phoneId] = mwi; 863 for (Record r : mRecords) { 864 if (r.matchPhoneStateListenerEvent( 865 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) && 866 idMatch(r.subId, subId, phoneId)) { 867 try { 868 r.callback.onMessageWaitingIndicatorChanged(mwi); 869 } catch (RemoteException ex) { 870 mRemoveList.add(r.binder); 871 } 872 } 873 } 874 } 875 handleRemoveListLocked(); 876 } 877 } 878 879 public void notifyCallForwardingChanged(boolean cfi) { 880 notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cfi); 881 } 882 883 public void notifyCallForwardingChangedForSubscriber(int subId, boolean cfi) { 884 if (!checkNotifyPermission("notifyCallForwardingChanged()")) { 885 return; 886 } 887 if (VDBG) { 888 log("notifyCallForwardingChangedForSubscriber: subId=" + subId 889 + " cfi=" + cfi); 890 } 891 synchronized (mRecords) { 892 int phoneId = SubscriptionManager.getPhoneId(subId); 893 if (validatePhoneId(phoneId)) { 894 mCallForwarding[phoneId] = cfi; 895 for (Record r : mRecords) { 896 if (r.matchPhoneStateListenerEvent( 897 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) && 898 idMatch(r.subId, subId, phoneId)) { 899 try { 900 r.callback.onCallForwardingIndicatorChanged(cfi); 901 } catch (RemoteException ex) { 902 mRemoveList.add(r.binder); 903 } 904 } 905 } 906 } 907 handleRemoveListLocked(); 908 } 909 } 910 911 public void notifyDataActivity(int state) { 912 notifyDataActivityForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, state); 913 } 914 915 public void notifyDataActivityForSubscriber(int subId, int state) { 916 if (!checkNotifyPermission("notifyDataActivity()" )) { 917 return; 918 } 919 synchronized (mRecords) { 920 int phoneId = SubscriptionManager.getPhoneId(subId); 921 mDataActivity[phoneId] = state; 922 for (Record r : mRecords) { 923 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_DATA_ACTIVITY)) { 924 try { 925 r.callback.onDataActivity(state); 926 } catch (RemoteException ex) { 927 mRemoveList.add(r.binder); 928 } 929 } 930 } 931 handleRemoveListLocked(); 932 } 933 } 934 935 public void notifyDataConnection(int state, boolean isDataConnectivityPossible, 936 String reason, String apn, String apnType, LinkProperties linkProperties, 937 NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { 938 notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, state, 939 isDataConnectivityPossible,reason, apn, apnType, linkProperties, 940 networkCapabilities, networkType, roaming); 941 } 942 943 public void notifyDataConnectionForSubscriber(int subId, int state, 944 boolean isDataConnectivityPossible, String reason, String apn, String apnType, 945 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 946 int networkType, boolean roaming) { 947 if (!checkNotifyPermission("notifyDataConnection()" )) { 948 return; 949 } 950 if (VDBG) { 951 log("notifyDataConnectionForSubscriber: subId=" + subId 952 + " state=" + state + " isDataConnectivityPossible=" + isDataConnectivityPossible 953 + " reason='" + reason 954 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType 955 + " mRecords.size()=" + mRecords.size() + " mRecords=" + mRecords); 956 } 957 synchronized (mRecords) { 958 int phoneId = SubscriptionManager.getPhoneId(subId); 959 boolean modified = false; 960 if (state == TelephonyManager.DATA_CONNECTED) { 961 if (!mConnectedApns.contains(apnType)) { 962 mConnectedApns.add(apnType); 963 if (mDataConnectionState[phoneId] != state) { 964 mDataConnectionState[phoneId] = state; 965 modified = true; 966 } 967 } 968 } else { 969 if (mConnectedApns.remove(apnType)) { 970 if (mConnectedApns.isEmpty()) { 971 mDataConnectionState[phoneId] = state; 972 modified = true; 973 } else { 974 // leave mDataConnectionState as is and 975 // send out the new status for the APN in question. 976 } 977 } 978 } 979 mDataConnectionPossible[phoneId] = isDataConnectivityPossible; 980 mDataConnectionReason[phoneId] = reason; 981 mDataConnectionLinkProperties[phoneId] = linkProperties; 982 mDataConnectionNetworkCapabilities[phoneId] = networkCapabilities; 983 if (mDataConnectionNetworkType[phoneId] != networkType) { 984 mDataConnectionNetworkType[phoneId] = networkType; 985 // need to tell registered listeners about the new network type 986 modified = true; 987 } 988 if (modified) { 989 if (DBG) { 990 log("onDataConnectionStateChanged(" + mDataConnectionState[phoneId] 991 + ", " + mDataConnectionNetworkType[phoneId] + ")"); 992 } 993 for (Record r : mRecords) { 994 if (r.matchPhoneStateListenerEvent( 995 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) && 996 idMatch(r.subId, subId, phoneId)) { 997 try { 998 log("Notify data connection state changed on sub: " + 999 subId); 1000 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], 1001 mDataConnectionNetworkType[phoneId]); 1002 } catch (RemoteException ex) { 1003 mRemoveList.add(r.binder); 1004 } 1005 } 1006 } 1007 handleRemoveListLocked(); 1008 } 1009 mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType, 1010 apnType, apn, reason, linkProperties, ""); 1011 for (Record r : mRecords) { 1012 if (r.matchPhoneStateListenerEvent( 1013 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { 1014 try { 1015 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 1016 } catch (RemoteException ex) { 1017 mRemoveList.add(r.binder); 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_SUB_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_SUB_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_SUB_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, String failCause) { 1403 Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED); 1404 intent.putExtra(PhoneConstants.STATE_KEY, state); 1405 intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType); 1406 if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); 1407 if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1408 if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); 1409 if (linkProperties != null) intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties); 1410 if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause); 1411 1412 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1413 android.Manifest.permission.READ_PRECISE_PHONE_STATE); 1414 } 1415 1416 private boolean checkNotifyPermission(String method) { 1417 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) 1418 == PackageManager.PERMISSION_GRANTED) { 1419 return true; 1420 } 1421 String msg = "Modify Phone State Permission Denial: " + method + " from pid=" 1422 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid(); 1423 if (DBG) log(msg); 1424 return false; 1425 } 1426 1427 private void checkListenerPermission(int events) { 1428 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { 1429 mContext.enforceCallingOrSelfPermission( 1430 android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 1431 1432 } 1433 1434 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) { 1435 mContext.enforceCallingOrSelfPermission( 1436 android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 1437 1438 } 1439 1440 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) { 1441 mContext.enforceCallingOrSelfPermission( 1442 android.Manifest.permission.READ_PHONE_STATE, null); 1443 } 1444 1445 if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) { 1446 mContext.enforceCallingOrSelfPermission( 1447 android.Manifest.permission.READ_PRECISE_PHONE_STATE, null); 1448 1449 } 1450 1451 if ((events & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) { 1452 mContext.enforceCallingOrSelfPermission( 1453 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); 1454 } 1455 } 1456 1457 private void handleRemoveListLocked() { 1458 int size = mRemoveList.size(); 1459 if (VDBG) log("handleRemoveListLocked: mRemoveList.size()=" + size); 1460 if (size > 0) { 1461 for (IBinder b: mRemoveList) { 1462 remove(b); 1463 } 1464 mRemoveList.clear(); 1465 } 1466 } 1467 1468 private boolean validateEventsAndUserLocked(Record r, int events) { 1469 int foregroundUser; 1470 long callingIdentity = Binder.clearCallingIdentity(); 1471 boolean valid = false; 1472 try { 1473 foregroundUser = ActivityManager.getCurrentUser(); 1474 valid = r.callerUid == foregroundUser && r.matchPhoneStateListenerEvent(events); 1475 if (DBG | DBG_LOC) { 1476 log("validateEventsAndUserLocked: valid=" + valid 1477 + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser 1478 + " r.events=" + r.events + " events=" + events); 1479 } 1480 } finally { 1481 Binder.restoreCallingIdentity(callingIdentity); 1482 } 1483 return valid; 1484 } 1485 1486 private boolean validatePhoneId(int phoneId) { 1487 boolean valid = (phoneId >= 0) && (phoneId < mNumPhones); 1488 if (VDBG) log("validatePhoneId: " + valid); 1489 return valid; 1490 } 1491 1492 private static void log(String s) { 1493 Rlog.d(TAG, s); 1494 } 1495 1496 private static class LogSSC { 1497 private Time mTime; 1498 private String mS; 1499 private int mSubId; 1500 private int mPhoneId; 1501 private ServiceState mState; 1502 1503 public void set(Time t, String s, int subId, int phoneId, ServiceState state) { 1504 mTime = t; mS = s; mSubId = subId; mPhoneId = phoneId; mState = state; 1505 } 1506 1507 @Override 1508 public String toString() { 1509 return mS + " Time " + mTime.toString() + " mSubId " + mSubId + " mPhoneId " + mPhoneId + " mState " + mState; 1510 } 1511 } 1512 1513 private LogSSC logSSC [] = new LogSSC[10]; 1514 private int next = 0; 1515 1516 private void logServiceStateChanged(String s, int subId, int phoneId, ServiceState state) { 1517 if (logSSC == null || logSSC.length == 0) { 1518 return; 1519 } 1520 if (logSSC[next] == null) { 1521 logSSC[next] = new LogSSC(); 1522 } 1523 Time t = new Time(); 1524 t.setToNow(); 1525 logSSC[next].set(t, s, subId, phoneId, state); 1526 if (++next >= logSSC.length) { 1527 next = 0; 1528 } 1529 } 1530 1531 private void toStringLogSSC(String prompt) { 1532 if (logSSC == null || logSSC.length == 0 || (next == 0 && logSSC[next] == null)) { 1533 log(prompt + ": logSSC is empty"); 1534 } else { 1535 // There is at least one element 1536 log(prompt + ": logSSC.length=" + logSSC.length + " next=" + next); 1537 int i = next; 1538 if (logSSC[i] == null) { 1539 // logSSC is not full so back to the beginning 1540 i = 0; 1541 } 1542 do { 1543 log(logSSC[i].toString()); 1544 if (++i >= logSSC.length) { 1545 i = 0; 1546 } 1547 } while (i != next); 1548 log(prompt + ": ----------------"); 1549 } 1550 } 1551 1552 boolean idMatch(int rSubId, int subId, int phoneId) { 1553 if(rSubId == SubscriptionManager.DEFAULT_SUB_ID) { 1554 if(subId < 0) { 1555 // Invalid case, we need compare phoneId with default one. 1556 return (mDefaultPhoneId == phoneId); 1557 } 1558 return (subId == mDefaultSubId); 1559 } else { 1560 return (rSubId == subId); 1561 } 1562 } 1563 1564 private void checkPossibleMissNotify(Record r, int phoneId) { 1565 int events = r.events; 1566 1567 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { 1568 try { 1569 if (VDBG) log("checkPossibleMissNotify: onServiceStateChanged state=" + 1570 mServiceState[phoneId]); 1571 r.callback.onServiceStateChanged( 1572 new ServiceState(mServiceState[phoneId])); 1573 } catch (RemoteException ex) { 1574 mRemoveList.add(r.binder); 1575 } 1576 } 1577 1578 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { 1579 try { 1580 SignalStrength signalStrength = mSignalStrength[phoneId]; 1581 if (DBG) { 1582 log("checkPossibleMissNotify: onSignalStrengthsChanged SS=" + signalStrength); 1583 } 1584 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); 1585 } catch (RemoteException ex) { 1586 mRemoveList.add(r.binder); 1587 } 1588 } 1589 1590 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { 1591 try { 1592 int gsmSignalStrength = mSignalStrength[phoneId] 1593 .getGsmSignalStrength(); 1594 if (DBG) { 1595 log("checkPossibleMissNotify: onSignalStrengthChanged SS=" + 1596 gsmSignalStrength); 1597 } 1598 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 1599 : gsmSignalStrength)); 1600 } catch (RemoteException ex) { 1601 mRemoveList.add(r.binder); 1602 } 1603 } 1604 1605 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) { 1606 try { 1607 if (DBG_LOC) { 1608 log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = " 1609 + mCellInfo.get(phoneId)); 1610 } 1611 r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); 1612 } catch (RemoteException ex) { 1613 mRemoveList.add(r.binder); 1614 } 1615 } 1616 1617 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { 1618 try { 1619 if (VDBG) { 1620 log("checkPossibleMissNotify: onMessageWaitingIndicatorChanged phoneId=" 1621 + phoneId + " mwi=" + mMessageWaiting[phoneId]); 1622 } 1623 r.callback.onMessageWaitingIndicatorChanged( 1624 mMessageWaiting[phoneId]); 1625 } catch (RemoteException ex) { 1626 mRemoveList.add(r.binder); 1627 } 1628 } 1629 1630 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { 1631 try { 1632 if (VDBG) { 1633 log("checkPossibleMissNotify: onCallForwardingIndicatorChanged phoneId=" 1634 + phoneId + " cfi=" + mCallForwarding[phoneId]); 1635 } 1636 r.callback.onCallForwardingIndicatorChanged( 1637 mCallForwarding[phoneId]); 1638 } catch (RemoteException ex) { 1639 mRemoveList.add(r.binder); 1640 } 1641 } 1642 1643 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { 1644 try { 1645 if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = " 1646 + mCellLocation[phoneId]); 1647 r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId])); 1648 } catch (RemoteException ex) { 1649 mRemoveList.add(r.binder); 1650 } 1651 } 1652 1653 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { 1654 try { 1655 if (DBG) { 1656 log("checkPossibleMissNotify: onDataConnectionStateChanged(mDataConnectionState" 1657 + "=" + mDataConnectionState[phoneId] 1658 + ", mDataConnectionNetworkType=" + mDataConnectionNetworkType[phoneId] 1659 + ")"); 1660 } 1661 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], 1662 mDataConnectionNetworkType[phoneId]); 1663 } catch (RemoteException ex) { 1664 mRemoveList.add(r.binder); 1665 } 1666 } 1667 } 1668} 1669