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