TelephonyRegistry.java revision f4cd25b2c867ad74f983f1bacae3925005685a69
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; 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 log("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 log("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 log("mBroadcastReceiver: action=" + action); 210 if (Intent.ACTION_USER_SWITCHED.equals(action)) { 211 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 212 if (DBG) log("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) log("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) log("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 log("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 (true /*VDBG*/) { 312 log("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 (true/*DBG*/) log("listen: DEFAULT_SUB_ID"); 351 } 352 mRecords.add(r); 353 if (true/*DBG*/) log("listen: add new record"); 354 } 355 int phoneId = SubscriptionManager.getPhoneId(subId); 356 r.events = events; 357 if (true/*DBG*/) log("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) log("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) log("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 (true /*VDBG*/) { 516 log("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 log("notifyServiceStateUsingSubId: using mDefaultSubId=" + mDefaultSubId); 552 } 553 if (true/*VDBG*/) { 554 log("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 // log("notifyServiceStateUsingSubId: r.events=0x" + Integer.toHexString(r.events) + " r.subId=" + r.subId + " subId=" + subId + " state=" + state); 563 // FIXME: use DEFAULT_SUB_ID instead?? 564 if (((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) && 565 (r.subId == subId)) { 566 try { 567 log("notifyServiceStateUsingSubId: call onSSC subId=" + subId 568 + " state=" + state); 569 r.callback.onServiceStateChanged(new ServiceState(state)); 570 } catch (RemoteException ex) { 571 mRemoveList.add(r.binder); 572 } 573 } 574 } 575 } else { 576 log("notifyServiceStateUsingSubId: INVALID phoneId=" + phoneId); 577 } 578 handleRemoveListLocked(); 579 } 580 broadcastServiceStateChanged(state, subId); 581 } 582 583 public void notifySignalStrength(SignalStrength signalStrength) { 584 notifySignalStrengthUsingSubId(mDefaultSubId, signalStrength); 585 } 586 587 public void notifySignalStrengthUsingSubId(long subId, SignalStrength signalStrength) { 588 if (!checkNotifyPermission("notifySignalStrength()")) { 589 return; 590 } 591 if (true/*VDBG*/) { 592 log("notifySignalStrengthUsingSubId: subId=" + subId 593 + " signalStrength=" + signalStrength); 594 } 595 synchronized (mRecords) { 596 int phoneId = SubscriptionManager.getPhoneId(subId); 597 if (validatePhoneId(phoneId)) { 598 log("notifySignalStrengthUsingSubId: valid phoneId=" + phoneId); 599 mSignalStrength[phoneId] = signalStrength; 600 for (Record r : mRecords) { 601 //log("notifySignalStrengthUsingSubId: r.events=0x" + Integer.toHexString(r.events) + " r.subId=" + r.subId + " subId=" + subId); 602 if (((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) && 603 (r.subId == subId)){ 604 try { 605 log("notifySignalStrengthUsingSubId: callback.onSsS ss=" + signalStrength); 606 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); 607 } catch (RemoteException ex) { 608 mRemoveList.add(r.binder); 609 } 610 } 611 if (((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) && 612 (r.subId == subId)) { 613 try { 614 int gsmSignalStrength = signalStrength.getGsmSignalStrength(); 615 int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); 616 log("notifySignalStrengthUsingSubId: callback.onSS gsmSS=" + gsmSignalStrength + " ss=" + ss); 617 r.callback.onSignalStrengthChanged(ss); 618 } catch (RemoteException ex) { 619 mRemoveList.add(r.binder); 620 } 621 } 622 } 623 } else { 624 log("notifySignalStrengthUsingSubId: invalid phoneId=" + phoneId); 625 } 626 handleRemoveListLocked(); 627 } 628 broadcastSignalStrengthChanged(signalStrength, subId); 629 } 630 631 public void notifyCellInfo(List<CellInfo> cellInfo) { 632 notifyCellInfoUsingSubId(mDefaultSubId, cellInfo); 633 } 634 635 public void notifyCellInfoUsingSubId(long subId, List<CellInfo> cellInfo) { 636 if (!checkNotifyPermission("notifyCellInfo()")) { 637 return; 638 } 639 if (VDBG) { 640 log("notifyCellInfoUsingSubId: subId=" + subId 641 + " cellInfo=" + cellInfo); 642 } 643 644 synchronized (mRecords) { 645 int phoneId = SubscriptionManager.getPhoneId(subId); 646 if (validatePhoneId(phoneId)) { 647 mCellInfo.set(phoneId, cellInfo); 648 for (Record r : mRecords) { 649 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) 650 && r.subId == subId) { 651 try { 652 if (DBG_LOC) { 653 log("notifyCellInfo: mCellInfo=" + cellInfo + " r=" + r); 654 } 655 r.callback.onCellInfoChanged(cellInfo); 656 } catch (RemoteException ex) { 657 mRemoveList.add(r.binder); 658 } 659 } 660 } 661 } 662 handleRemoveListLocked(); 663 } 664 } 665 666 public void notifyDataConnectionRealTimeInfo(DataConnectionRealTimeInfo dcRtInfo) { 667 if (!checkNotifyPermission("notifyDataConnectionRealTimeInfo()")) { 668 return; 669 } 670 671 synchronized (mRecords) { 672 mDcRtInfo = dcRtInfo; 673 for (Record r : mRecords) { 674 if (validateEventsAndUserLocked(r, 675 PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO)) { 676 try { 677 if (DBG_LOC) { 678 log("notifyDataConnectionRealTimeInfo: mDcRtInfo=" 679 + mDcRtInfo + " r=" + r); 680 } 681 r.callback.onDataConnectionRealTimeInfoChanged(mDcRtInfo); 682 } catch (RemoteException ex) { 683 mRemoveList.add(r.binder); 684 } 685 } 686 } 687 handleRemoveListLocked(); 688 } 689 } 690 691 public void notifyMessageWaitingChanged(boolean mwi) { 692 notifyMessageWaitingChangedUsingSubId(mDefaultSubId, mwi); 693 } 694 695 public void notifyMessageWaitingChangedUsingSubId(long subId, boolean mwi) { 696 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) { 697 return; 698 } 699 if (VDBG) { 700 log("notifyMessageWaitingChangedUsingSubId: subId=" + subId 701 + " mwi=" + mwi); 702 } 703 synchronized (mRecords) { 704 int phoneId = SubscriptionManager.getPhoneId(subId); 705 if (validatePhoneId(phoneId)) { 706 mMessageWaiting[phoneId] = mwi; 707 for (Record r : mRecords) { 708 if (((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) && 709 (r.subId == subId)) { 710 try { 711 r.callback.onMessageWaitingIndicatorChanged(mwi); 712 } catch (RemoteException ex) { 713 mRemoveList.add(r.binder); 714 } 715 } 716 } 717 } 718 handleRemoveListLocked(); 719 } 720 } 721 722 public void notifyCallForwardingChanged(boolean cfi) { 723 notifyCallForwardingChangedUsingSubId(mDefaultSubId, cfi); 724 } 725 726 public void notifyCallForwardingChangedUsingSubId(long subId, boolean cfi) { 727 if (!checkNotifyPermission("notifyCallForwardingChanged()")) { 728 return; 729 } 730 if (VDBG) { 731 log("notifyCallForwardingChangedUsingSubId: subId=" + subId 732 + " cfi=" + cfi); 733 } 734 synchronized (mRecords) { 735 int phoneId = SubscriptionManager.getPhoneId(subId); 736 if (validatePhoneId(phoneId)) { 737 mCallForwarding[phoneId] = cfi; 738 for (Record r : mRecords) { 739 if (((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) && 740 (r.subId == subId)) { 741 try { 742 r.callback.onCallForwardingIndicatorChanged(cfi); 743 } catch (RemoteException ex) { 744 mRemoveList.add(r.binder); 745 } 746 } 747 } 748 } 749 handleRemoveListLocked(); 750 } 751 } 752 753 public void notifyDataActivity(int state) { 754 notifyDataActivityUsingSubId(mDefaultSubId, state); 755 } 756 757 public void notifyDataActivityUsingSubId(long subId, int state) { 758 if (!checkNotifyPermission("notifyDataActivity()" )) { 759 return; 760 } 761 synchronized (mRecords) { 762 int phoneId = SubscriptionManager.getPhoneId(subId); 763 mDataActivity[phoneId] = state; 764 for (Record r : mRecords) { 765 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) { 766 try { 767 r.callback.onDataActivity(state); 768 } catch (RemoteException ex) { 769 mRemoveList.add(r.binder); 770 } 771 } 772 } 773 handleRemoveListLocked(); 774 } 775 } 776 777 public void notifyDataConnection(int state, boolean isDataConnectivityPossible, 778 String reason, String apn, String apnType, LinkProperties linkProperties, 779 NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { 780 notifyDataConnectionUsingSubId(mDefaultSubId, state, isDataConnectivityPossible, 781 reason, apn, apnType, linkProperties, 782 networkCapabilities, networkType, roaming); 783 } 784 785 public void notifyDataConnectionUsingSubId(long subId, int state, 786 boolean isDataConnectivityPossible, String reason, String apn, String apnType, 787 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 788 int networkType, boolean roaming) { 789 if (!checkNotifyPermission("notifyDataConnection()" )) { 790 return; 791 } 792 if (VDBG) { 793 log("notifyDataConnectionUsingSubId: subId=" + subId 794 + " state=" + state + " isDataConnectivityPossible=" + isDataConnectivityPossible 795 + " reason='" + reason 796 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType 797 + " mRecords.size()=" + mRecords.size() + " mRecords=" + mRecords); 798 } 799 synchronized (mRecords) { 800 int phoneId = SubscriptionManager.getPhoneId(subId); 801 boolean modified = false; 802 if (state == TelephonyManager.DATA_CONNECTED) { 803 if (!mConnectedApns.contains(apnType)) { 804 mConnectedApns.add(apnType); 805 if (mDataConnectionState[phoneId] != state) { 806 mDataConnectionState[phoneId] = state; 807 modified = true; 808 } 809 } 810 } else { 811 if (mConnectedApns.remove(apnType)) { 812 if (mConnectedApns.isEmpty()) { 813 mDataConnectionState[phoneId] = state; 814 modified = true; 815 } else { 816 // leave mDataConnectionState as is and 817 // send out the new status for the APN in question. 818 } 819 } 820 } 821 mDataConnectionPossible[phoneId] = isDataConnectivityPossible; 822 mDataConnectionReason[phoneId] = reason; 823 mDataConnectionLinkProperties[phoneId] = linkProperties; 824 mDataConnectionNetworkCapabilities[phoneId] = networkCapabilities; 825 if (mDataConnectionNetworkType[phoneId] != networkType) { 826 mDataConnectionNetworkType[phoneId] = networkType; 827 // need to tell registered listeners about the new network type 828 modified = true; 829 } 830 if (modified) { 831 if (DBG) { 832 log("onDataConnectionStateChanged(" + mDataConnectionState[phoneId] 833 + ", " + mDataConnectionNetworkType[phoneId] + ")"); 834 } 835 for (Record r : mRecords) { 836 if (((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) && 837 (r.subId == subId)) { 838 try { 839 log("Notify data connection state changed on sub: " + 840 subId); 841 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], 842 mDataConnectionNetworkType[phoneId]); 843 } catch (RemoteException ex) { 844 mRemoveList.add(r.binder); 845 } 846 } 847 } 848 handleRemoveListLocked(); 849 } 850 mPreciseDataConnectionState = new PreciseDataConnectionState(state, networkType, 851 apnType, apn, reason, linkProperties, ""); 852 for (Record r : mRecords) { 853 if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { 854 try { 855 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 856 } catch (RemoteException ex) { 857 mRemoveList.add(r.binder); 858 } 859 } 860 } 861 handleRemoveListLocked(); 862 } 863 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn, 864 apnType, linkProperties, networkCapabilities, roaming, subId); 865 broadcastPreciseDataConnectionStateChanged(state, networkType, apnType, apn, reason, 866 linkProperties, ""); 867 } 868 869 public void notifyDataConnectionFailed(String reason, String apnType) { 870 notifyDataConnectionFailedUsingSubId(mDefaultSubId, reason, apnType); 871 } 872 873 public void notifyDataConnectionFailedUsingSubId(long subId, 874 String reason, String apnType) { 875 if (!checkNotifyPermission("notifyDataConnectionFailed()")) { 876 return; 877 } 878 if (VDBG) { 879 log("notifyDataConnectionFailedUsingSubId: subId=" + subId 880 + " reason=" + reason + " apnType=" + apnType); 881 } 882 synchronized (mRecords) { 883 mPreciseDataConnectionState = new PreciseDataConnectionState( 884 TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN, 885 apnType, "", reason, null, ""); 886 for (Record r : mRecords) { 887 if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { 888 try { 889 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 890 } catch (RemoteException ex) { 891 mRemoveList.add(r.binder); 892 } 893 } 894 } 895 handleRemoveListLocked(); 896 } 897 broadcastDataConnectionFailed(reason, apnType, subId); 898 broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN, 899 TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, "", reason, null, ""); 900 } 901 902 public void notifyCellLocation(Bundle cellLocation) { 903 notifyCellLocationUsingSubId(mDefaultSubId, cellLocation); 904 } 905 906 public void notifyCellLocationUsingSubId(long subId, Bundle cellLocation) { 907 log("notifyCellLocationUsingSubId: subId=" + subId 908 + " cellLocation=" + cellLocation); 909 if (!checkNotifyPermission("notifyCellLocation()")) { 910 return; 911 } 912 if (VDBG) { 913 log("notifyCellLocationUsingSubId: subId=" + subId 914 + " cellLocation=" + cellLocation); 915 } 916 synchronized (mRecords) { 917 int phoneId = SubscriptionManager.getPhoneId(subId); 918 if (validatePhoneId(phoneId)) { 919 mCellLocation[phoneId] = cellLocation; 920 for (Record r : mRecords) { 921 if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) 922 && r.subId == subId) { 923 try { 924 if (DBG_LOC) { 925 log("notifyCellLocation: cellLocation=" + cellLocation 926 + " r=" + r); 927 } 928 r.callback.onCellLocationChanged(new Bundle(cellLocation)); 929 } catch (RemoteException ex) { 930 mRemoveList.add(r.binder); 931 } 932 } 933 } 934 } 935 handleRemoveListLocked(); 936 } 937 } 938 939 public void notifyOtaspChanged(int otaspMode) { 940 if (!checkNotifyPermission("notifyOtaspChanged()" )) { 941 return; 942 } 943 synchronized (mRecords) { 944 mOtaspMode = otaspMode; 945 for (Record r : mRecords) { 946 if ((r.events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) { 947 try { 948 r.callback.onOtaspChanged(otaspMode); 949 } catch (RemoteException ex) { 950 mRemoveList.add(r.binder); 951 } 952 } 953 } 954 handleRemoveListLocked(); 955 } 956 } 957 958 public void notifyPreciseCallState(int ringingCallState, int foregroundCallState, 959 int backgroundCallState) { 960 if (!checkNotifyPermission("notifyPreciseCallState()")) { 961 return; 962 } 963 synchronized (mRecords) { 964 mRingingCallState = ringingCallState; 965 mForegroundCallState = foregroundCallState; 966 mBackgroundCallState = backgroundCallState; 967 mPreciseCallState = new PreciseCallState(ringingCallState, foregroundCallState, 968 backgroundCallState, 969 DisconnectCause.NOT_VALID, 970 PreciseDisconnectCause.NOT_VALID); 971 for (Record r : mRecords) { 972 if ((r.events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) { 973 try { 974 r.callback.onPreciseCallStateChanged(mPreciseCallState); 975 } catch (RemoteException ex) { 976 mRemoveList.add(r.binder); 977 } 978 } 979 } 980 handleRemoveListLocked(); 981 } 982 broadcastPreciseCallStateChanged(ringingCallState, foregroundCallState, backgroundCallState, 983 DisconnectCause.NOT_VALID, 984 PreciseDisconnectCause.NOT_VALID); 985 } 986 987 public void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause) { 988 if (!checkNotifyPermission("notifyDisconnectCause()")) { 989 return; 990 } 991 synchronized (mRecords) { 992 mPreciseCallState = new PreciseCallState(mRingingCallState, mForegroundCallState, 993 mBackgroundCallState, disconnectCause, preciseDisconnectCause); 994 for (Record r : mRecords) { 995 if ((r.events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) { 996 try { 997 r.callback.onPreciseCallStateChanged(mPreciseCallState); 998 } catch (RemoteException ex) { 999 mRemoveList.add(r.binder); 1000 } 1001 } 1002 } 1003 handleRemoveListLocked(); 1004 } 1005 broadcastPreciseCallStateChanged(mRingingCallState, mForegroundCallState, 1006 mBackgroundCallState, disconnectCause, preciseDisconnectCause); 1007 } 1008 1009 public void notifyPreciseDataConnectionFailed(String reason, String apnType, 1010 String apn, String failCause) { 1011 if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) { 1012 return; 1013 } 1014 synchronized (mRecords) { 1015 mPreciseDataConnectionState = new PreciseDataConnectionState( 1016 TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN, 1017 apnType, apn, reason, null, failCause); 1018 for (Record r : mRecords) { 1019 if ((r.events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { 1020 try { 1021 r.callback.onPreciseDataConnectionStateChanged(mPreciseDataConnectionState); 1022 } catch (RemoteException ex) { 1023 mRemoveList.add(r.binder); 1024 } 1025 } 1026 } 1027 handleRemoveListLocked(); 1028 } 1029 broadcastPreciseDataConnectionStateChanged(TelephonyManager.DATA_UNKNOWN, 1030 TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause); 1031 } 1032 1033 public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) { 1034 if (!checkNotifyPermission("notifyVoLteServiceStateChanged()")) { 1035 return; 1036 } 1037 synchronized (mRecords) { 1038 mVoLteServiceState = lteState; 1039 for (Record r : mRecords) { 1040 if ((r.events & PhoneStateListener.LISTEN_VOLTE_STATE) != 0) { 1041 try { 1042 r.callback.onVoLteServiceStateChanged( 1043 new VoLteServiceState(mVoLteServiceState)); 1044 } catch (RemoteException ex) { 1045 mRemoveList.add(r.binder); 1046 } 1047 } 1048 } 1049 handleRemoveListLocked(); 1050 } 1051 } 1052 1053 @Override 1054 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1055 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 1056 != PackageManager.PERMISSION_GRANTED) { 1057 pw.println("Permission Denial: can't dump telephony.registry from from pid=" 1058 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 1059 return; 1060 } 1061 synchronized (mRecords) { 1062 final int recordCount = mRecords.size(); 1063 pw.println("last known state:"); 1064 pw.println(" mCallState=" + mCallState); 1065 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber); 1066 pw.println(" mServiceState=" + mServiceState); 1067 pw.println(" mSignalStrength=" + mSignalStrength); 1068 pw.println(" mMessageWaiting=" + mMessageWaiting); 1069 pw.println(" mCallForwarding=" + mCallForwarding); 1070 pw.println(" mDataActivity=" + mDataActivity); 1071 pw.println(" mDataConnectionState=" + mDataConnectionState); 1072 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible); 1073 pw.println(" mDataConnectionReason=" + mDataConnectionReason); 1074 pw.println(" mDataConnectionApn=" + mDataConnectionApn); 1075 pw.println(" mDataConnectionLinkProperties=" + mDataConnectionLinkProperties); 1076 pw.println(" mDataConnectionNetworkCapabilities=" + 1077 mDataConnectionNetworkCapabilities); 1078 pw.println(" mDefaultSubId=" + mDefaultSubId); 1079 pw.println(" mCellLocation=" + mCellLocation); 1080 pw.println(" mCellInfo=" + mCellInfo); 1081 pw.println(" mDcRtInfo=" + mDcRtInfo); 1082 pw.println("registrations: count=" + recordCount); 1083 for (Record r : mRecords) { 1084 pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events)); 1085 } 1086 } 1087 } 1088 1089 // 1090 // the legacy intent broadcasting 1091 // 1092 1093 private void broadcastServiceStateChanged(ServiceState state, long subId) { 1094 long ident = Binder.clearCallingIdentity(); 1095 try { 1096 mBatteryStats.notePhoneState(state.getState()); 1097 } catch (RemoteException re) { 1098 // Can't do much 1099 } finally { 1100 Binder.restoreCallingIdentity(ident); 1101 } 1102 1103 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); 1104 Bundle data = new Bundle(); 1105 state.fillInNotifierBundle(data); 1106 intent.putExtras(data); 1107 // Pass the subscription along with the intent. 1108 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1109 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1110 } 1111 1112 private void broadcastSignalStrengthChanged(SignalStrength signalStrength, long subId) { 1113 long ident = Binder.clearCallingIdentity(); 1114 try { 1115 mBatteryStats.notePhoneSignalStrength(signalStrength); 1116 } catch (RemoteException e) { 1117 /* The remote entity disappeared, we can safely ignore the exception. */ 1118 } finally { 1119 Binder.restoreCallingIdentity(ident); 1120 } 1121 1122 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED); 1123 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1124 Bundle data = new Bundle(); 1125 signalStrength.fillInNotifierBundle(data); 1126 intent.putExtras(data); 1127 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1128 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1129 } 1130 1131 private void broadcastCallStateChanged(int state, String incomingNumber, long subId) { 1132 long ident = Binder.clearCallingIdentity(); 1133 try { 1134 if (state == TelephonyManager.CALL_STATE_IDLE) { 1135 mBatteryStats.notePhoneOff(); 1136 } else { 1137 mBatteryStats.notePhoneOn(); 1138 } 1139 } catch (RemoteException e) { 1140 /* The remote entity disappeared, we can safely ignore the exception. */ 1141 } finally { 1142 Binder.restoreCallingIdentity(ident); 1143 } 1144 1145 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED); 1146 intent.putExtra(PhoneConstants.STATE_KEY, 1147 DefaultPhoneNotifier.convertCallState(state).toString()); 1148 if (!TextUtils.isEmpty(incomingNumber)) { 1149 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber); 1150 } 1151 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1152 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1153 android.Manifest.permission.READ_PHONE_STATE); 1154 } 1155 1156 private void broadcastDataConnectionStateChanged(int state, 1157 boolean isDataConnectivityPossible, 1158 String reason, String apn, String apnType, LinkProperties linkProperties, 1159 NetworkCapabilities networkCapabilities, boolean roaming, long subId) { 1160 // Note: not reporting to the battery stats service here, because the 1161 // status bar takes care of that after taking into account all of the 1162 // required info. 1163 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); 1164 intent.putExtra(PhoneConstants.STATE_KEY, 1165 DefaultPhoneNotifier.convertDataState(state).toString()); 1166 if (!isDataConnectivityPossible) { 1167 intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true); 1168 } 1169 if (reason != null) { 1170 intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); 1171 } 1172 if (linkProperties != null) { 1173 intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties); 1174 String iface = linkProperties.getInterfaceName(); 1175 if (iface != null) { 1176 intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface); 1177 } 1178 } 1179 if (networkCapabilities != null) { 1180 intent.putExtra(PhoneConstants.DATA_NETWORK_CAPABILITIES_KEY, networkCapabilities); 1181 } 1182 if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true); 1183 1184 intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); 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 broadcastDataConnectionFailed(String reason, String apnType, 1191 long subId) { 1192 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED); 1193 intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason); 1194 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1195 intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); 1196 mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); 1197 } 1198 1199 private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState, 1200 int backgroundCallState, int disconnectCause, int preciseDisconnectCause) { 1201 Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED); 1202 intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState); 1203 intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState); 1204 intent.putExtra(TelephonyManager.EXTRA_BACKGROUND_CALL_STATE, backgroundCallState); 1205 intent.putExtra(TelephonyManager.EXTRA_DISCONNECT_CAUSE, disconnectCause); 1206 intent.putExtra(TelephonyManager.EXTRA_PRECISE_DISCONNECT_CAUSE, preciseDisconnectCause); 1207 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1208 android.Manifest.permission.READ_PRECISE_PHONE_STATE); 1209 } 1210 1211 private void broadcastPreciseDataConnectionStateChanged(int state, int networkType, 1212 String apnType, String apn, String reason, LinkProperties linkProperties, String failCause) { 1213 Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED); 1214 intent.putExtra(PhoneConstants.STATE_KEY, state); 1215 intent.putExtra(PhoneConstants.DATA_NETWORK_TYPE_KEY, networkType); 1216 if (reason != null) intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); 1217 if (apnType != null) intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 1218 if (apn != null) intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); 1219 if (linkProperties != null) intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties); 1220 if (failCause != null) intent.putExtra(PhoneConstants.DATA_FAILURE_CAUSE_KEY, failCause); 1221 1222 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, 1223 android.Manifest.permission.READ_PRECISE_PHONE_STATE); 1224 } 1225 1226 private boolean checkNotifyPermission(String method) { 1227 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) 1228 == PackageManager.PERMISSION_GRANTED) { 1229 return true; 1230 } 1231 String msg = "Modify Phone State Permission Denial: " + method + " from pid=" 1232 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid(); 1233 if (DBG) log(msg); 1234 return false; 1235 } 1236 1237 private void checkListenerPermission(int events) { 1238 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { 1239 mContext.enforceCallingOrSelfPermission( 1240 android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 1241 1242 } 1243 1244 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) { 1245 mContext.enforceCallingOrSelfPermission( 1246 android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 1247 1248 } 1249 1250 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) { 1251 mContext.enforceCallingOrSelfPermission( 1252 android.Manifest.permission.READ_PHONE_STATE, null); 1253 } 1254 1255 if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) { 1256 mContext.enforceCallingOrSelfPermission( 1257 android.Manifest.permission.READ_PRECISE_PHONE_STATE, null); 1258 1259 } 1260 } 1261 1262 private void handleRemoveListLocked() { 1263 if (mRemoveList.size() > 0) { 1264 for (IBinder b: mRemoveList) { 1265 remove(b); 1266 } 1267 mRemoveList.clear(); 1268 } 1269 } 1270 1271 private boolean validateEventsAndUserLocked(Record r, int events) { 1272 int foregroundUser; 1273 long callingIdentity = Binder.clearCallingIdentity(); 1274 boolean valid = false; 1275 try { 1276 foregroundUser = ActivityManager.getCurrentUser(); 1277 valid = r.callerUid == foregroundUser && (r.events & events) != 0; 1278 if (DBG | DBG_LOC) { 1279 log("validateEventsAndUserLocked: valid=" + valid 1280 + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser 1281 + " r.events=" + r.events + " events=" + events); 1282 } 1283 } finally { 1284 Binder.restoreCallingIdentity(callingIdentity); 1285 } 1286 return valid; 1287 } 1288 1289 private boolean validatePhoneId(int phoneId) { 1290 boolean valid = (phoneId >= 0) && (phoneId < mNumPhones); 1291 if (VDBG) log("validatePhoneId: " + valid); 1292 return valid; 1293 } 1294 1295 private static void log(String s) { 1296 Rlog.d(TAG, s); 1297 } 1298} 1299