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