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