TelephonyRegistry.java revision a54bf6583380cf328b9858d942b4c387c6163f0f
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 if (!hasNotifySubscriptionInfoChangedOccurred) { 413 log("notifySubscriptionInfoChanged: first invocation mRecords.size=" 414 + mRecords.size()); 415 } 416 hasNotifySubscriptionInfoChangedOccurred = true; 417 mRemoveList.clear(); 418 for (Record r : mRecords) { 419 if (r.matchOnSubscriptionsChangedListener()) { 420 try { 421 if (VDBG) log("notifySubscriptionInfoChanged: call osc to r=" + r); 422 r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged(); 423 if (VDBG) log("notifySubscriptionInfoChanged: done osc to r=" + r); 424 } catch (RemoteException ex) { 425 if (VDBG) log("notifySubscriptionInfoChanged: RemoteException r=" + r); 426 mRemoveList.add(r.binder); 427 } 428 } 429 } 430 handleRemoveListLocked(); 431 } 432 } 433 434 @Override 435 public void listen(String pkgForDebug, IPhoneStateListener callback, int events, 436 boolean notifyNow) { 437 listenForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, pkgForDebug, callback, 438 events, notifyNow); 439 } 440 441 @Override 442 public void listenForSubscriber(int subId, String pkgForDebug, IPhoneStateListener callback, 443 int events, boolean notifyNow) { 444 listen(pkgForDebug, callback, events, notifyNow, subId); 445 } 446 447 private void listen(String pkgForDebug, IPhoneStateListener callback, int events, 448 boolean notifyNow, int subId) { 449 int callerUid = UserHandle.getCallingUserId(); 450 int myUid = UserHandle.myUserId(); 451 if (VDBG) { 452 log("listen: E pkg=" + pkgForDebug + " events=0x" + Integer.toHexString(events) 453 + " notifyNow=" + notifyNow + " subId=" + subId + " myUid=" + myUid 454 + " callerUid=" + callerUid); 455 } 456 457 if (events != PhoneStateListener.LISTEN_NONE) { 458 /* Checks permission and throws Security exception */ 459 checkListenerPermission(events); 460 synchronized (mRecords) { 461 // register 462 Record r = null; 463 find_and_add: { 464 IBinder b = callback.asBinder(); 465 final int N = mRecords.size(); 466 for (int i = 0; i < N; i++) { 467 r = mRecords.get(i); 468 if (b == r.binder) { 469 break find_and_add; 470 } 471 } 472 r = new Record(); 473 r.binder = b; 474 mRecords.add(r); 475 if (DBG) log("listen: add new record"); 476 } 477 478 r.callback = callback; 479 r.pkgForDebug = pkgForDebug; 480 r.callerUid = callerUid; 481 // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID, 482 // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID 483 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 484 r.subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; 485 } else {//APP specify subID 486 r.subId = subId; 487 } 488 r.phoneId = SubscriptionManager.getPhoneId(r.subId); 489 490 int phoneId = r.phoneId; 491 r.events = events; 492 if (DBG) { 493 log("listen: Register r=" + r + " r.subId=" + r.subId + " phoneId=" + phoneId); 494 } 495 if (VDBG) toStringLogSSC("listen"); 496 if (notifyNow && validatePhoneId(phoneId)) { 497 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { 498 try { 499 if (VDBG) log("listen: call onSSC state=" + mServiceState[phoneId]); 500 r.callback.onServiceStateChanged( 501 new ServiceState(mServiceState[phoneId])); 502 } catch (RemoteException ex) { 503 remove(r.binder); 504 } 505 } 506 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { 507 try { 508 int gsmSignalStrength = mSignalStrength[phoneId] 509 .getGsmSignalStrength(); 510 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 511 : gsmSignalStrength)); 512 } catch (RemoteException ex) { 513 remove(r.binder); 514 } 515 } 516 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { 517 try { 518 r.callback.onMessageWaitingIndicatorChanged( 519 mMessageWaiting[phoneId]); 520 } catch (RemoteException ex) { 521 remove(r.binder); 522 } 523 } 524 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { 525 try { 526 r.callback.onCallForwardingIndicatorChanged( 527 mCallForwarding[phoneId]); 528 } catch (RemoteException ex) { 529 remove(r.binder); 530 } 531 } 532 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { 533 try { 534 if (DBG_LOC) log("listen: mCellLocation = " 535 + mCellLocation[phoneId]); 536 r.callback.onCellLocationChanged( 537 new Bundle(mCellLocation[phoneId])); 538 } catch (RemoteException ex) { 539 remove(r.binder); 540 } 541 } 542 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) { 543 try { 544 r.callback.onCallStateChanged(mCallState[phoneId], 545 mCallIncomingNumber[phoneId]); 546 } catch (RemoteException ex) { 547 remove(r.binder); 548 } 549 } 550 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { 551 try { 552 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], 553 mDataConnectionNetworkType[phoneId]); 554 } catch (RemoteException ex) { 555 remove(r.binder); 556 } 557 } 558 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) { 559 try { 560 r.callback.onDataActivity(mDataActivity[phoneId]); 561 } catch (RemoteException ex) { 562 remove(r.binder); 563 } 564 } 565 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { 566 try { 567 r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]); 568 } catch (RemoteException ex) { 569 remove(r.binder); 570 } 571 } 572 if ((events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) { 573 try { 574 r.callback.onOtaspChanged(mOtaspMode); 575 } catch (RemoteException ex) { 576 remove(r.binder); 577 } 578 } 579 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) { 580 try { 581 if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = " 582 + mCellInfo.get(phoneId)); 583 r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); 584 } catch (RemoteException ex) { 585 remove(r.binder); 586 } 587 } 588 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO) != 0) { 589 try { 590 r.callback.onDataConnectionRealTimeInfoChanged(mDcRtInfo); 591 } catch (RemoteException ex) { 592 remove(r.binder); 593 } 594 } 595 if ((events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) { 596 try { 597 r.callback.onPreciseCallStateChanged(mPreciseCallState); 598 } catch (RemoteException ex) { 599 remove(r.binder); 600 } 601 } 602 if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { 603 try { 604 r.callback.onPreciseDataConnectionStateChanged( 605 mPreciseDataConnectionState); 606 } catch (RemoteException ex) { 607 remove(r.binder); 608 } 609 } 610 } 611 } 612 } else { 613 if(DBG) log("listen: Unregister"); 614 remove(callback.asBinder()); 615 } 616 } 617 618 private void remove(IBinder binder) { 619 synchronized (mRecords) { 620 final int recordCount = mRecords.size(); 621 for (int i = 0; i < recordCount; i++) { 622 if (mRecords.get(i).binder == binder) { 623 if (VDBG) log("remove: binder=" + binder); 624 mRecords.remove(i); 625 return; 626 } 627 } 628 } 629 } 630 631 public void notifyCallState(int state, String incomingNumber) { 632 if (!checkNotifyPermission("notifyCallState()")) { 633 return; 634 } 635 636 if (VDBG) { 637 log("notifyCallState: state=" + state + " incomingNumber=" + incomingNumber); 638 } 639 640 synchronized (mRecords) { 641 for (Record r : mRecords) { 642 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) && 643 (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { 644 try { 645 r.callback.onCallStateChanged(state, incomingNumber); 646 } catch (RemoteException ex) { 647 mRemoveList.add(r.binder); 648 } 649 } 650 } 651 handleRemoveListLocked(); 652 } 653 broadcastCallStateChanged(state, incomingNumber, 654 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); 655 } 656 657 public void notifyCallStateForSubscriber(int subId, int state, String incomingNumber) { 658 if (!checkNotifyPermission("notifyCallState()")) { 659 return; 660 } 661 if (VDBG) { 662 log("notifyCallStateForSubscriber: subId=" + subId 663 + " state=" + state + " incomingNumber=" + incomingNumber); 664 } 665 synchronized (mRecords) { 666 int phoneId = SubscriptionManager.getPhoneId(subId); 667 if (validatePhoneId(phoneId)) { 668 mCallState[phoneId] = state; 669 mCallIncomingNumber[phoneId] = incomingNumber; 670 for (Record r : mRecords) { 671 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) && 672 (r.subId == subId) && 673 (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { 674 try { 675 r.callback.onCallStateChanged(state, incomingNumber); 676 } catch (RemoteException ex) { 677 mRemoveList.add(r.binder); 678 } 679 } 680 } 681 } 682 handleRemoveListLocked(); 683 } 684 broadcastCallStateChanged(state, incomingNumber, subId); 685 } 686 687 public void notifyServiceStateForPhoneId(int phoneId, int subId, ServiceState state) { 688 if (!checkNotifyPermission("notifyServiceState()")){ 689 return; 690 } 691 692 synchronized (mRecords) { 693 if (VDBG) { 694 log("notifyServiceStateForSubscriber: subId=" + subId + " phoneId=" + phoneId 695 + " state=" + state); 696 } 697 if (validatePhoneId(phoneId)) { 698 mServiceState[phoneId] = state; 699 logServiceStateChanged("notifyServiceStateForSubscriber", subId, phoneId, state); 700 if (VDBG) toStringLogSSC("notifyServiceStateForSubscriber"); 701 702 for (Record r : mRecords) { 703 if (VDBG) { 704 log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId 705 + " phoneId=" + phoneId + " state=" + state); 706 } 707 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SERVICE_STATE) && 708 idMatch(r.subId, subId, phoneId)) { 709 try { 710 if (DBG) { 711 log("notifyServiceStateForSubscriber: callback.onSSC r=" + r 712 + " subId=" + subId + " phoneId=" + phoneId 713 + " state=" + state); 714 } 715 r.callback.onServiceStateChanged(new ServiceState(state)); 716 } catch (RemoteException ex) { 717 mRemoveList.add(r.binder); 718 } 719 } 720 } 721 } else { 722 log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId); 723 } 724 handleRemoveListLocked(); 725 } 726 broadcastServiceStateChanged(state, subId); 727 } 728 729 public void notifySignalStrength(SignalStrength signalStrength) { 730 notifySignalStrengthForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, 731 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_SUBSCRIPTION_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_SUBSCRIPTION_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_SUBSCRIPTION_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 if (validatePhoneId(phoneId)) { 922 mDataActivity[phoneId] = state; 923 for (Record r : mRecords) { 924 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_DATA_ACTIVITY)) { 925 try { 926 r.callback.onDataActivity(state); 927 } catch (RemoteException ex) { 928 mRemoveList.add(r.binder); 929 } 930 } 931 } 932 } 933 handleRemoveListLocked(); 934 } 935 } 936 937 public void notifyDataConnection(int state, boolean isDataConnectivityPossible, 938 String reason, String apn, String apnType, LinkProperties linkProperties, 939 NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { 940 notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state, 941 isDataConnectivityPossible,reason, apn, apnType, linkProperties, 942 networkCapabilities, networkType, roaming); 943 } 944 945 public void notifyDataConnectionForSubscriber(int subId, int state, 946 boolean isDataConnectivityPossible, String reason, String apn, String apnType, 947 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 948 int networkType, boolean roaming) { 949 if (!checkNotifyPermission("notifyDataConnection()" )) { 950 return; 951 } 952 if (VDBG) { 953 log("notifyDataConnectionForSubscriber: subId=" + subId 954 + " state=" + state + " isDataConnectivityPossible=" + isDataConnectivityPossible 955 + " reason='" + reason 956 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType 957 + " mRecords.size()=" + mRecords.size() + " mRecords=" + mRecords); 958 } 959 synchronized (mRecords) { 960 int phoneId = SubscriptionManager.getPhoneId(subId); 961 if (validatePhoneId(phoneId)) { 962 boolean modified = false; 963 if (state == TelephonyManager.DATA_CONNECTED) { 964 if (!mConnectedApns.contains(apnType)) { 965 mConnectedApns.add(apnType); 966 if (mDataConnectionState[phoneId] != state) { 967 mDataConnectionState[phoneId] = state; 968 modified = true; 969 } 970 } 971 } else { 972 if (mConnectedApns.remove(apnType)) { 973 if (mConnectedApns.isEmpty()) { 974 mDataConnectionState[phoneId] = state; 975 modified = true; 976 } else { 977 // leave mDataConnectionState as is and 978 // send out the new status for the APN in question. 979 } 980 } 981 } 982 mDataConnectionPossible[phoneId] = isDataConnectivityPossible; 983 mDataConnectionReason[phoneId] = reason; 984 mDataConnectionLinkProperties[phoneId] = linkProperties; 985 mDataConnectionNetworkCapabilities[phoneId] = networkCapabilities; 986 if (mDataConnectionNetworkType[phoneId] != networkType) { 987 mDataConnectionNetworkType[phoneId] = networkType; 988 // need to tell registered listeners about the new network type 989 modified = true; 990 } 991 if (modified) { 992 if (DBG) { 993 log("onDataConnectionStateChanged(" + mDataConnectionState[phoneId] 994 + ", " + mDataConnectionNetworkType[phoneId] + ")"); 995 } 996 for (Record r : mRecords) { 997 if (r.matchPhoneStateListenerEvent( 998 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) && 999 idMatch(r.subId, subId, phoneId)) { 1000 try { 1001 log("Notify data connection state changed on sub: " + 1002 subId); 1003 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], 1004 mDataConnectionNetworkType[phoneId]); 1005 } catch (RemoteException ex) { 1006 mRemoveList.add(r.binder); 1007 } 1008 } 1009 } 1010 handleRemoveListLocked(); 1011 } 1012 mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType, 1013 apnType, apn, reason, linkProperties, ""); 1014 for (Record r : mRecords) { 1015 if (r.matchPhoneStateListenerEvent( 1016 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { 1017 try { 1018 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 1019 } catch (RemoteException ex) { 1020 mRemoveList.add(r.binder); 1021 } 1022 } 1023 } 1024 } 1025 handleRemoveListLocked(); 1026 } 1027 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn, 1028 apnType, linkProperties, networkCapabilities, roaming, subId); 1029 broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, reason, 1030 linkProperties, ""); 1031 } 1032 1033 public void notifyDataConnectionFailed(String reason, String apnType) { 1034 notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, 1035 reason, apnType); 1036 } 1037 1038 public void notifyDataConnectionFailedForSubscriber(int subId, 1039 String reason, String apnType) { 1040 if (!checkNotifyPermission("notifyDataConnectionFailed()")) { 1041 return; 1042 } 1043 if (VDBG) { 1044 log("notifyDataConnectionFailedForSubscriber: subId=" + subId 1045 + " reason=" + reason + " apnType=" + apnType); 1046 } 1047 synchronized (mRecords) { 1048 mPreciseDataConnectionState = new PreciseDataConnectionState( 1049 TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN, 1050 apnType, "", reason, null, ""); 1051 for (Record r : mRecords) { 1052 if (r.matchPhoneStateListenerEvent( 1053 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { 1054 try { 1055 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 1056 } catch (RemoteException ex) { 1057 mRemoveList.add(r.binder); 1058 } 1059 } 1060 } 1061 handleRemoveListLocked(); 1062 } 1063 broadcastDataConnectionFailed(reason, apnType, subId); 1064 broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN, 1065 TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", reason, null, ""); 1066 } 1067 1068 public void notifyCellLocation(Bundle cellLocation) { 1069 notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation); 1070 } 1071 1072 public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) { 1073 log("notifyCellLocationForSubscriber: subId=" + subId 1074 + " cellLocation=" + cellLocation); 1075 if (!checkNotifyPermission("notifyCellLocation()")) { 1076 return; 1077 } 1078 if (VDBG) { 1079 log("notifyCellLocationForSubscriber: subId=" + subId 1080 + " cellLocation=" + cellLocation); 1081 } 1082 synchronized (mRecords) { 1083 int phoneId = SubscriptionManager.getPhoneId(subId); 1084 if (validatePhoneId(phoneId)) { 1085 mCellLocation[phoneId] = cellLocation; 1086 for (Record r : mRecords) { 1087 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) && 1088 idMatch(r.subId, subId, phoneId)) { 1089 try { 1090 if (DBG_LOC) { 1091 log("notifyCellLocation: cellLocation=" + cellLocation 1092 + " r=" + r); 1093 } 1094 r.callback.onCellLocationChanged(new Bundle(cellLocation)); 1095 } catch (RemoteException ex) { 1096 mRemoveList.add(r.binder); 1097 } 1098 } 1099 } 1100 } 1101 handleRemoveListLocked(); 1102 } 1103 } 1104 1105 public void notifyOtaspChanged(int otaspMode) { 1106 if (!checkNotifyPermission("notifyOtaspChanged()" )) { 1107 return; 1108 } 1109 synchronized (mRecords) { 1110 mOtaspMode = otaspMode; 1111 for (Record r : mRecords) { 1112 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_OTASP_CHANGED)) { 1113 try { 1114 r.callback.onOtaspChanged(otaspMode); 1115 } catch (RemoteException ex) { 1116 mRemoveList.add(r.binder); 1117 } 1118 } 1119 } 1120 handleRemoveListLocked(); 1121 } 1122 } 1123 1124 public void notifyPreciseCallState(int ringingCallState, int foregroundCallState, 1125 int backgroundCallState) { 1126 if (!checkNotifyPermission("notifyPreciseCallState()")) { 1127 return; 1128 } 1129 synchronized (mRecords) { 1130 mRingingCallState = ringingCallState; 1131 mForegroundCallState = foregroundCallState; 1132 mBackgroundCallState = backgroundCallState; 1133 mPreciseCallState = new PreciseCallState(ringingCallState, foregroundCallState, 1134 backgroundCallState, 1135 DisconnectCause.NOT_VALID, 1136 PreciseDisconnectCause.NOT_VALID); 1137 for (Record r : mRecords) { 1138 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_PRECISE_CALL_STATE)) { 1139 try { 1140 r.callback.onPreciseCallStateChanged(mPreciseCallState); 1141 } catch (RemoteException ex) { 1142 mRemoveList.add(r.binder); 1143 } 1144 } 1145 } 1146 handleRemoveListLocked(); 1147 } 1148 broadcastPreciseCallStateChanged(ringingCallState, foregroundCallState, backgroundCallState, 1149 DisconnectCause.NOT_VALID, 1150 PreciseDisconnectCause.NOT_VALID); 1151 } 1152 1153 public void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause) { 1154 if (!checkNotifyPermission("notifyDisconnectCause()")) { 1155 return; 1156 } 1157 synchronized (mRecords) { 1158 mPreciseCallState = new PreciseCallState(mRingingCallState, mForegroundCallState, 1159 mBackgroundCallState, disconnectCause, preciseDisconnectCause); 1160 for (Record r : mRecords) { 1161 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_PRECISE_CALL_STATE)) { 1162 try { 1163 r.callback.onPreciseCallStateChanged(mPreciseCallState); 1164 } catch (RemoteException ex) { 1165 mRemoveList.add(r.binder); 1166 } 1167 } 1168 } 1169 handleRemoveListLocked(); 1170 } 1171 broadcastPreciseCallStateChanged(mRingingCallState, mForegroundCallState, 1172 mBackgroundCallState, disconnectCause, preciseDisconnectCause); 1173 } 1174 1175 public void notifyPreciseDataConnectionFailed(String reason, String apnType, 1176 String apn, String failCause) { 1177 if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) { 1178 return; 1179 } 1180 synchronized (mRecords) { 1181 mPreciseDataConnectionState = new PreciseDataConnectionState( 1182 TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN, 1183 apnType, apn, reason, null, failCause); 1184 for (Record r : mRecords) { 1185 if (r.matchPhoneStateListenerEvent( 1186 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { 1187 try { 1188 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 1189 } catch (RemoteException ex) { 1190 mRemoveList.add(r.binder); 1191 } 1192 } 1193 } 1194 handleRemoveListLocked(); 1195 } 1196 broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN, 1197 TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause); 1198 } 1199 1200 public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) { 1201 if (!checkNotifyPermission("notifyVoLteServiceStateChanged()")) { 1202 return; 1203 } 1204 synchronized (mRecords) { 1205 mVoLteServiceState = lteState; 1206 for (Record r : mRecords) { 1207 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_VOLTE_STATE)) { 1208 try { 1209 r.callback.onVoLteServiceStateChanged( 1210 new VoLteServiceState(mVoLteServiceState)); 1211 } catch (RemoteException ex) { 1212 mRemoveList.add(r.binder); 1213 } 1214 } 1215 } 1216 handleRemoveListLocked(); 1217 } 1218 } 1219 1220 public void notifyOemHookRawEventForSubscriber(int subId, byte[] rawData) { 1221 if (!checkNotifyPermission("notifyOemHookRawEventForSubscriber")) { 1222 return; 1223 } 1224 1225 synchronized (mRecords) { 1226 for (Record r : mRecords) { 1227 if (VDBG) { 1228 log("notifyOemHookRawEventForSubscriber: r=" + r + " subId=" + subId); 1229 } 1230 if ((r.matchPhoneStateListenerEvent( 1231 PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT)) && 1232 ((r.subId == subId) || 1233 (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID))) { 1234 try { 1235 r.callback.onOemHookRawEvent(rawData); 1236 } catch (RemoteException ex) { 1237 mRemoveList.add(r.binder); 1238 } 1239 } 1240 } 1241 handleRemoveListLocked(); 1242 } 1243 } 1244 1245 @Override 1246 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1247 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 1248 != PackageManager.PERMISSION_GRANTED) { 1249 pw.println("Permission Denial: can't dump telephony.registry from from pid=" 1250 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 1251 return; 1252 } 1253 synchronized (mRecords) { 1254 final int recordCount = mRecords.size(); 1255 pw.println("last known state:"); 1256 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 1257 pw.println(" Phone Id=" + i); 1258 pw.println(" mCallState=" + mCallState[i]); 1259 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber[i]); 1260 pw.println(" mServiceState=" + mServiceState[i]); 1261 pw.println(" mSignalStrength=" + mSignalStrength[i]); 1262 pw.println(" mMessageWaiting=" + mMessageWaiting[i]); 1263 pw.println(" mCallForwarding=" + mCallForwarding[i]); 1264 pw.println(" mDataActivity=" + mDataActivity[i]); 1265 pw.println(" mDataConnectionState=" + mDataConnectionState[i]); 1266 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible[i]); 1267 pw.println(" mDataConnectionReason=" + mDataConnectionReason[i]); 1268 pw.println(" mDataConnectionApn=" + mDataConnectionApn[i]); 1269 pw.println(" mDataConnectionLinkProperties=" + mDataConnectionLinkProperties[i]); 1270 pw.println(" mDataConnectionNetworkCapabilities=" + 1271 mDataConnectionNetworkCapabilities[i]); 1272 pw.println(" mCellLocation=" + mCellLocation[i]); 1273 pw.println(" mCellInfo=" + mCellInfo.get(i)); 1274 } 1275 pw.println(" mDcRtInfo=" + mDcRtInfo); 1276 pw.println("registrations: count=" + recordCount); 1277 for (Record r : mRecords) { 1278 pw.println(" " + r); 1279 } 1280 } 1281 } 1282 1283 // 1284 // the legacy intent broadcasting 1285 // 1286 1287 private void broadcastServiceStateChanged(ServiceState state, int subId) { 1288 long ident = Binder.clearCallingIdentity(); 1289 try { 1290 mBatteryStats.notePhoneState(state.getState()); 1291 } catch (RemoteException re) { 1292 // Can't do much 1293 } finally { 1294 Binder.restoreCallingIdentity(ident); 1295 } 1296 1297 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); 1298 Bundle data = new Bundle(); 1299 state.fillInNotifierBundle(data); 1300 intent.putExtras(data); 1301 // Pass the subscription along with the intent. 1302 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1303 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1304 } 1305 1306 private void broadcastSignalStrengthChanged(SignalStrength signalStrength, int subId) { 1307 long ident = Binder.clearCallingIdentity(); 1308 try { 1309 mBatteryStats.notePhoneSignalStrength(signalStrength); 1310 } catch (RemoteException e) { 1311 /* The remote entity disappeared, we can safely ignore the exception. */ 1312 } finally { 1313 Binder.restoreCallingIdentity(ident); 1314 } 1315 1316 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED); 1317 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1318 Bundle data = new Bundle(); 1319 signalStrength.fillInNotifierBundle(data); 1320 intent.putExtras(data); 1321 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1322 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1323 } 1324 1325 private void broadcastCallStateChanged(int state, String incomingNumber, int subId) { 1326 long ident = Binder.clearCallingIdentity(); 1327 try { 1328 if (state == TelephonyManager.CALL_STATE_IDLE) { 1329 mBatteryStats.notePhoneOff(); 1330 } else { 1331 mBatteryStats.notePhoneOn(); 1332 } 1333 } catch (RemoteException e) { 1334 /* The remote entity disappeared, we can safely ignore the exception. */ 1335 } finally { 1336 Binder.restoreCallingIdentity(ident); 1337 } 1338 1339 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED); 1340 intent.putExtra(PhoneConstants.STATE_KEY, 1341 DefaultPhoneNotifier.convertCallState(state).toString()); 1342 if (!TextUtils.isEmpty(incomingNumber)) { 1343 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber); 1344 } 1345 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1346 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1347 android.Manifest.permission.READ_PHONE_STATE); 1348 } 1349 1350 private void broadcastDataConnectionStateChanged(int state, 1351 boolean isDataConnectivityPossible, 1352 String reason, String apn, String apnType, LinkProperties linkProperties, 1353 NetworkCapabilities networkCapabilities, boolean roaming, int subId) { 1354 // Note: not reporting to the battery stats service here, because the 1355 // status bar takes care of that after taking into account all of the 1356 // required info. 1357 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); 1358 intent.putExtra(PhoneConstants.STATE_KEY, 1359 DefaultPhoneNotifier.convertDataState(state).toString()); 1360 if (!isDataConnectivityPossible) { 1361 intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true); 1362 } 1363 if (reason != null) { 1364 intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); 1365 } 1366 if (linkProperties != null) { 1367 intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties); 1368 String iface = linkProperties.getInterfaceName(); 1369 if (iface != null) { 1370 intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface); 1371 } 1372 } 1373 if (networkCapabilities != null) { 1374 intent.putExtra(PhoneConstants.DATA_NETWORK_CAPABILITIES_KEY, networkCapabilities); 1375 } 1376 if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true); 1377 1378 intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); 1379 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1380 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1381 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1382 } 1383 1384 private void broadcastDataConnectionFailed(String reason, String apnType, 1385 int subId) { 1386 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED); 1387 intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason); 1388 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1389 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1390 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1391 } 1392 1393 private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState, 1394 int backgroundCallState, int disconnectCause, int preciseDisconnectCause) { 1395 Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED); 1396 intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState); 1397 intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState); 1398 intent.putExtra(TelephonyManager.EXTRA_BACKGROUND_CALL_STATE, backgroundCallState); 1399 intent.putExtra(TelephonyManager.EXTRA_DISCONNECT_CAUSE, disconnectCause); 1400 intent.putExtra(TelephonyManager.EXTRA_PRECISE_DISCONNECT_CAUSE, preciseDisconnectCause); 1401 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1402 android.Manifest.permission.READ_PRECISE_PHONE_STATE); 1403 } 1404 1405 private void broadcastPreciseDataConnectionStateChanged(int state, int networkType, 1406 String apnType, String apn, String reason, LinkProperties linkProperties, 1407 String failCause) { 1408 Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED); 1409 intent.putExtra(PhoneConstants.STATE_KEY, state); 1410 intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType); 1411 if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); 1412 if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1413 if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); 1414 if (linkProperties != null) { 1415 intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY,linkProperties); 1416 } 1417 if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause); 1418 1419 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1420 android.Manifest.permission.READ_PRECISE_PHONE_STATE); 1421 } 1422 1423 private boolean checkNotifyPermission(String method) { 1424 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) 1425 == PackageManager.PERMISSION_GRANTED) { 1426 return true; 1427 } 1428 String msg = "Modify Phone State Permission Denial: " + method + " from pid=" 1429 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid(); 1430 if (DBG) log(msg); 1431 return false; 1432 } 1433 1434 private void checkListenerPermission(int events) { 1435 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { 1436 mContext.enforceCallingOrSelfPermission( 1437 android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 1438 1439 } 1440 1441 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) { 1442 mContext.enforceCallingOrSelfPermission( 1443 android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 1444 1445 } 1446 1447 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) { 1448 mContext.enforceCallingOrSelfPermission( 1449 android.Manifest.permission.READ_PHONE_STATE, null); 1450 } 1451 1452 if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) { 1453 mContext.enforceCallingOrSelfPermission( 1454 android.Manifest.permission.READ_PRECISE_PHONE_STATE, null); 1455 1456 } 1457 1458 if ((events & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) { 1459 mContext.enforceCallingOrSelfPermission( 1460 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); 1461 } 1462 } 1463 1464 private void handleRemoveListLocked() { 1465 int size = mRemoveList.size(); 1466 if (VDBG) log("handleRemoveListLocked: mRemoveList.size()=" + size); 1467 if (size > 0) { 1468 for (IBinder b: mRemoveList) { 1469 remove(b); 1470 } 1471 mRemoveList.clear(); 1472 } 1473 } 1474 1475 private boolean validateEventsAndUserLocked(Record r, int events) { 1476 int foregroundUser; 1477 long callingIdentity = Binder.clearCallingIdentity(); 1478 boolean valid = false; 1479 try { 1480 foregroundUser = ActivityManager.getCurrentUser(); 1481 valid = r.callerUid == foregroundUser && r.matchPhoneStateListenerEvent(events); 1482 if (DBG | DBG_LOC) { 1483 log("validateEventsAndUserLocked: valid=" + valid 1484 + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser 1485 + " r.events=" + r.events + " events=" + events); 1486 } 1487 } finally { 1488 Binder.restoreCallingIdentity(callingIdentity); 1489 } 1490 return valid; 1491 } 1492 1493 private boolean validatePhoneId(int phoneId) { 1494 boolean valid = (phoneId >= 0) && (phoneId < mNumPhones); 1495 if (VDBG) log("validatePhoneId: " + valid); 1496 return valid; 1497 } 1498 1499 private static void log(String s) { 1500 Rlog.d(TAG, s); 1501 } 1502 1503 private static class LogSSC { 1504 private Time mTime; 1505 private String mS; 1506 private int mSubId; 1507 private int mPhoneId; 1508 private ServiceState mState; 1509 1510 public void set(Time t, String s, int subId, int phoneId, ServiceState state) { 1511 mTime = t; mS = s; mSubId = subId; mPhoneId = phoneId; mState = state; 1512 } 1513 1514 @Override 1515 public String toString() { 1516 return mS + " Time " + mTime.toString() + " mSubId " + mSubId + " mPhoneId " 1517 + mPhoneId + " mState " + mState; 1518 } 1519 } 1520 1521 private LogSSC logSSC [] = new LogSSC[10]; 1522 private int next = 0; 1523 1524 private void logServiceStateChanged(String s, int subId, int phoneId, ServiceState state) { 1525 if (logSSC == null || logSSC.length == 0) { 1526 return; 1527 } 1528 if (logSSC[next] == null) { 1529 logSSC[next] = new LogSSC(); 1530 } 1531 Time t = new Time(); 1532 t.setToNow(); 1533 logSSC[next].set(t, s, subId, phoneId, state); 1534 if (++next >= logSSC.length) { 1535 next = 0; 1536 } 1537 } 1538 1539 private void toStringLogSSC(String prompt) { 1540 if (logSSC == null || logSSC.length == 0 || (next == 0 && logSSC[next] == null)) { 1541 log(prompt + ": logSSC is empty"); 1542 } else { 1543 // There is at least one element 1544 log(prompt + ": logSSC.length=" + logSSC.length + " next=" + next); 1545 int i = next; 1546 if (logSSC[i] == null) { 1547 // logSSC is not full so back to the beginning 1548 i = 0; 1549 } 1550 do { 1551 log(logSSC[i].toString()); 1552 if (++i >= logSSC.length) { 1553 i = 0; 1554 } 1555 } while (i != next); 1556 log(prompt + ": ----------------"); 1557 } 1558 } 1559 1560 boolean idMatch(int rSubId, int subId, int phoneId) { 1561 if(rSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { 1562 if(subId < 0) { 1563 // Invalid case, we need compare phoneId with default one. 1564 return (mDefaultPhoneId == phoneId); 1565 } 1566 return (subId == mDefaultSubId); 1567 } else { 1568 return (rSubId == subId); 1569 } 1570 } 1571 1572 private void checkPossibleMissNotify(Record r, int phoneId) { 1573 int events = r.events; 1574 1575 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { 1576 try { 1577 if (VDBG) log("checkPossibleMissNotify: onServiceStateChanged state=" + 1578 mServiceState[phoneId]); 1579 r.callback.onServiceStateChanged( 1580 new ServiceState(mServiceState[phoneId])); 1581 } catch (RemoteException ex) { 1582 mRemoveList.add(r.binder); 1583 } 1584 } 1585 1586 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { 1587 try { 1588 SignalStrength signalStrength = mSignalStrength[phoneId]; 1589 if (DBG) { 1590 log("checkPossibleMissNotify: onSignalStrengthsChanged SS=" + signalStrength); 1591 } 1592 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); 1593 } catch (RemoteException ex) { 1594 mRemoveList.add(r.binder); 1595 } 1596 } 1597 1598 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { 1599 try { 1600 int gsmSignalStrength = mSignalStrength[phoneId] 1601 .getGsmSignalStrength(); 1602 if (DBG) { 1603 log("checkPossibleMissNotify: onSignalStrengthChanged SS=" + 1604 gsmSignalStrength); 1605 } 1606 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 1607 : gsmSignalStrength)); 1608 } catch (RemoteException ex) { 1609 mRemoveList.add(r.binder); 1610 } 1611 } 1612 1613 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) { 1614 try { 1615 if (DBG_LOC) { 1616 log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = " 1617 + mCellInfo.get(phoneId)); 1618 } 1619 r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); 1620 } catch (RemoteException ex) { 1621 mRemoveList.add(r.binder); 1622 } 1623 } 1624 1625 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { 1626 try { 1627 if (VDBG) { 1628 log("checkPossibleMissNotify: onMessageWaitingIndicatorChanged phoneId=" 1629 + phoneId + " mwi=" + mMessageWaiting[phoneId]); 1630 } 1631 r.callback.onMessageWaitingIndicatorChanged( 1632 mMessageWaiting[phoneId]); 1633 } catch (RemoteException ex) { 1634 mRemoveList.add(r.binder); 1635 } 1636 } 1637 1638 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { 1639 try { 1640 if (VDBG) { 1641 log("checkPossibleMissNotify: onCallForwardingIndicatorChanged phoneId=" 1642 + phoneId + " cfi=" + mCallForwarding[phoneId]); 1643 } 1644 r.callback.onCallForwardingIndicatorChanged( 1645 mCallForwarding[phoneId]); 1646 } catch (RemoteException ex) { 1647 mRemoveList.add(r.binder); 1648 } 1649 } 1650 1651 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { 1652 try { 1653 if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = " 1654 + mCellLocation[phoneId]); 1655 r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId])); 1656 } catch (RemoteException ex) { 1657 mRemoveList.add(r.binder); 1658 } 1659 } 1660 1661 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { 1662 try { 1663 if (DBG) { 1664 log("checkPossibleMissNotify: onDataConnectionStateChanged(mDataConnectionState" 1665 + "=" + mDataConnectionState[phoneId] 1666 + ", mDataConnectionNetworkType=" + mDataConnectionNetworkType[phoneId] 1667 + ")"); 1668 } 1669 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], 1670 mDataConnectionNetworkType[phoneId]); 1671 } catch (RemoteException ex) { 1672 mRemoveList.add(r.binder); 1673 } 1674 } 1675 } 1676} 1677