1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server; 18 19 import android.app.ActivityManager; 20 import android.content.BroadcastReceiver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.content.pm.PackageManager; 25 import android.net.LinkProperties; 26 import android.net.NetworkCapabilities; 27 import android.os.Binder; 28 import android.os.Bundle; 29 import android.os.Handler; 30 import android.os.IBinder; 31 import android.os.Message; 32 import android.os.RemoteException; 33 import android.os.UserHandle; 34 import android.telephony.CellLocation; 35 import android.telephony.DataConnectionRealTimeInfo; 36 import android.telephony.Rlog; 37 import android.telephony.TelephonyManager; 38 import android.telephony.SubscriptionManager; 39 import android.telephony.PhoneStateListener; 40 import android.telephony.ServiceState; 41 import android.telephony.SignalStrength; 42 import android.telephony.CellInfo; 43 import android.telephony.VoLteServiceState; 44 import android.telephony.DisconnectCause; 45 import android.telephony.PreciseCallState; 46 import android.telephony.PreciseDataConnectionState; 47 import android.telephony.PreciseDisconnectCause; 48 import android.text.TextUtils; 49 import android.text.format.Time; 50 51 import java.util.ArrayList; 52 import java.util.List; 53 import java.io.FileDescriptor; 54 import java.io.PrintWriter; 55 56 import com.android.internal.app.IBatteryStats; 57 import com.android.internal.telephony.IOnSubscriptionsChangedListener; 58 import com.android.internal.telephony.ITelephonyRegistry; 59 import com.android.internal.telephony.IPhoneStateListener; 60 import com.android.internal.telephony.DefaultPhoneNotifier; 61 import com.android.internal.telephony.PhoneConstants; 62 import com.android.internal.telephony.ServiceStateTracker; 63 import com.android.internal.telephony.TelephonyIntents; 64 import 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 */ 80 class 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 addOnSubscriptionsChangedListener(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 removeOnSubscriptionsChangedListener(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 (DBG) { 624 Record r = mRecords.get(i); 625 log("remove: binder=" + binder + "r.pkgForDebug" + r.pkgForDebug 626 + "r.callback" + r.callback); 627 } 628 mRecords.remove(i); 629 return; 630 } 631 } 632 } 633 } 634 635 public void notifyCallState(int state, String incomingNumber) { 636 if (!checkNotifyPermission("notifyCallState()")) { 637 return; 638 } 639 640 if (VDBG) { 641 log("notifyCallState: state=" + state + " incomingNumber=" + incomingNumber); 642 } 643 644 synchronized (mRecords) { 645 for (Record r : mRecords) { 646 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) && 647 (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { 648 try { 649 r.callback.onCallStateChanged(state, incomingNumber); 650 } catch (RemoteException ex) { 651 mRemoveList.add(r.binder); 652 } 653 } 654 } 655 handleRemoveListLocked(); 656 } 657 broadcastCallStateChanged(state, incomingNumber, 658 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); 659 } 660 661 public void notifyCallStateForSubscriber(int subId, int state, String incomingNumber) { 662 if (!checkNotifyPermission("notifyCallState()")) { 663 return; 664 } 665 if (VDBG) { 666 log("notifyCallStateForSubscriber: subId=" + subId 667 + " state=" + state + " incomingNumber=" + incomingNumber); 668 } 669 synchronized (mRecords) { 670 int phoneId = SubscriptionManager.getPhoneId(subId); 671 if (validatePhoneId(phoneId)) { 672 mCallState[phoneId] = state; 673 mCallIncomingNumber[phoneId] = incomingNumber; 674 for (Record r : mRecords) { 675 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) && 676 (r.subId == subId) && 677 (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { 678 try { 679 r.callback.onCallStateChanged(state, incomingNumber); 680 } catch (RemoteException ex) { 681 mRemoveList.add(r.binder); 682 } 683 } 684 } 685 } 686 handleRemoveListLocked(); 687 } 688 broadcastCallStateChanged(state, incomingNumber, subId); 689 } 690 691 public void notifyServiceStateForPhoneId(int phoneId, int subId, ServiceState state) { 692 if (!checkNotifyPermission("notifyServiceState()")){ 693 return; 694 } 695 696 synchronized (mRecords) { 697 if (VDBG) { 698 log("notifyServiceStateForSubscriber: subId=" + subId + " phoneId=" + phoneId 699 + " state=" + state); 700 } 701 if (validatePhoneId(phoneId)) { 702 mServiceState[phoneId] = state; 703 logServiceStateChanged("notifyServiceStateForSubscriber", subId, phoneId, state); 704 if (VDBG) toStringLogSSC("notifyServiceStateForSubscriber"); 705 706 for (Record r : mRecords) { 707 if (VDBG) { 708 log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId 709 + " phoneId=" + phoneId + " state=" + state); 710 } 711 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SERVICE_STATE) && 712 idMatch(r.subId, subId, phoneId)) { 713 try { 714 if (DBG) { 715 log("notifyServiceStateForSubscriber: callback.onSSC r=" + r 716 + " subId=" + subId + " phoneId=" + phoneId 717 + " state=" + state); 718 } 719 r.callback.onServiceStateChanged(new ServiceState(state)); 720 } catch (RemoteException ex) { 721 mRemoveList.add(r.binder); 722 } 723 } 724 } 725 } else { 726 log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId); 727 } 728 handleRemoveListLocked(); 729 } 730 broadcastServiceStateChanged(state, subId); 731 } 732 733 public void notifySignalStrength(SignalStrength signalStrength) { 734 notifySignalStrengthForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, 735 signalStrength); 736 } 737 738 public void notifySignalStrengthForSubscriber(int subId, SignalStrength signalStrength) { 739 if (!checkNotifyPermission("notifySignalStrength()")) { 740 return; 741 } 742 if (VDBG) { 743 log("notifySignalStrengthForSubscriber: subId=" + subId 744 + " signalStrength=" + signalStrength); 745 toStringLogSSC("notifySignalStrengthForSubscriber"); 746 } 747 synchronized (mRecords) { 748 int phoneId = SubscriptionManager.getPhoneId(subId); 749 if (validatePhoneId(phoneId)) { 750 if (VDBG) log("notifySignalStrengthForSubscriber: valid phoneId=" + phoneId); 751 mSignalStrength[phoneId] = signalStrength; 752 for (Record r : mRecords) { 753 if (VDBG) { 754 log("notifySignalStrengthForSubscriber: r=" + r + " subId=" + subId 755 + " phoneId=" + phoneId + " ss=" + signalStrength); 756 } 757 if (r.matchPhoneStateListenerEvent( 758 PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) && 759 idMatch(r.subId, subId, phoneId)) { 760 try { 761 if (DBG) { 762 log("notifySignalStrengthForSubscriber: callback.onSsS r=" + r 763 + " subId=" + subId + " phoneId=" + phoneId 764 + " ss=" + signalStrength); 765 } 766 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); 767 } catch (RemoteException ex) { 768 mRemoveList.add(r.binder); 769 } 770 } 771 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTH) && 772 idMatch(r.subId, subId, phoneId)){ 773 try { 774 int gsmSignalStrength = signalStrength.getGsmSignalStrength(); 775 int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); 776 if (DBG) { 777 log("notifySignalStrengthForSubscriber: callback.onSS r=" + r 778 + " subId=" + subId + " phoneId=" + phoneId 779 + " gsmSS=" + gsmSignalStrength + " ss=" + ss); 780 } 781 r.callback.onSignalStrengthChanged(ss); 782 } catch (RemoteException ex) { 783 mRemoveList.add(r.binder); 784 } 785 } 786 } 787 } else { 788 log("notifySignalStrengthForSubscriber: invalid phoneId=" + phoneId); 789 } 790 handleRemoveListLocked(); 791 } 792 broadcastSignalStrengthChanged(signalStrength, subId); 793 } 794 795 public void notifyCellInfo(List<CellInfo> cellInfo) { 796 notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellInfo); 797 } 798 799 public void notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo) { 800 if (!checkNotifyPermission("notifyCellInfo()")) { 801 return; 802 } 803 if (VDBG) { 804 log("notifyCellInfoForSubscriber: subId=" + subId 805 + " cellInfo=" + cellInfo); 806 } 807 808 synchronized (mRecords) { 809 int phoneId = SubscriptionManager.getPhoneId(subId); 810 if (validatePhoneId(phoneId)) { 811 mCellInfo.set(phoneId, cellInfo); 812 for (Record r : mRecords) { 813 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) && 814 idMatch(r.subId, subId, phoneId)) { 815 try { 816 if (DBG_LOC) { 817 log("notifyCellInfo: mCellInfo=" + cellInfo + " r=" + r); 818 } 819 r.callback.onCellInfoChanged(cellInfo); 820 } catch (RemoteException ex) { 821 mRemoveList.add(r.binder); 822 } 823 } 824 } 825 } 826 handleRemoveListLocked(); 827 } 828 } 829 830 public void notifyDataConnectionRealTimeInfo(DataConnectionRealTimeInfo dcRtInfo) { 831 if (!checkNotifyPermission("notifyDataConnectionRealTimeInfo()")) { 832 return; 833 } 834 835 synchronized (mRecords) { 836 mDcRtInfo = dcRtInfo; 837 for (Record r : mRecords) { 838 if (validateEventsAndUserLocked(r, 839 PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO)) { 840 try { 841 if (DBG_LOC) { 842 log("notifyDataConnectionRealTimeInfo: mDcRtInfo=" 843 + mDcRtInfo + " r=" + r); 844 } 845 r.callback.onDataConnectionRealTimeInfoChanged(mDcRtInfo); 846 } catch (RemoteException ex) { 847 mRemoveList.add(r.binder); 848 } 849 } 850 } 851 handleRemoveListLocked(); 852 } 853 } 854 855 @Override 856 public void notifyMessageWaitingChangedForPhoneId(int phoneId, int subId, boolean mwi) { 857 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) { 858 return; 859 } 860 if (VDBG) { 861 log("notifyMessageWaitingChangedForSubscriberPhoneID: subId=" + phoneId 862 + " mwi=" + mwi); 863 } 864 synchronized (mRecords) { 865 if (validatePhoneId(phoneId)) { 866 mMessageWaiting[phoneId] = mwi; 867 for (Record r : mRecords) { 868 if (r.matchPhoneStateListenerEvent( 869 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) && 870 idMatch(r.subId, subId, phoneId)) { 871 try { 872 r.callback.onMessageWaitingIndicatorChanged(mwi); 873 } catch (RemoteException ex) { 874 mRemoveList.add(r.binder); 875 } 876 } 877 } 878 } 879 handleRemoveListLocked(); 880 } 881 } 882 883 public void notifyCallForwardingChanged(boolean cfi) { 884 notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cfi); 885 } 886 887 public void notifyCallForwardingChangedForSubscriber(int subId, boolean cfi) { 888 if (!checkNotifyPermission("notifyCallForwardingChanged()")) { 889 return; 890 } 891 if (VDBG) { 892 log("notifyCallForwardingChangedForSubscriber: subId=" + subId 893 + " cfi=" + cfi); 894 } 895 synchronized (mRecords) { 896 int phoneId = SubscriptionManager.getPhoneId(subId); 897 if (validatePhoneId(phoneId)) { 898 mCallForwarding[phoneId] = cfi; 899 for (Record r : mRecords) { 900 if (r.matchPhoneStateListenerEvent( 901 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) && 902 idMatch(r.subId, subId, phoneId)) { 903 try { 904 r.callback.onCallForwardingIndicatorChanged(cfi); 905 } catch (RemoteException ex) { 906 mRemoveList.add(r.binder); 907 } 908 } 909 } 910 } 911 handleRemoveListLocked(); 912 } 913 } 914 915 public void notifyDataActivity(int state) { 916 notifyDataActivityForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state); 917 } 918 919 public void notifyDataActivityForSubscriber(int subId, int state) { 920 if (!checkNotifyPermission("notifyDataActivity()" )) { 921 return; 922 } 923 synchronized (mRecords) { 924 int phoneId = SubscriptionManager.getPhoneId(subId); 925 if (validatePhoneId(phoneId)) { 926 mDataActivity[phoneId] = state; 927 for (Record r : mRecords) { 928 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_DATA_ACTIVITY)) { 929 try { 930 r.callback.onDataActivity(state); 931 } catch (RemoteException ex) { 932 mRemoveList.add(r.binder); 933 } 934 } 935 } 936 } 937 handleRemoveListLocked(); 938 } 939 } 940 941 public void notifyDataConnection(int state, boolean isDataConnectivityPossible, 942 String reason, String apn, String apnType, LinkProperties linkProperties, 943 NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { 944 notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state, 945 isDataConnectivityPossible,reason, apn, apnType, linkProperties, 946 networkCapabilities, networkType, roaming); 947 } 948 949 public void notifyDataConnectionForSubscriber(int subId, int state, 950 boolean isDataConnectivityPossible, String reason, String apn, String apnType, 951 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 952 int networkType, boolean roaming) { 953 if (!checkNotifyPermission("notifyDataConnection()" )) { 954 return; 955 } 956 if (VDBG) { 957 log("notifyDataConnectionForSubscriber: subId=" + subId 958 + " state=" + state + " isDataConnectivityPossible=" + isDataConnectivityPossible 959 + " reason='" + reason 960 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType 961 + " mRecords.size()=" + mRecords.size()); 962 } 963 synchronized (mRecords) { 964 int phoneId = SubscriptionManager.getPhoneId(subId); 965 if (validatePhoneId(phoneId)) { 966 boolean modified = false; 967 if (state == TelephonyManager.DATA_CONNECTED) { 968 if (!mConnectedApns.contains(apnType)) { 969 mConnectedApns.add(apnType); 970 if (mDataConnectionState[phoneId] != state) { 971 mDataConnectionState[phoneId] = state; 972 modified = true; 973 } 974 } 975 } else { 976 if (mConnectedApns.remove(apnType)) { 977 if (mConnectedApns.isEmpty()) { 978 mDataConnectionState[phoneId] = state; 979 modified = true; 980 } else { 981 // leave mDataConnectionState as is and 982 // send out the new status for the APN in question. 983 } 984 } 985 } 986 mDataConnectionPossible[phoneId] = isDataConnectivityPossible; 987 mDataConnectionReason[phoneId] = reason; 988 mDataConnectionLinkProperties[phoneId] = linkProperties; 989 mDataConnectionNetworkCapabilities[phoneId] = networkCapabilities; 990 if (mDataConnectionNetworkType[phoneId] != networkType) { 991 mDataConnectionNetworkType[phoneId] = networkType; 992 // need to tell registered listeners about the new network type 993 modified = true; 994 } 995 if (modified) { 996 if (DBG) { 997 log("onDataConnectionStateChanged(" + mDataConnectionState[phoneId] 998 + ", " + mDataConnectionNetworkType[phoneId] + ")"); 999 } 1000 for (Record r : mRecords) { 1001 if (r.matchPhoneStateListenerEvent( 1002 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) && 1003 idMatch(r.subId, subId, phoneId)) { 1004 try { 1005 log("Notify data connection state changed on sub: " + 1006 subId); 1007 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], 1008 mDataConnectionNetworkType[phoneId]); 1009 } catch (RemoteException ex) { 1010 mRemoveList.add(r.binder); 1011 } 1012 } 1013 } 1014 handleRemoveListLocked(); 1015 } 1016 mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType, 1017 apnType, apn, reason, linkProperties, ""); 1018 for (Record r : mRecords) { 1019 if (r.matchPhoneStateListenerEvent( 1020 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { 1021 try { 1022 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 1023 } catch (RemoteException ex) { 1024 mRemoveList.add(r.binder); 1025 } 1026 } 1027 } 1028 } 1029 handleRemoveListLocked(); 1030 } 1031 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn, 1032 apnType, linkProperties, networkCapabilities, roaming, subId); 1033 broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, reason, 1034 linkProperties, ""); 1035 } 1036 1037 public void notifyDataConnectionFailed(String reason, String apnType) { 1038 notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, 1039 reason, apnType); 1040 } 1041 1042 public void notifyDataConnectionFailedForSubscriber(int subId, 1043 String reason, String apnType) { 1044 if (!checkNotifyPermission("notifyDataConnectionFailed()")) { 1045 return; 1046 } 1047 if (VDBG) { 1048 log("notifyDataConnectionFailedForSubscriber: subId=" + subId 1049 + " reason=" + reason + " apnType=" + apnType); 1050 } 1051 synchronized (mRecords) { 1052 mPreciseDataConnectionState = new PreciseDataConnectionState( 1053 TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN, 1054 apnType, "", reason, null, ""); 1055 for (Record r : mRecords) { 1056 if (r.matchPhoneStateListenerEvent( 1057 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { 1058 try { 1059 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 1060 } catch (RemoteException ex) { 1061 mRemoveList.add(r.binder); 1062 } 1063 } 1064 } 1065 handleRemoveListLocked(); 1066 } 1067 broadcastDataConnectionFailed(reason, apnType, subId); 1068 broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN, 1069 TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", reason, null, ""); 1070 } 1071 1072 public void notifyCellLocation(Bundle cellLocation) { 1073 notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation); 1074 } 1075 1076 public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) { 1077 log("notifyCellLocationForSubscriber: subId=" + subId 1078 + " cellLocation=" + cellLocation); 1079 if (!checkNotifyPermission("notifyCellLocation()")) { 1080 return; 1081 } 1082 if (VDBG) { 1083 log("notifyCellLocationForSubscriber: subId=" + subId 1084 + " cellLocation=" + cellLocation); 1085 } 1086 synchronized (mRecords) { 1087 int phoneId = SubscriptionManager.getPhoneId(subId); 1088 if (validatePhoneId(phoneId)) { 1089 mCellLocation[phoneId] = cellLocation; 1090 for (Record r : mRecords) { 1091 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) && 1092 idMatch(r.subId, subId, phoneId)) { 1093 try { 1094 if (DBG_LOC) { 1095 log("notifyCellLocation: cellLocation=" + cellLocation 1096 + " r=" + r); 1097 } 1098 r.callback.onCellLocationChanged(new Bundle(cellLocation)); 1099 } catch (RemoteException ex) { 1100 mRemoveList.add(r.binder); 1101 } 1102 } 1103 } 1104 } 1105 handleRemoveListLocked(); 1106 } 1107 } 1108 1109 public void notifyOtaspChanged(int otaspMode) { 1110 if (!checkNotifyPermission("notifyOtaspChanged()" )) { 1111 return; 1112 } 1113 synchronized (mRecords) { 1114 mOtaspMode = otaspMode; 1115 for (Record r : mRecords) { 1116 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_OTASP_CHANGED)) { 1117 try { 1118 r.callback.onOtaspChanged(otaspMode); 1119 } catch (RemoteException ex) { 1120 mRemoveList.add(r.binder); 1121 } 1122 } 1123 } 1124 handleRemoveListLocked(); 1125 } 1126 } 1127 1128 public void notifyPreciseCallState(int ringingCallState, int foregroundCallState, 1129 int backgroundCallState) { 1130 if (!checkNotifyPermission("notifyPreciseCallState()")) { 1131 return; 1132 } 1133 synchronized (mRecords) { 1134 mRingingCallState = ringingCallState; 1135 mForegroundCallState = foregroundCallState; 1136 mBackgroundCallState = backgroundCallState; 1137 mPreciseCallState = new PreciseCallState(ringingCallState, foregroundCallState, 1138 backgroundCallState, 1139 DisconnectCause.NOT_VALID, 1140 PreciseDisconnectCause.NOT_VALID); 1141 for (Record r : mRecords) { 1142 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_PRECISE_CALL_STATE)) { 1143 try { 1144 r.callback.onPreciseCallStateChanged(mPreciseCallState); 1145 } catch (RemoteException ex) { 1146 mRemoveList.add(r.binder); 1147 } 1148 } 1149 } 1150 handleRemoveListLocked(); 1151 } 1152 broadcastPreciseCallStateChanged(ringingCallState, foregroundCallState, backgroundCallState, 1153 DisconnectCause.NOT_VALID, 1154 PreciseDisconnectCause.NOT_VALID); 1155 } 1156 1157 public void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause) { 1158 if (!checkNotifyPermission("notifyDisconnectCause()")) { 1159 return; 1160 } 1161 synchronized (mRecords) { 1162 mPreciseCallState = new PreciseCallState(mRingingCallState, mForegroundCallState, 1163 mBackgroundCallState, disconnectCause, preciseDisconnectCause); 1164 for (Record r : mRecords) { 1165 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_PRECISE_CALL_STATE)) { 1166 try { 1167 r.callback.onPreciseCallStateChanged(mPreciseCallState); 1168 } catch (RemoteException ex) { 1169 mRemoveList.add(r.binder); 1170 } 1171 } 1172 } 1173 handleRemoveListLocked(); 1174 } 1175 broadcastPreciseCallStateChanged(mRingingCallState, mForegroundCallState, 1176 mBackgroundCallState, disconnectCause, preciseDisconnectCause); 1177 } 1178 1179 public void notifyPreciseDataConnectionFailed(String reason, String apnType, 1180 String apn, String failCause) { 1181 if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) { 1182 return; 1183 } 1184 synchronized (mRecords) { 1185 mPreciseDataConnectionState = new PreciseDataConnectionState( 1186 TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN, 1187 apnType, apn, reason, null, failCause); 1188 for (Record r : mRecords) { 1189 if (r.matchPhoneStateListenerEvent( 1190 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)) { 1191 try { 1192 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 1193 } catch (RemoteException ex) { 1194 mRemoveList.add(r.binder); 1195 } 1196 } 1197 } 1198 handleRemoveListLocked(); 1199 } 1200 broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN, 1201 TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause); 1202 } 1203 1204 public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) { 1205 if (!checkNotifyPermission("notifyVoLteServiceStateChanged()")) { 1206 return; 1207 } 1208 synchronized (mRecords) { 1209 mVoLteServiceState = lteState; 1210 for (Record r : mRecords) { 1211 if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_VOLTE_STATE)) { 1212 try { 1213 r.callback.onVoLteServiceStateChanged( 1214 new VoLteServiceState(mVoLteServiceState)); 1215 } catch (RemoteException ex) { 1216 mRemoveList.add(r.binder); 1217 } 1218 } 1219 } 1220 handleRemoveListLocked(); 1221 } 1222 } 1223 1224 public void notifyOemHookRawEventForSubscriber(int subId, byte[] rawData) { 1225 if (!checkNotifyPermission("notifyOemHookRawEventForSubscriber")) { 1226 return; 1227 } 1228 1229 synchronized (mRecords) { 1230 for (Record r : mRecords) { 1231 if (VDBG) { 1232 log("notifyOemHookRawEventForSubscriber: r=" + r + " subId=" + subId); 1233 } 1234 if ((r.matchPhoneStateListenerEvent( 1235 PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT)) && 1236 ((r.subId == subId) || 1237 (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID))) { 1238 try { 1239 r.callback.onOemHookRawEvent(rawData); 1240 } catch (RemoteException ex) { 1241 mRemoveList.add(r.binder); 1242 } 1243 } 1244 } 1245 handleRemoveListLocked(); 1246 } 1247 } 1248 1249 @Override 1250 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1251 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 1252 != PackageManager.PERMISSION_GRANTED) { 1253 pw.println("Permission Denial: can't dump telephony.registry from from pid=" 1254 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 1255 return; 1256 } 1257 synchronized (mRecords) { 1258 final int recordCount = mRecords.size(); 1259 pw.println("last known state:"); 1260 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 1261 pw.println(" Phone Id=" + i); 1262 pw.println(" mCallState=" + mCallState[i]); 1263 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber[i]); 1264 pw.println(" mServiceState=" + mServiceState[i]); 1265 pw.println(" mSignalStrength=" + mSignalStrength[i]); 1266 pw.println(" mMessageWaiting=" + mMessageWaiting[i]); 1267 pw.println(" mCallForwarding=" + mCallForwarding[i]); 1268 pw.println(" mDataActivity=" + mDataActivity[i]); 1269 pw.println(" mDataConnectionState=" + mDataConnectionState[i]); 1270 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible[i]); 1271 pw.println(" mDataConnectionReason=" + mDataConnectionReason[i]); 1272 pw.println(" mDataConnectionApn=" + mDataConnectionApn[i]); 1273 pw.println(" mDataConnectionLinkProperties=" + mDataConnectionLinkProperties[i]); 1274 pw.println(" mDataConnectionNetworkCapabilities=" + 1275 mDataConnectionNetworkCapabilities[i]); 1276 pw.println(" mCellLocation=" + mCellLocation[i]); 1277 pw.println(" mCellInfo=" + mCellInfo.get(i)); 1278 } 1279 pw.println(" mDcRtInfo=" + mDcRtInfo); 1280 pw.println("registrations: count=" + recordCount); 1281 for (Record r : mRecords) { 1282 pw.println(" " + r); 1283 } 1284 } 1285 } 1286 1287 // 1288 // the legacy intent broadcasting 1289 // 1290 1291 private void broadcastServiceStateChanged(ServiceState state, int subId) { 1292 long ident = Binder.clearCallingIdentity(); 1293 try { 1294 mBatteryStats.notePhoneState(state.getState()); 1295 } catch (RemoteException re) { 1296 // Can't do much 1297 } finally { 1298 Binder.restoreCallingIdentity(ident); 1299 } 1300 1301 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); 1302 Bundle data = new Bundle(); 1303 state.fillInNotifierBundle(data); 1304 intent.putExtras(data); 1305 // Pass the subscription along with the intent. 1306 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1307 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1308 } 1309 1310 private void broadcastSignalStrengthChanged(SignalStrength signalStrength, int subId) { 1311 long ident = Binder.clearCallingIdentity(); 1312 try { 1313 mBatteryStats.notePhoneSignalStrength(signalStrength); 1314 } catch (RemoteException e) { 1315 /* The remote entity disappeared, we can safely ignore the exception. */ 1316 } finally { 1317 Binder.restoreCallingIdentity(ident); 1318 } 1319 1320 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED); 1321 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1322 Bundle data = new Bundle(); 1323 signalStrength.fillInNotifierBundle(data); 1324 intent.putExtras(data); 1325 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1326 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1327 } 1328 1329 private void broadcastCallStateChanged(int state, String incomingNumber, int subId) { 1330 long ident = Binder.clearCallingIdentity(); 1331 try { 1332 if (state == TelephonyManager.CALL_STATE_IDLE) { 1333 mBatteryStats.notePhoneOff(); 1334 } else { 1335 mBatteryStats.notePhoneOn(); 1336 } 1337 } catch (RemoteException e) { 1338 /* The remote entity disappeared, we can safely ignore the exception. */ 1339 } finally { 1340 Binder.restoreCallingIdentity(ident); 1341 } 1342 1343 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED); 1344 intent.putExtra(PhoneConstants.STATE_KEY, 1345 DefaultPhoneNotifier.convertCallState(state).toString()); 1346 if (!TextUtils.isEmpty(incomingNumber)) { 1347 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber); 1348 } 1349 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1350 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1351 android.Manifest.permission.READ_PHONE_STATE); 1352 } 1353 1354 private void broadcastDataConnectionStateChanged(int state, 1355 boolean isDataConnectivityPossible, 1356 String reason, String apn, String apnType, LinkProperties linkProperties, 1357 NetworkCapabilities networkCapabilities, boolean roaming, int subId) { 1358 // Note: not reporting to the battery stats service here, because the 1359 // status bar takes care of that after taking into account all of the 1360 // required info. 1361 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); 1362 intent.putExtra(PhoneConstants.STATE_KEY, 1363 DefaultPhoneNotifier.convertDataState(state).toString()); 1364 if (!isDataConnectivityPossible) { 1365 intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true); 1366 } 1367 if (reason != null) { 1368 intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); 1369 } 1370 if (linkProperties != null) { 1371 intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties); 1372 String iface = linkProperties.getInterfaceName(); 1373 if (iface != null) { 1374 intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface); 1375 } 1376 } 1377 if (networkCapabilities != null) { 1378 intent.putExtra(PhoneConstants.DATA_NETWORK_CAPABILITIES_KEY, networkCapabilities); 1379 } 1380 if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true); 1381 1382 intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); 1383 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1384 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1385 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1386 } 1387 1388 private void broadcastDataConnectionFailed(String reason, String apnType, 1389 int subId) { 1390 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED); 1391 intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason); 1392 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1393 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1394 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1395 } 1396 1397 private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState, 1398 int backgroundCallState, int disconnectCause, int preciseDisconnectCause) { 1399 Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED); 1400 intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState); 1401 intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState); 1402 intent.putExtra(TelephonyManager.EXTRA_BACKGROUND_CALL_STATE, backgroundCallState); 1403 intent.putExtra(TelephonyManager.EXTRA_DISCONNECT_CAUSE, disconnectCause); 1404 intent.putExtra(TelephonyManager.EXTRA_PRECISE_DISCONNECT_CAUSE, preciseDisconnectCause); 1405 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1406 android.Manifest.permission.READ_PRECISE_PHONE_STATE); 1407 } 1408 1409 private void broadcastPreciseDataConnectionStateChanged(int state, int networkType, 1410 String apnType, String apn, String reason, LinkProperties linkProperties, 1411 String failCause) { 1412 Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED); 1413 intent.putExtra(PhoneConstants.STATE_KEY, state); 1414 intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType); 1415 if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); 1416 if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1417 if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); 1418 if (linkProperties != null) { 1419 intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY,linkProperties); 1420 } 1421 if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause); 1422 1423 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1424 android.Manifest.permission.READ_PRECISE_PHONE_STATE); 1425 } 1426 1427 private boolean checkNotifyPermission(String method) { 1428 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) 1429 == PackageManager.PERMISSION_GRANTED) { 1430 return true; 1431 } 1432 String msg = "Modify Phone State Permission Denial: " + method + " from pid=" 1433 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid(); 1434 if (DBG) log(msg); 1435 return false; 1436 } 1437 1438 private void checkListenerPermission(int events) { 1439 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { 1440 mContext.enforceCallingOrSelfPermission( 1441 android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 1442 1443 } 1444 1445 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) { 1446 mContext.enforceCallingOrSelfPermission( 1447 android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 1448 1449 } 1450 1451 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) { 1452 mContext.enforceCallingOrSelfPermission( 1453 android.Manifest.permission.READ_PHONE_STATE, null); 1454 } 1455 1456 if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) { 1457 mContext.enforceCallingOrSelfPermission( 1458 android.Manifest.permission.READ_PRECISE_PHONE_STATE, null); 1459 1460 } 1461 1462 if ((events & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) { 1463 mContext.enforceCallingOrSelfPermission( 1464 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); 1465 } 1466 } 1467 1468 private void handleRemoveListLocked() { 1469 int size = mRemoveList.size(); 1470 if (VDBG) log("handleRemoveListLocked: mRemoveList.size()=" + size); 1471 if (size > 0) { 1472 for (IBinder b: mRemoveList) { 1473 remove(b); 1474 } 1475 mRemoveList.clear(); 1476 } 1477 } 1478 1479 private boolean validateEventsAndUserLocked(Record r, int events) { 1480 int foregroundUser; 1481 long callingIdentity = Binder.clearCallingIdentity(); 1482 boolean valid = false; 1483 try { 1484 foregroundUser = ActivityManager.getCurrentUser(); 1485 valid = r.callerUid == foregroundUser && r.matchPhoneStateListenerEvent(events); 1486 if (DBG | DBG_LOC) { 1487 log("validateEventsAndUserLocked: valid=" + valid 1488 + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser 1489 + " r.events=" + r.events + " events=" + events); 1490 } 1491 } finally { 1492 Binder.restoreCallingIdentity(callingIdentity); 1493 } 1494 return valid; 1495 } 1496 1497 private boolean validatePhoneId(int phoneId) { 1498 boolean valid = (phoneId >= 0) && (phoneId < mNumPhones); 1499 if (VDBG) log("validatePhoneId: " + valid); 1500 return valid; 1501 } 1502 1503 private static void log(String s) { 1504 Rlog.d(TAG, s); 1505 } 1506 1507 private static class LogSSC { 1508 private Time mTime; 1509 private String mS; 1510 private int mSubId; 1511 private int mPhoneId; 1512 private ServiceState mState; 1513 1514 public void set(Time t, String s, int subId, int phoneId, ServiceState state) { 1515 mTime = t; mS = s; mSubId = subId; mPhoneId = phoneId; mState = state; 1516 } 1517 1518 @Override 1519 public String toString() { 1520 return mS + " Time " + mTime.toString() + " mSubId " + mSubId + " mPhoneId " 1521 + mPhoneId + " mState " + mState; 1522 } 1523 } 1524 1525 private LogSSC logSSC [] = new LogSSC[10]; 1526 private int next = 0; 1527 1528 private void logServiceStateChanged(String s, int subId, int phoneId, ServiceState state) { 1529 if (logSSC == null || logSSC.length == 0) { 1530 return; 1531 } 1532 if (logSSC[next] == null) { 1533 logSSC[next] = new LogSSC(); 1534 } 1535 Time t = new Time(); 1536 t.setToNow(); 1537 logSSC[next].set(t, s, subId, phoneId, state); 1538 if (++next >= logSSC.length) { 1539 next = 0; 1540 } 1541 } 1542 1543 private void toStringLogSSC(String prompt) { 1544 if (logSSC == null || logSSC.length == 0 || (next == 0 && logSSC[next] == null)) { 1545 log(prompt + ": logSSC is empty"); 1546 } else { 1547 // There is at least one element 1548 log(prompt + ": logSSC.length=" + logSSC.length + " next=" + next); 1549 int i = next; 1550 if (logSSC[i] == null) { 1551 // logSSC is not full so back to the beginning 1552 i = 0; 1553 } 1554 do { 1555 log(logSSC[i].toString()); 1556 if (++i >= logSSC.length) { 1557 i = 0; 1558 } 1559 } while (i != next); 1560 log(prompt + ": ----------------"); 1561 } 1562 } 1563 1564 boolean idMatch(int rSubId, int subId, int phoneId) { 1565 1566 if(subId < 0) { 1567 // Invalid case, we need compare phoneId with default one. 1568 return (mDefaultPhoneId == phoneId); 1569 } 1570 if(rSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) { 1571 return (subId == mDefaultSubId); 1572 } else { 1573 return (rSubId == subId); 1574 } 1575 } 1576 1577 private void checkPossibleMissNotify(Record r, int phoneId) { 1578 int events = r.events; 1579 1580 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { 1581 try { 1582 if (VDBG) log("checkPossibleMissNotify: onServiceStateChanged state=" + 1583 mServiceState[phoneId]); 1584 r.callback.onServiceStateChanged( 1585 new ServiceState(mServiceState[phoneId])); 1586 } catch (RemoteException ex) { 1587 mRemoveList.add(r.binder); 1588 } 1589 } 1590 1591 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { 1592 try { 1593 SignalStrength signalStrength = mSignalStrength[phoneId]; 1594 if (DBG) { 1595 log("checkPossibleMissNotify: onSignalStrengthsChanged SS=" + signalStrength); 1596 } 1597 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); 1598 } catch (RemoteException ex) { 1599 mRemoveList.add(r.binder); 1600 } 1601 } 1602 1603 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { 1604 try { 1605 int gsmSignalStrength = mSignalStrength[phoneId] 1606 .getGsmSignalStrength(); 1607 if (DBG) { 1608 log("checkPossibleMissNotify: onSignalStrengthChanged SS=" + 1609 gsmSignalStrength); 1610 } 1611 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 1612 : gsmSignalStrength)); 1613 } catch (RemoteException ex) { 1614 mRemoveList.add(r.binder); 1615 } 1616 } 1617 1618 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) { 1619 try { 1620 if (DBG_LOC) { 1621 log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = " 1622 + mCellInfo.get(phoneId)); 1623 } 1624 r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); 1625 } catch (RemoteException ex) { 1626 mRemoveList.add(r.binder); 1627 } 1628 } 1629 1630 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { 1631 try { 1632 if (VDBG) { 1633 log("checkPossibleMissNotify: onMessageWaitingIndicatorChanged phoneId=" 1634 + phoneId + " mwi=" + mMessageWaiting[phoneId]); 1635 } 1636 r.callback.onMessageWaitingIndicatorChanged( 1637 mMessageWaiting[phoneId]); 1638 } catch (RemoteException ex) { 1639 mRemoveList.add(r.binder); 1640 } 1641 } 1642 1643 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { 1644 try { 1645 if (VDBG) { 1646 log("checkPossibleMissNotify: onCallForwardingIndicatorChanged phoneId=" 1647 + phoneId + " cfi=" + mCallForwarding[phoneId]); 1648 } 1649 r.callback.onCallForwardingIndicatorChanged( 1650 mCallForwarding[phoneId]); 1651 } catch (RemoteException ex) { 1652 mRemoveList.add(r.binder); 1653 } 1654 } 1655 1656 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { 1657 try { 1658 if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = " 1659 + mCellLocation[phoneId]); 1660 r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId])); 1661 } catch (RemoteException ex) { 1662 mRemoveList.add(r.binder); 1663 } 1664 } 1665 1666 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { 1667 try { 1668 if (DBG) { 1669 log("checkPossibleMissNotify: onDataConnectionStateChanged(mDataConnectionState" 1670 + "=" + mDataConnectionState[phoneId] 1671 + ", mDataConnectionNetworkType=" + mDataConnectionNetworkType[phoneId] 1672 + ")"); 1673 } 1674 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], 1675 mDataConnectionNetworkType[phoneId]); 1676 } catch (RemoteException ex) { 1677 mRemoveList.add(r.binder); 1678 } 1679 } 1680 } 1681 } 1682