TelephonyRegistry.java revision 63f03dd94c43c22f2c77306059b5748e5e1e0e3c
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(int 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 int 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 int 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 int newDefaultSubId = (Integer)(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 Integer newDefaultSubIdObj = new Integer(intent.getIntExtra( 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(int 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, int 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 350 if (events != PhoneStateListener.LISTEN_NONE) { 351 /* Checks permission and throws Security exception */ 352 checkListenerPermission(events); 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 mRecords.add(r); 368 if (DBG) log("listen: add new record"); 369 } 370 371 r.callback = callback; 372 r.pkgForDebug = pkgForDebug; 373 r.callerUid = callerUid; 374 // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID, 375 // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID 376 if (!SubscriptionManager.isValidSubId(subId)) { 377 r.subId = SubscriptionManager.DEFAULT_SUB_ID; 378 } else {//APP specify subID 379 r.subId = subId; 380 } 381 r.phoneId = SubscriptionManager.getPhoneId(r.subId); 382 383 int phoneId = r.phoneId; 384 r.events = events; 385 if (DBG) { 386 log("listen: Register 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 if(DBG) log("listen: Unregister"); 507 remove(callback.asBinder()); 508 } 509 } 510 511 private void remove(IBinder binder) { 512 synchronized (mRecords) { 513 final int recordCount = mRecords.size(); 514 for (int i = 0; i < recordCount; i++) { 515 if (mRecords.get(i).binder == binder) { 516 mRecords.remove(i); 517 return; 518 } 519 } 520 } 521 } 522 523 public void notifyCallState(int state, String incomingNumber) { 524 if (!checkNotifyPermission("notifyCallState()")) { 525 return; 526 } 527 528 if (VDBG) { 529 log("notifyCallState: state=" + state + " incomingNumber=" + incomingNumber); 530 } 531 532 synchronized (mRecords) { 533 for (Record r : mRecords) { 534 if (((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) && 535 (r.subId == SubscriptionManager.DEFAULT_SUB_ID)) { 536 try { 537 r.callback.onCallStateChanged(state, incomingNumber); 538 } catch (RemoteException ex) { 539 mRemoveList.add(r.binder); 540 } 541 } 542 } 543 handleRemoveListLocked(); 544 } 545 broadcastCallStateChanged(state, incomingNumber, SubscriptionManager.DEFAULT_SUB_ID); 546 } 547 548 public void notifyCallStateForSubscriber(int subId, int state, String incomingNumber) { 549 if (!checkNotifyPermission("notifyCallState()")) { 550 return; 551 } 552 if (VDBG) { 553 log("notifyCallStateForSubscriber: subId=" + subId 554 + " state=" + state + " incomingNumber=" + incomingNumber); 555 } 556 synchronized (mRecords) { 557 int phoneId = SubscriptionManager.getPhoneId(subId); 558 if (validatePhoneId(phoneId)) { 559 mCallState[phoneId] = state; 560 mCallIncomingNumber[phoneId] = incomingNumber; 561 for (Record r : mRecords) { 562 if (((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) && 563 (r.subId == subId) && 564 (r.subId != SubscriptionManager.DEFAULT_SUB_ID)) { 565 try { 566 r.callback.onCallStateChanged(state, incomingNumber); 567 } catch (RemoteException ex) { 568 mRemoveList.add(r.binder); 569 } 570 } 571 } 572 } 573 handleRemoveListLocked(); 574 } 575 broadcastCallStateChanged(state, incomingNumber, subId); 576 } 577 578 public void notifyServiceStateForPhoneId(int phoneId, int subId, ServiceState state) { 579 if (!checkNotifyPermission("notifyServiceState()")){ 580 return; 581 } 582 583 synchronized (mRecords) { 584 if (VDBG) { 585 log("notifyServiceStateForSubscriber: subId=" + subId + " phoneId=" + phoneId 586 + " state=" + state); 587 } 588 if (validatePhoneId(phoneId)) { 589 mServiceState[phoneId] = state; 590 logServiceStateChanged("notifyServiceStateForSubscriber", subId, phoneId, state); 591 if (VDBG) toStringLogSSC("notifyServiceStateForSubscriber"); 592 593 for (Record r : mRecords) { 594 if (VDBG) { 595 log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId 596 + " phoneId=" + phoneId + " state=" + state); 597 } 598 if (((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) && 599 subIdMatch(r.subId, subId)) { 600 try { 601 if (DBG) { 602 log("notifyServiceStateForSubscriber: callback.onSSC r=" + r 603 + " subId=" + subId + " phoneId=" + phoneId 604 + " state=" + state); 605 } 606 r.callback.onServiceStateChanged(new ServiceState(state)); 607 } catch (RemoteException ex) { 608 mRemoveList.add(r.binder); 609 } 610 } 611 } 612 } else { 613 log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId); 614 } 615 handleRemoveListLocked(); 616 } 617 broadcastServiceStateChanged(state, subId); 618 } 619 620 public void notifySignalStrength(SignalStrength signalStrength) { 621 notifySignalStrengthForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, signalStrength); 622 } 623 624 public void notifySignalStrengthForSubscriber(int subId, SignalStrength signalStrength) { 625 if (!checkNotifyPermission("notifySignalStrength()")) { 626 return; 627 } 628 if (VDBG) { 629 log("notifySignalStrengthForSubscriber: subId=" + subId 630 + " signalStrength=" + signalStrength); 631 toStringLogSSC("notifySignalStrengthForSubscriber"); 632 } 633 synchronized (mRecords) { 634 int phoneId = SubscriptionManager.getPhoneId(subId); 635 if (validatePhoneId(phoneId)) { 636 if (VDBG) log("notifySignalStrengthForSubscriber: valid phoneId=" + phoneId); 637 mSignalStrength[phoneId] = signalStrength; 638 for (Record r : mRecords) { 639 if (VDBG) { 640 log("notifySignalStrengthForSubscriber: r=" + r + " subId=" + subId 641 + " phoneId=" + phoneId + " ss=" + signalStrength); 642 } 643 if (((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) && 644 subIdMatch(r.subId, subId)) { 645 try { 646 if (DBG) { 647 log("notifySignalStrengthForSubscriber: callback.onSsS r=" + r 648 + " subId=" + subId + " phoneId=" + phoneId 649 + " ss=" + signalStrength); 650 } 651 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); 652 } catch (RemoteException ex) { 653 mRemoveList.add(r.binder); 654 } 655 } 656 if (((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) && 657 subIdMatch(r.subId, subId)){ 658 try { 659 int gsmSignalStrength = signalStrength.getGsmSignalStrength(); 660 int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); 661 if (DBG) { 662 log("notifySignalStrengthForSubscriber: callback.onSS r=" + r 663 + " subId=" + subId + " phoneId=" + phoneId 664 + " gsmSS=" + gsmSignalStrength + " ss=" + ss); 665 } 666 r.callback.onSignalStrengthChanged(ss); 667 } catch (RemoteException ex) { 668 mRemoveList.add(r.binder); 669 } 670 } 671 } 672 } else { 673 log("notifySignalStrengthForSubscriber: invalid phoneId=" + phoneId); 674 } 675 handleRemoveListLocked(); 676 } 677 broadcastSignalStrengthChanged(signalStrength, subId); 678 } 679 680 public void notifyCellInfo(List<CellInfo> cellInfo) { 681 notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cellInfo); 682 } 683 684 public void notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo) { 685 if (!checkNotifyPermission("notifyCellInfo()")) { 686 return; 687 } 688 if (VDBG) { 689 log("notifyCellInfoForSubscriber: subId=" + subId 690 + " cellInfo=" + cellInfo); 691 } 692 693 synchronized (mRecords) { 694 int phoneId = SubscriptionManager.getPhoneId(subId); 695 if (validatePhoneId(phoneId)) { 696 mCellInfo.set(phoneId, cellInfo); 697 for (Record r : mRecords) { 698 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) && 699 subIdMatch(r.subId, subId)) { 700 try { 701 if (DBG_LOC) { 702 log("notifyCellInfo: mCellInfo=" + cellInfo + " r=" + r); 703 } 704 r.callback.onCellInfoChanged(cellInfo); 705 } catch (RemoteException ex) { 706 mRemoveList.add(r.binder); 707 } 708 } 709 } 710 } 711 handleRemoveListLocked(); 712 } 713 } 714 715 public void notifyDataConnectionRealTimeInfo(DataConnectionRealTimeInfo dcRtInfo) { 716 if (!checkNotifyPermission("notifyDataConnectionRealTimeInfo()")) { 717 return; 718 } 719 720 synchronized (mRecords) { 721 mDcRtInfo = dcRtInfo; 722 for (Record r : mRecords) { 723 if (validateEventsAndUserLocked(r, 724 PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO)) { 725 try { 726 if (DBG_LOC) { 727 log("notifyDataConnectionRealTimeInfo: mDcRtInfo=" 728 + mDcRtInfo + " r=" + r); 729 } 730 r.callback.onDataConnectionRealTimeInfoChanged(mDcRtInfo); 731 } catch (RemoteException ex) { 732 mRemoveList.add(r.binder); 733 } 734 } 735 } 736 handleRemoveListLocked(); 737 } 738 } 739 740 @Override 741 public void notifyMessageWaitingChangedForPhoneId(int phoneId, int subId, boolean mwi) { 742 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) { 743 return; 744 } 745 if (VDBG) { 746 log("notifyMessageWaitingChangedForSubscriberPhoneID: subId=" + phoneId 747 + " mwi=" + mwi); 748 } 749 synchronized (mRecords) { 750 if (validatePhoneId(phoneId)) { 751 mMessageWaiting[phoneId] = mwi; 752 for (Record r : mRecords) { 753 if (((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) && 754 subIdMatch(r.subId, subId)) { 755 try { 756 r.callback.onMessageWaitingIndicatorChanged(mwi); 757 } catch (RemoteException ex) { 758 mRemoveList.add(r.binder); 759 } 760 } 761 } 762 } 763 handleRemoveListLocked(); 764 } 765 } 766 767 public void notifyCallForwardingChanged(boolean cfi) { 768 notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cfi); 769 } 770 771 public void notifyCallForwardingChangedForSubscriber(int subId, boolean cfi) { 772 if (!checkNotifyPermission("notifyCallForwardingChanged()")) { 773 return; 774 } 775 if (VDBG) { 776 log("notifyCallForwardingChangedForSubscriber: subId=" + subId 777 + " cfi=" + cfi); 778 } 779 synchronized (mRecords) { 780 int phoneId = SubscriptionManager.getPhoneId(subId); 781 if (validatePhoneId(phoneId)) { 782 mCallForwarding[phoneId] = cfi; 783 for (Record r : mRecords) { 784 if (((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) && 785 subIdMatch(r.subId, subId)) { 786 try { 787 r.callback.onCallForwardingIndicatorChanged(cfi); 788 } catch (RemoteException ex) { 789 mRemoveList.add(r.binder); 790 } 791 } 792 } 793 } 794 handleRemoveListLocked(); 795 } 796 } 797 798 public void notifyDataActivity(int state) { 799 notifyDataActivityForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, state); 800 } 801 802 public void notifyDataActivityForSubscriber(int subId, int state) { 803 if (!checkNotifyPermission("notifyDataActivity()" )) { 804 return; 805 } 806 synchronized (mRecords) { 807 int phoneId = SubscriptionManager.getPhoneId(subId); 808 mDataActivity[phoneId] = state; 809 for (Record r : mRecords) { 810 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) { 811 try { 812 r.callback.onDataActivity(state); 813 } catch (RemoteException ex) { 814 mRemoveList.add(r.binder); 815 } 816 } 817 } 818 handleRemoveListLocked(); 819 } 820 } 821 822 public void notifyDataConnection(int state, boolean isDataConnectivityPossible, 823 String reason, String apn, String apnType, LinkProperties linkProperties, 824 NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { 825 notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, state, 826 isDataConnectivityPossible,reason, apn, apnType, linkProperties, 827 networkCapabilities, networkType, roaming); 828 } 829 830 public void notifyDataConnectionForSubscriber(int subId, int state, 831 boolean isDataConnectivityPossible, String reason, String apn, String apnType, 832 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 833 int networkType, boolean roaming) { 834 if (!checkNotifyPermission("notifyDataConnection()" )) { 835 return; 836 } 837 if (VDBG) { 838 log("notifyDataConnectionForSubscriber: subId=" + subId 839 + " state=" + state + " isDataConnectivityPossible=" + isDataConnectivityPossible 840 + " reason='" + reason 841 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType 842 + " mRecords.size()=" + mRecords.size() + " mRecords=" + mRecords); 843 } 844 synchronized (mRecords) { 845 int phoneId = SubscriptionManager.getPhoneId(subId); 846 boolean modified = false; 847 if (state == TelephonyManager.DATA_CONNECTED) { 848 if (!mConnectedApns.contains(apnType)) { 849 mConnectedApns.add(apnType); 850 if (mDataConnectionState[phoneId] != state) { 851 mDataConnectionState[phoneId] = state; 852 modified = true; 853 } 854 } 855 } else { 856 if (mConnectedApns.remove(apnType)) { 857 if (mConnectedApns.isEmpty()) { 858 mDataConnectionState[phoneId] = state; 859 modified = true; 860 } else { 861 // leave mDataConnectionState as is and 862 // send out the new status for the APN in question. 863 } 864 } 865 } 866 mDataConnectionPossible[phoneId] = isDataConnectivityPossible; 867 mDataConnectionReason[phoneId] = reason; 868 mDataConnectionLinkProperties[phoneId] = linkProperties; 869 mDataConnectionNetworkCapabilities[phoneId] = networkCapabilities; 870 if (mDataConnectionNetworkType[phoneId] != networkType) { 871 mDataConnectionNetworkType[phoneId] = networkType; 872 // need to tell registered listeners about the new network type 873 modified = true; 874 } 875 if (modified) { 876 if (DBG) { 877 log("onDataConnectionStateChanged(" + mDataConnectionState[phoneId] 878 + ", " + mDataConnectionNetworkType[phoneId] + ")"); 879 } 880 for (Record r : mRecords) { 881 if (((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) && 882 subIdMatch(r.subId, subId)) { 883 try { 884 log("Notify data connection state changed on sub: " + 885 subId); 886 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], 887 mDataConnectionNetworkType[phoneId]); 888 } catch (RemoteException ex) { 889 mRemoveList.add(r.binder); 890 } 891 } 892 } 893 handleRemoveListLocked(); 894 } 895 mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType, 896 apnType, apn, reason, linkProperties, ""); 897 for (Record r : mRecords) { 898 if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { 899 try { 900 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 901 } catch (RemoteException ex) { 902 mRemoveList.add(r.binder); 903 } 904 } 905 } 906 handleRemoveListLocked(); 907 } 908 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn, 909 apnType, linkProperties, networkCapabilities, roaming, subId); 910 broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, reason, 911 linkProperties, ""); 912 } 913 914 public void notifyDataConnectionFailed(String reason, String apnType) { 915 notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, 916 reason, apnType); 917 } 918 919 public void notifyDataConnectionFailedForSubscriber(int subId, 920 String reason, String apnType) { 921 if (!checkNotifyPermission("notifyDataConnectionFailed()")) { 922 return; 923 } 924 if (VDBG) { 925 log("notifyDataConnectionFailedForSubscriber: subId=" + subId 926 + " reason=" + reason + " apnType=" + apnType); 927 } 928 synchronized (mRecords) { 929 mPreciseDataConnectionState = new PreciseDataConnectionState( 930 TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN, 931 apnType, "", reason, null, ""); 932 for (Record r : mRecords) { 933 if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { 934 try { 935 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 936 } catch (RemoteException ex) { 937 mRemoveList.add(r.binder); 938 } 939 } 940 } 941 handleRemoveListLocked(); 942 } 943 broadcastDataConnectionFailed(reason, apnType, subId); 944 broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN, 945 TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", reason, null, ""); 946 } 947 948 public void notifyCellLocation(Bundle cellLocation) { 949 notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cellLocation); 950 } 951 952 public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) { 953 log("notifyCellLocationForSubscriber: subId=" + subId 954 + " cellLocation=" + cellLocation); 955 if (!checkNotifyPermission("notifyCellLocation()")) { 956 return; 957 } 958 if (VDBG) { 959 log("notifyCellLocationForSubscriber: subId=" + subId 960 + " cellLocation=" + cellLocation); 961 } 962 synchronized (mRecords) { 963 int phoneId = SubscriptionManager.getPhoneId(subId); 964 if (validatePhoneId(phoneId)) { 965 mCellLocation[phoneId] = cellLocation; 966 for (Record r : mRecords) { 967 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) && 968 subIdMatch(r.subId, subId)) { 969 try { 970 if (DBG_LOC) { 971 log("notifyCellLocation: cellLocation=" + cellLocation 972 + " r=" + r); 973 } 974 r.callback.onCellLocationChanged(new Bundle(cellLocation)); 975 } catch (RemoteException ex) { 976 mRemoveList.add(r.binder); 977 } 978 } 979 } 980 } 981 handleRemoveListLocked(); 982 } 983 } 984 985 public void notifyOtaspChanged(int otaspMode) { 986 if (!checkNotifyPermission("notifyOtaspChanged()" )) { 987 return; 988 } 989 synchronized (mRecords) { 990 mOtaspMode = otaspMode; 991 for (Record r : mRecords) { 992 if ((r.events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) { 993 try { 994 r.callback.onOtaspChanged(otaspMode); 995 } catch (RemoteException ex) { 996 mRemoveList.add(r.binder); 997 } 998 } 999 } 1000 handleRemoveListLocked(); 1001 } 1002 } 1003 1004 public void notifyPreciseCallState(int ringingCallState, int foregroundCallState, 1005 int backgroundCallState) { 1006 if (!checkNotifyPermission("notifyPreciseCallState()")) { 1007 return; 1008 } 1009 synchronized (mRecords) { 1010 mRingingCallState = ringingCallState; 1011 mForegroundCallState = foregroundCallState; 1012 mBackgroundCallState = backgroundCallState; 1013 mPreciseCallState = new PreciseCallState(ringingCallState, foregroundCallState, 1014 backgroundCallState, 1015 DisconnectCause.NOT_VALID, 1016 PreciseDisconnectCause.NOT_VALID); 1017 for (Record r : mRecords) { 1018 if ((r.events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) { 1019 try { 1020 r.callback.onPreciseCallStateChanged(mPreciseCallState); 1021 } catch (RemoteException ex) { 1022 mRemoveList.add(r.binder); 1023 } 1024 } 1025 } 1026 handleRemoveListLocked(); 1027 } 1028 broadcastPreciseCallStateChanged(ringingCallState, foregroundCallState, backgroundCallState, 1029 DisconnectCause.NOT_VALID, 1030 PreciseDisconnectCause.NOT_VALID); 1031 } 1032 1033 public void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause) { 1034 if (!checkNotifyPermission("notifyDisconnectCause()")) { 1035 return; 1036 } 1037 synchronized (mRecords) { 1038 mPreciseCallState = new PreciseCallState(mRingingCallState, mForegroundCallState, 1039 mBackgroundCallState, disconnectCause, preciseDisconnectCause); 1040 for (Record r : mRecords) { 1041 if ((r.events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) { 1042 try { 1043 r.callback.onPreciseCallStateChanged(mPreciseCallState); 1044 } catch (RemoteException ex) { 1045 mRemoveList.add(r.binder); 1046 } 1047 } 1048 } 1049 handleRemoveListLocked(); 1050 } 1051 broadcastPreciseCallStateChanged(mRingingCallState, mForegroundCallState, 1052 mBackgroundCallState, disconnectCause, preciseDisconnectCause); 1053 } 1054 1055 public void notifyPreciseDataConnectionFailed(String reason, String apnType, 1056 String apn, String failCause) { 1057 if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) { 1058 return; 1059 } 1060 synchronized (mRecords) { 1061 mPreciseDataConnectionState = new PreciseDataConnectionState( 1062 TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN, 1063 apnType, apn, reason, null, failCause); 1064 for (Record r : mRecords) { 1065 if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { 1066 try { 1067 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 1068 } catch (RemoteException ex) { 1069 mRemoveList.add(r.binder); 1070 } 1071 } 1072 } 1073 handleRemoveListLocked(); 1074 } 1075 broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN, 1076 TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause); 1077 } 1078 1079 public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) { 1080 if (!checkNotifyPermission("notifyVoLteServiceStateChanged()")) { 1081 return; 1082 } 1083 synchronized (mRecords) { 1084 mVoLteServiceState = lteState; 1085 for (Record r : mRecords) { 1086 if ((r.events & PhoneStateListener.LISTEN_VOLTE_STATE) != 0) { 1087 try { 1088 r.callback.onVoLteServiceStateChanged( 1089 new VoLteServiceState(mVoLteServiceState)); 1090 } catch (RemoteException ex) { 1091 mRemoveList.add(r.binder); 1092 } 1093 } 1094 } 1095 handleRemoveListLocked(); 1096 } 1097 } 1098 1099 public void notifyOemHookRawEventForSubscriber(int subId, byte[] rawData) { 1100 if (!checkNotifyPermission("notifyOemHookRawEventForSubscriber")) { 1101 return; 1102 } 1103 1104 synchronized (mRecords) { 1105 for (Record r : mRecords) { 1106 if (VDBG) { 1107 log("notifyOemHookRawEventForSubscriber: r=" + r + " subId=" + subId); 1108 } 1109 if (((r.events & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) && 1110 ((r.subId == subId) || 1111 (r.subId == SubscriptionManager.DEFAULT_SUB_ID))) { 1112 try { 1113 r.callback.onOemHookRawEvent(rawData); 1114 } catch (RemoteException ex) { 1115 mRemoveList.add(r.binder); 1116 } 1117 } 1118 } 1119 handleRemoveListLocked(); 1120 } 1121 } 1122 1123 @Override 1124 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1125 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 1126 != PackageManager.PERMISSION_GRANTED) { 1127 pw.println("Permission Denial: can't dump telephony.registry from from pid=" 1128 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 1129 return; 1130 } 1131 synchronized (mRecords) { 1132 final int recordCount = mRecords.size(); 1133 pw.println("last known state:"); 1134 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 1135 pw.println(" Phone Id=" + i); 1136 pw.println(" mCallState=" + mCallState[i]); 1137 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber[i]); 1138 pw.println(" mServiceState=" + mServiceState[i]); 1139 pw.println(" mSignalStrength=" + mSignalStrength[i]); 1140 pw.println(" mMessageWaiting=" + mMessageWaiting[i]); 1141 pw.println(" mCallForwarding=" + mCallForwarding[i]); 1142 pw.println(" mDataActivity=" + mDataActivity[i]); 1143 pw.println(" mDataConnectionState=" + mDataConnectionState[i]); 1144 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible[i]); 1145 pw.println(" mDataConnectionReason=" + mDataConnectionReason[i]); 1146 pw.println(" mDataConnectionApn=" + mDataConnectionApn[i]); 1147 pw.println(" mDataConnectionLinkProperties=" + mDataConnectionLinkProperties[i]); 1148 pw.println(" mDataConnectionNetworkCapabilities=" + 1149 mDataConnectionNetworkCapabilities[i]); 1150 pw.println(" mCellLocation=" + mCellLocation[i]); 1151 pw.println(" mCellInfo=" + mCellInfo.get(i)); 1152 } 1153 pw.println(" mDcRtInfo=" + mDcRtInfo); 1154 pw.println("registrations: count=" + recordCount); 1155 for (Record r : mRecords) { 1156 pw.println(" " + r); 1157 } 1158 } 1159 } 1160 1161 // 1162 // the legacy intent broadcasting 1163 // 1164 1165 private void broadcastServiceStateChanged(ServiceState state, int subId) { 1166 long ident = Binder.clearCallingIdentity(); 1167 try { 1168 mBatteryStats.notePhoneState(state.getState()); 1169 } catch (RemoteException re) { 1170 // Can't do much 1171 } finally { 1172 Binder.restoreCallingIdentity(ident); 1173 } 1174 1175 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); 1176 Bundle data = new Bundle(); 1177 state.fillInNotifierBundle(data); 1178 intent.putExtras(data); 1179 // Pass the subscription along with the intent. 1180 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1181 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1182 } 1183 1184 private void broadcastSignalStrengthChanged(SignalStrength signalStrength, int subId) { 1185 long ident = Binder.clearCallingIdentity(); 1186 try { 1187 mBatteryStats.notePhoneSignalStrength(signalStrength); 1188 } catch (RemoteException e) { 1189 /* The remote entity disappeared, we can safely ignore the exception. */ 1190 } finally { 1191 Binder.restoreCallingIdentity(ident); 1192 } 1193 1194 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED); 1195 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1196 Bundle data = new Bundle(); 1197 signalStrength.fillInNotifierBundle(data); 1198 intent.putExtras(data); 1199 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1200 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1201 } 1202 1203 private void broadcastCallStateChanged(int state, String incomingNumber, int subId) { 1204 long ident = Binder.clearCallingIdentity(); 1205 try { 1206 if (state == TelephonyManager.CALL_STATE_IDLE) { 1207 mBatteryStats.notePhoneOff(); 1208 } else { 1209 mBatteryStats.notePhoneOn(); 1210 } 1211 } catch (RemoteException e) { 1212 /* The remote entity disappeared, we can safely ignore the exception. */ 1213 } finally { 1214 Binder.restoreCallingIdentity(ident); 1215 } 1216 1217 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED); 1218 intent.putExtra(PhoneConstants.STATE_KEY, 1219 DefaultPhoneNotifier.convertCallState(state).toString()); 1220 if (!TextUtils.isEmpty(incomingNumber)) { 1221 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber); 1222 } 1223 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1224 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1225 android.Manifest.permission.READ_PHONE_STATE); 1226 } 1227 1228 private void broadcastDataConnectionStateChanged(int state, 1229 boolean isDataConnectivityPossible, 1230 String reason, String apn, String apnType, LinkProperties linkProperties, 1231 NetworkCapabilities networkCapabilities, boolean roaming, int subId) { 1232 // Note: not reporting to the battery stats service here, because the 1233 // status bar takes care of that after taking into account all of the 1234 // required info. 1235 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); 1236 intent.putExtra(PhoneConstants.STATE_KEY, 1237 DefaultPhoneNotifier.convertDataState(state).toString()); 1238 if (!isDataConnectivityPossible) { 1239 intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true); 1240 } 1241 if (reason != null) { 1242 intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); 1243 } 1244 if (linkProperties != null) { 1245 intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties); 1246 String iface = linkProperties.getInterfaceName(); 1247 if (iface != null) { 1248 intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface); 1249 } 1250 } 1251 if (networkCapabilities != null) { 1252 intent.putExtra(PhoneConstants.DATA_NETWORK_CAPABILITIES_KEY, networkCapabilities); 1253 } 1254 if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true); 1255 1256 intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); 1257 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1258 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1259 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1260 } 1261 1262 private void broadcastDataConnectionFailed(String reason, String apnType, 1263 int subId) { 1264 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED); 1265 intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason); 1266 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1267 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1268 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1269 } 1270 1271 private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState, 1272 int backgroundCallState, int disconnectCause, int preciseDisconnectCause) { 1273 Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED); 1274 intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState); 1275 intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState); 1276 intent.putExtra(TelephonyManager.EXTRA_BACKGROUND_CALL_STATE, backgroundCallState); 1277 intent.putExtra(TelephonyManager.EXTRA_DISCONNECT_CAUSE, disconnectCause); 1278 intent.putExtra(TelephonyManager.EXTRA_PRECISE_DISCONNECT_CAUSE, preciseDisconnectCause); 1279 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1280 android.Manifest.permission.READ_PRECISE_PHONE_STATE); 1281 } 1282 1283 private void broadcastPreciseDataConnectionStateChanged(int state, int networkType, 1284 String apnType, String apn, String reason, LinkProperties linkProperties, String failCause) { 1285 Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED); 1286 intent.putExtra(PhoneConstants.STATE_KEY, state); 1287 intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType); 1288 if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); 1289 if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1290 if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); 1291 if (linkProperties != null) intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties); 1292 if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause); 1293 1294 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1295 android.Manifest.permission.READ_PRECISE_PHONE_STATE); 1296 } 1297 1298 private boolean checkNotifyPermission(String method) { 1299 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) 1300 == PackageManager.PERMISSION_GRANTED) { 1301 return true; 1302 } 1303 String msg = "Modify Phone State Permission Denial: " + method + " from pid=" 1304 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid(); 1305 if (DBG) log(msg); 1306 return false; 1307 } 1308 1309 private void checkListenerPermission(int events) { 1310 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { 1311 mContext.enforceCallingOrSelfPermission( 1312 android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 1313 1314 } 1315 1316 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) { 1317 mContext.enforceCallingOrSelfPermission( 1318 android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 1319 1320 } 1321 1322 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) { 1323 mContext.enforceCallingOrSelfPermission( 1324 android.Manifest.permission.READ_PHONE_STATE, null); 1325 } 1326 1327 if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) { 1328 mContext.enforceCallingOrSelfPermission( 1329 android.Manifest.permission.READ_PRECISE_PHONE_STATE, null); 1330 1331 } 1332 1333 if ((events & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) { 1334 mContext.enforceCallingOrSelfPermission( 1335 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); 1336 } 1337 } 1338 1339 private void handleRemoveListLocked() { 1340 if (mRemoveList.size() > 0) { 1341 for (IBinder b: mRemoveList) { 1342 remove(b); 1343 } 1344 mRemoveList.clear(); 1345 } 1346 } 1347 1348 private boolean validateEventsAndUserLocked(Record r, int events) { 1349 int foregroundUser; 1350 long callingIdentity = Binder.clearCallingIdentity(); 1351 boolean valid = false; 1352 try { 1353 foregroundUser = ActivityManager.getCurrentUser(); 1354 valid = r.callerUid == foregroundUser && (r.events & events) != 0; 1355 if (DBG | DBG_LOC) { 1356 log("validateEventsAndUserLocked: valid=" + valid 1357 + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser 1358 + " r.events=" + r.events + " events=" + events); 1359 } 1360 } finally { 1361 Binder.restoreCallingIdentity(callingIdentity); 1362 } 1363 return valid; 1364 } 1365 1366 private boolean validatePhoneId(int phoneId) { 1367 boolean valid = (phoneId >= 0) && (phoneId < mNumPhones); 1368 if (VDBG) log("validatePhoneId: " + valid); 1369 return valid; 1370 } 1371 1372 private static void log(String s) { 1373 Rlog.d(TAG, s); 1374 } 1375 1376 private static class LogSSC { 1377 private Time mTime; 1378 private String mS; 1379 private int mSubId; 1380 private int mPhoneId; 1381 private ServiceState mState; 1382 1383 public void set(Time t, String s, int subId, int phoneId, ServiceState state) { 1384 mTime = t; mS = s; mSubId = subId; mPhoneId = phoneId; mState = state; 1385 } 1386 1387 @Override 1388 public String toString() { 1389 return mS + " " + mTime.toString() + " " + mSubId + " " + mPhoneId + " " + mState; 1390 } 1391 } 1392 1393 private LogSSC logSSC [] = new LogSSC[10]; 1394 private int next = 0; 1395 1396 private void logServiceStateChanged(String s, int subId, int phoneId, ServiceState state) { 1397 if (logSSC == null || logSSC.length == 0) { 1398 return; 1399 } 1400 if (logSSC[next] == null) { 1401 logSSC[next] = new LogSSC(); 1402 } 1403 Time t = new Time(); 1404 t.setToNow(); 1405 logSSC[next].set(t, s, subId, phoneId, state); 1406 if (++next >= logSSC.length) { 1407 next = 0; 1408 } 1409 } 1410 1411 private void toStringLogSSC(String prompt) { 1412 if (logSSC == null || logSSC.length == 0 || (next == 0 && logSSC[next] == null)) { 1413 log(prompt + ": logSSC is empty"); 1414 } else { 1415 // There is at least one element 1416 log(prompt + ": logSSC.length=" + logSSC.length + " next=" + next); 1417 int i = next; 1418 if (logSSC[i] == null) { 1419 // logSSC is not full so back to the beginning 1420 i = 0; 1421 } 1422 do { 1423 log(logSSC[i].toString()); 1424 if (++i >= logSSC.length) { 1425 i = 0; 1426 } 1427 } while (i != next); 1428 log(prompt + ": ----------------"); 1429 } 1430 } 1431 1432 boolean subIdMatch(int rSubId, int subId) { 1433 if(rSubId == SubscriptionManager.DEFAULT_SUB_ID) { 1434 return (subId == mDefaultSubId); 1435 } else { 1436 return (rSubId == subId); 1437 } 1438 } 1439 1440 private void checkPossibleMissNotify(Record r, int phoneId) { 1441 int events = r.events; 1442 1443 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { 1444 try { 1445 if (VDBG) log("checkPossibleMissNotify: onServiceStateChanged state=" + 1446 mServiceState[phoneId]); 1447 r.callback.onServiceStateChanged( 1448 new ServiceState(mServiceState[phoneId])); 1449 } catch (RemoteException ex) { 1450 mRemoveList.add(r.binder); 1451 } 1452 } 1453 1454 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { 1455 try { 1456 SignalStrength signalStrength = mSignalStrength[phoneId]; 1457 if (DBG) { 1458 log("checkPossibleMissNotify: onSignalStrengthsChanged SS=" + signalStrength); 1459 } 1460 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); 1461 } catch (RemoteException ex) { 1462 mRemoveList.add(r.binder); 1463 } 1464 } 1465 1466 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { 1467 try { 1468 int gsmSignalStrength = mSignalStrength[phoneId] 1469 .getGsmSignalStrength(); 1470 if (DBG) { 1471 log("checkPossibleMissNotify: onSignalStrengthChanged SS=" + 1472 gsmSignalStrength); 1473 } 1474 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 1475 : gsmSignalStrength)); 1476 } catch (RemoteException ex) { 1477 mRemoveList.add(r.binder); 1478 } 1479 } 1480 1481 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) { 1482 try { 1483 if (DBG_LOC) { 1484 log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = " 1485 + mCellInfo.get(phoneId)); 1486 } 1487 r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); 1488 } catch (RemoteException ex) { 1489 mRemoveList.add(r.binder); 1490 } 1491 } 1492 1493 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { 1494 try { 1495 if (VDBG) { 1496 log("checkPossibleMissNotify: onMessageWaitingIndicatorChanged phoneId=" 1497 + phoneId + " mwi=" + mMessageWaiting[phoneId]); 1498 } 1499 r.callback.onMessageWaitingIndicatorChanged( 1500 mMessageWaiting[phoneId]); 1501 } catch (RemoteException ex) { 1502 mRemoveList.add(r.binder); 1503 } 1504 } 1505 1506 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { 1507 try { 1508 if (VDBG) { 1509 log("checkPossibleMissNotify: onCallForwardingIndicatorChanged phoneId=" 1510 + phoneId + " cfi=" + mCallForwarding[phoneId]); 1511 } 1512 r.callback.onCallForwardingIndicatorChanged( 1513 mCallForwarding[phoneId]); 1514 } catch (RemoteException ex) { 1515 mRemoveList.add(r.binder); 1516 } 1517 } 1518 1519 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { 1520 try { 1521 if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = " 1522 + mCellLocation[phoneId]); 1523 r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId])); 1524 } catch (RemoteException ex) { 1525 mRemoveList.add(r.binder); 1526 } 1527 } 1528 1529 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { 1530 try { 1531 if (DBG) { 1532 log("checkPossibleMissNotify: onDataConnectionStateChanged(mDataConnectionState" 1533 + "=" + mDataConnectionState[phoneId] 1534 + ", mDataConnectionNetworkType=" + mDataConnectionNetworkType[phoneId] 1535 + ")"); 1536 } 1537 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], 1538 mDataConnectionNetworkType[phoneId]); 1539 } catch (RemoteException ex) { 1540 mRemoveList.add(r.binder); 1541 } 1542 } 1543 } 1544} 1545