TelephonyRegistry.java revision a639b311e93ad14d9ee5c2b2c215ed2d86c32d2a
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.content.Context; 20import android.content.Intent; 21import android.content.pm.PackageManager; 22import android.net.LinkCapabilities; 23import android.net.LinkProperties; 24import android.os.Binder; 25import android.os.Bundle; 26import android.os.IBinder; 27import android.os.RemoteException; 28import android.telephony.CellLocation; 29import android.telephony.PhoneStateListener; 30import android.telephony.ServiceState; 31import android.telephony.SignalStrength; 32import android.telephony.CellInfo; 33import android.telephony.TelephonyManager; 34import android.text.TextUtils; 35import android.util.Slog; 36 37import java.util.ArrayList; 38import java.io.FileDescriptor; 39import java.io.PrintWriter; 40import java.net.NetworkInterface; 41 42import com.android.internal.app.IBatteryStats; 43import com.android.internal.telephony.ITelephonyRegistry; 44import com.android.internal.telephony.IPhoneStateListener; 45import com.android.internal.telephony.DefaultPhoneNotifier; 46import com.android.internal.telephony.Phone; 47import com.android.internal.telephony.PhoneConstants; 48import com.android.internal.telephony.ServiceStateTracker; 49import com.android.internal.telephony.TelephonyIntents; 50import com.android.server.am.BatteryStatsService; 51 52/** 53 * Since phone process can be restarted, this class provides a centralized place 54 * that applications can register and be called back from. 55 */ 56class TelephonyRegistry extends ITelephonyRegistry.Stub { 57 private static final String TAG = "TelephonyRegistry"; 58 private static final boolean DBG = false; 59 60 private static class Record { 61 String pkgForDebug; 62 63 IBinder binder; 64 65 IPhoneStateListener callback; 66 67 int events; 68 } 69 70 private final Context mContext; 71 72 // access should be inside synchronized (mRecords) for these two fields 73 private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>(); 74 private final ArrayList<Record> mRecords = new ArrayList<Record>(); 75 76 private final IBatteryStats mBatteryStats; 77 78 private int mCallState = TelephonyManager.CALL_STATE_IDLE; 79 80 private String mCallIncomingNumber = ""; 81 82 private ServiceState mServiceState = new ServiceState(); 83 84 private SignalStrength mSignalStrength = new SignalStrength(); 85 86 private boolean mMessageWaiting = false; 87 88 private boolean mCallForwarding = false; 89 90 private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE; 91 92 private int mDataConnectionState = TelephonyManager.DATA_UNKNOWN; 93 94 private boolean mDataConnectionPossible = false; 95 96 private String mDataConnectionReason = ""; 97 98 private String mDataConnectionApn = ""; 99 100 private ArrayList<String> mConnectedApns; 101 102 private LinkProperties mDataConnectionLinkProperties; 103 104 private LinkCapabilities mDataConnectionLinkCapabilities; 105 106 private Bundle mCellLocation = new Bundle(); 107 108 private int mDataConnectionNetworkType; 109 110 private int mOtaspMode = ServiceStateTracker.OTASP_UNKNOWN; 111 112 private CellInfo mCellInfo = null; 113 114 static final int PHONE_STATE_PERMISSION_MASK = 115 PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR | 116 PhoneStateListener.LISTEN_CALL_STATE | 117 PhoneStateListener.LISTEN_DATA_ACTIVITY | 118 PhoneStateListener.LISTEN_DATA_CONNECTION_STATE | 119 PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR; 120 121 // we keep a copy of all of the state so we can send it out when folks 122 // register for it 123 // 124 // In these calls we call with the lock held. This is safe becasuse remote 125 // calls go through a oneway interface and local calls going through a 126 // handler before they get to app code. 127 128 TelephonyRegistry(Context context) { 129 CellLocation location = CellLocation.getEmpty(); 130 131 // Note that location can be null for non-phone builds like 132 // like the generic one. 133 if (location != null) { 134 location.fillInNotifierBundle(mCellLocation); 135 } 136 mContext = context; 137 mBatteryStats = BatteryStatsService.getService(); 138 mConnectedApns = new ArrayList<String>(); 139 } 140 141 public void listen(String pkgForDebug, IPhoneStateListener callback, int events, 142 boolean notifyNow) { 143 // Slog.d(TAG, "listen pkg=" + pkgForDebug + " events=0x" + 144 // Integer.toHexString(events)); 145 if (events != 0) { 146 /* Checks permission and throws Security exception */ 147 checkListenerPermission(events); 148 149 synchronized (mRecords) { 150 // register 151 Record r = null; 152 find_and_add: { 153 IBinder b = callback.asBinder(); 154 final int N = mRecords.size(); 155 for (int i = 0; i < N; i++) { 156 r = mRecords.get(i); 157 if (b == r.binder) { 158 break find_and_add; 159 } 160 } 161 r = new Record(); 162 r.binder = b; 163 r.callback = callback; 164 r.pkgForDebug = pkgForDebug; 165 mRecords.add(r); 166 } 167 int send = events & (events ^ r.events); 168 r.events = events; 169 if (notifyNow) { 170 if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { 171 try { 172 r.callback.onServiceStateChanged(new ServiceState(mServiceState)); 173 } catch (RemoteException ex) { 174 remove(r.binder); 175 } 176 } 177 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { 178 try { 179 int gsmSignalStrength = mSignalStrength.getGsmSignalStrength(); 180 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 181 : gsmSignalStrength)); 182 } catch (RemoteException ex) { 183 remove(r.binder); 184 } 185 } 186 if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { 187 try { 188 r.callback.onMessageWaitingIndicatorChanged(mMessageWaiting); 189 } catch (RemoteException ex) { 190 remove(r.binder); 191 } 192 } 193 if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { 194 try { 195 r.callback.onCallForwardingIndicatorChanged(mCallForwarding); 196 } catch (RemoteException ex) { 197 remove(r.binder); 198 } 199 } 200 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { 201 try { 202 r.callback.onCellLocationChanged(new Bundle(mCellLocation)); 203 } catch (RemoteException ex) { 204 remove(r.binder); 205 } 206 } 207 if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) { 208 try { 209 r.callback.onCallStateChanged(mCallState, mCallIncomingNumber); 210 } catch (RemoteException ex) { 211 remove(r.binder); 212 } 213 } 214 if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { 215 try { 216 r.callback.onDataConnectionStateChanged(mDataConnectionState, 217 mDataConnectionNetworkType); 218 } catch (RemoteException ex) { 219 remove(r.binder); 220 } 221 } 222 if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) { 223 try { 224 r.callback.onDataActivity(mDataActivity); 225 } catch (RemoteException ex) { 226 remove(r.binder); 227 } 228 } 229 if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { 230 try { 231 r.callback.onSignalStrengthsChanged(mSignalStrength); 232 } catch (RemoteException ex) { 233 remove(r.binder); 234 } 235 } 236 if ((events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) { 237 try { 238 r.callback.onOtaspChanged(mOtaspMode); 239 } catch (RemoteException ex) { 240 remove(r.binder); 241 } 242 } 243 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) { 244 try { 245 r.callback.onCellInfoChanged(new CellInfo(mCellInfo)); 246 } catch (RemoteException ex) { 247 remove(r.binder); 248 } 249 } 250 } 251 } 252 } else { 253 remove(callback.asBinder()); 254 } 255 } 256 257 private void remove(IBinder binder) { 258 synchronized (mRecords) { 259 final int recordCount = mRecords.size(); 260 for (int i = 0; i < recordCount; i++) { 261 if (mRecords.get(i).binder == binder) { 262 mRecords.remove(i); 263 return; 264 } 265 } 266 } 267 } 268 269 public void notifyCallState(int state, String incomingNumber) { 270 if (!checkNotifyPermission("notifyCallState()")) { 271 return; 272 } 273 synchronized (mRecords) { 274 mCallState = state; 275 mCallIncomingNumber = incomingNumber; 276 for (Record r : mRecords) { 277 if ((r.events & PhoneStateListener.LISTEN_CALL_STATE) != 0) { 278 try { 279 r.callback.onCallStateChanged(state, incomingNumber); 280 } catch (RemoteException ex) { 281 mRemoveList.add(r.binder); 282 } 283 } 284 } 285 handleRemoveListLocked(); 286 } 287 broadcastCallStateChanged(state, incomingNumber); 288 } 289 290 public void notifyServiceState(ServiceState state) { 291 if (!checkNotifyPermission("notifyServiceState()")){ 292 return; 293 } 294 synchronized (mRecords) { 295 mServiceState = state; 296 for (Record r : mRecords) { 297 if ((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { 298 try { 299 r.callback.onServiceStateChanged(new ServiceState(state)); 300 } catch (RemoteException ex) { 301 mRemoveList.add(r.binder); 302 } 303 } 304 } 305 handleRemoveListLocked(); 306 } 307 broadcastServiceStateChanged(state); 308 } 309 310 public void notifySignalStrength(SignalStrength signalStrength) { 311 if (!checkNotifyPermission("notifySignalStrength()")) { 312 return; 313 } 314 synchronized (mRecords) { 315 mSignalStrength = signalStrength; 316 for (Record r : mRecords) { 317 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { 318 try { 319 r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength)); 320 } catch (RemoteException ex) { 321 mRemoveList.add(r.binder); 322 } 323 } 324 if ((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { 325 try { 326 int gsmSignalStrength = signalStrength.getGsmSignalStrength(); 327 r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 328 : gsmSignalStrength)); 329 } catch (RemoteException ex) { 330 mRemoveList.add(r.binder); 331 } 332 } 333 } 334 handleRemoveListLocked(); 335 } 336 broadcastSignalStrengthChanged(signalStrength); 337 } 338 339 public void notifyCellInfo(CellInfo cellInfo) { 340 if (!checkNotifyPermission("notifyCellInfo()")) { 341 return; 342 } 343 344 synchronized (mRecords) { 345 mCellInfo = cellInfo; 346 for (Record r : mRecords) { 347 if ((r.events & PhoneStateListener.LISTEN_CELL_INFO) != 0) { 348 try { 349 r.callback.onCellInfoChanged(new CellInfo(cellInfo)); 350 } catch (RemoteException ex) { 351 mRemoveList.add(r.binder); 352 } 353 } 354 } 355 handleRemoveListLocked(); 356 } 357 } 358 359 public void notifyMessageWaitingChanged(boolean mwi) { 360 if (!checkNotifyPermission("notifyMessageWaitingChanged()")) { 361 return; 362 } 363 synchronized (mRecords) { 364 mMessageWaiting = mwi; 365 for (Record r : mRecords) { 366 if ((r.events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { 367 try { 368 r.callback.onMessageWaitingIndicatorChanged(mwi); 369 } catch (RemoteException ex) { 370 mRemoveList.add(r.binder); 371 } 372 } 373 } 374 handleRemoveListLocked(); 375 } 376 } 377 378 public void notifyCallForwardingChanged(boolean cfi) { 379 if (!checkNotifyPermission("notifyCallForwardingChanged()")) { 380 return; 381 } 382 synchronized (mRecords) { 383 mCallForwarding = cfi; 384 for (Record r : mRecords) { 385 if ((r.events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { 386 try { 387 r.callback.onCallForwardingIndicatorChanged(cfi); 388 } catch (RemoteException ex) { 389 mRemoveList.add(r.binder); 390 } 391 } 392 } 393 handleRemoveListLocked(); 394 } 395 } 396 397 public void notifyDataActivity(int state) { 398 if (!checkNotifyPermission("notifyDataActivity()" )) { 399 return; 400 } 401 synchronized (mRecords) { 402 mDataActivity = state; 403 for (Record r : mRecords) { 404 if ((r.events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) { 405 try { 406 r.callback.onDataActivity(state); 407 } catch (RemoteException ex) { 408 mRemoveList.add(r.binder); 409 } 410 } 411 } 412 handleRemoveListLocked(); 413 } 414 } 415 416 public void notifyDataConnection(int state, boolean isDataConnectivityPossible, 417 String reason, String apn, String apnType, LinkProperties linkProperties, 418 LinkCapabilities linkCapabilities, int networkType, boolean roaming) { 419 if (!checkNotifyPermission("notifyDataConnection()" )) { 420 return; 421 } 422 if (DBG) { 423 Slog.i(TAG, "notifyDataConnection: state=" + state + " isDataConnectivityPossible=" 424 + isDataConnectivityPossible + " reason='" + reason 425 + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType); 426 } 427 synchronized (mRecords) { 428 boolean modified = false; 429 if (state == TelephonyManager.DATA_CONNECTED) { 430 if (!mConnectedApns.contains(apnType)) { 431 mConnectedApns.add(apnType); 432 if (mDataConnectionState != state) { 433 mDataConnectionState = state; 434 modified = true; 435 } 436 } 437 } else { 438 if (mConnectedApns.remove(apnType)) { 439 if (mConnectedApns.isEmpty()) { 440 mDataConnectionState = state; 441 modified = true; 442 } else { 443 // leave mDataConnectionState as is and 444 // send out the new status for the APN in question. 445 } 446 } 447 } 448 mDataConnectionPossible = isDataConnectivityPossible; 449 mDataConnectionReason = reason; 450 mDataConnectionLinkProperties = linkProperties; 451 mDataConnectionLinkCapabilities = linkCapabilities; 452 if (mDataConnectionNetworkType != networkType) { 453 mDataConnectionNetworkType = networkType; 454 // need to tell registered listeners about the new network type 455 modified = true; 456 } 457 if (modified) { 458 if (DBG) { 459 Slog.d(TAG, "onDataConnectionStateChanged(" + mDataConnectionState 460 + ", " + mDataConnectionNetworkType + ")"); 461 } 462 for (Record r : mRecords) { 463 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { 464 try { 465 r.callback.onDataConnectionStateChanged(mDataConnectionState, 466 mDataConnectionNetworkType); 467 } catch (RemoteException ex) { 468 mRemoveList.add(r.binder); 469 } 470 } 471 } 472 handleRemoveListLocked(); 473 } 474 } 475 broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn, 476 apnType, linkProperties, linkCapabilities, roaming); 477 } 478 479 public void notifyDataConnectionFailed(String reason, String apnType) { 480 if (!checkNotifyPermission("notifyDataConnectionFailed()")) { 481 return; 482 } 483 /* 484 * This is commented out because there is no onDataConnectionFailed callback 485 * in PhoneStateListener. There should be. 486 synchronized (mRecords) { 487 mDataConnectionFailedReason = reason; 488 final int N = mRecords.size(); 489 for (int i=N-1; i>=0; i--) { 490 Record r = mRecords.get(i); 491 if ((r.events & PhoneStateListener.LISTEN_DATA_CONNECTION_FAILED) != 0) { 492 // XXX 493 } 494 } 495 } 496 */ 497 broadcastDataConnectionFailed(reason, apnType); 498 } 499 500 public void notifyCellLocation(Bundle cellLocation) { 501 if (!checkNotifyPermission("notifyCellLocation()")) { 502 return; 503 } 504 synchronized (mRecords) { 505 mCellLocation = cellLocation; 506 for (Record r : mRecords) { 507 if ((r.events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { 508 try { 509 r.callback.onCellLocationChanged(new Bundle(cellLocation)); 510 } catch (RemoteException ex) { 511 mRemoveList.add(r.binder); 512 } 513 514 } 515 } 516 handleRemoveListLocked(); 517 } 518 } 519 520 public void notifyOtaspChanged(int otaspMode) { 521 if (!checkNotifyPermission("notifyOtaspChanged()" )) { 522 return; 523 } 524 synchronized (mRecords) { 525 mOtaspMode = otaspMode; 526 for (Record r : mRecords) { 527 if ((r.events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) { 528 try { 529 r.callback.onOtaspChanged(otaspMode); 530 } catch (RemoteException ex) { 531 mRemoveList.add(r.binder); 532 } 533 } 534 } 535 handleRemoveListLocked(); 536 } 537 } 538 539 @Override 540 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 541 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 542 != PackageManager.PERMISSION_GRANTED) { 543 pw.println("Permission Denial: can't dump telephony.registry from from pid=" 544 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 545 return; 546 } 547 synchronized (mRecords) { 548 final int recordCount = mRecords.size(); 549 pw.println("last known state:"); 550 pw.println(" mCallState=" + mCallState); 551 pw.println(" mCallIncomingNumber=" + mCallIncomingNumber); 552 pw.println(" mServiceState=" + mServiceState); 553 pw.println(" mSignalStrength=" + mSignalStrength); 554 pw.println(" mMessageWaiting=" + mMessageWaiting); 555 pw.println(" mCallForwarding=" + mCallForwarding); 556 pw.println(" mDataActivity=" + mDataActivity); 557 pw.println(" mDataConnectionState=" + mDataConnectionState); 558 pw.println(" mDataConnectionPossible=" + mDataConnectionPossible); 559 pw.println(" mDataConnectionReason=" + mDataConnectionReason); 560 pw.println(" mDataConnectionApn=" + mDataConnectionApn); 561 pw.println(" mDataConnectionLinkProperties=" + mDataConnectionLinkProperties); 562 pw.println(" mDataConnectionLinkCapabilities=" + mDataConnectionLinkCapabilities); 563 pw.println(" mCellLocation=" + mCellLocation); 564 pw.println(" mCellInfo=" + mCellInfo); 565 pw.println("registrations: count=" + recordCount); 566 for (Record r : mRecords) { 567 pw.println(" " + r.pkgForDebug + " 0x" + Integer.toHexString(r.events)); 568 } 569 } 570 } 571 572 // 573 // the legacy intent broadcasting 574 // 575 576 private void broadcastServiceStateChanged(ServiceState state) { 577 long ident = Binder.clearCallingIdentity(); 578 try { 579 mBatteryStats.notePhoneState(state.getState()); 580 } catch (RemoteException re) { 581 // Can't do much 582 } finally { 583 Binder.restoreCallingIdentity(ident); 584 } 585 586 Intent intent = new Intent(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); 587 Bundle data = new Bundle(); 588 state.fillInNotifierBundle(data); 589 intent.putExtras(data); 590 mContext.sendStickyBroadcast(intent); 591 } 592 593 private void broadcastSignalStrengthChanged(SignalStrength signalStrength) { 594 long ident = Binder.clearCallingIdentity(); 595 try { 596 mBatteryStats.notePhoneSignalStrength(signalStrength); 597 } catch (RemoteException e) { 598 /* The remote entity disappeared, we can safely ignore the exception. */ 599 } finally { 600 Binder.restoreCallingIdentity(ident); 601 } 602 603 Intent intent = new Intent(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED); 604 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 605 Bundle data = new Bundle(); 606 signalStrength.fillInNotifierBundle(data); 607 intent.putExtras(data); 608 mContext.sendStickyBroadcast(intent); 609 } 610 611 private void broadcastCallStateChanged(int state, String incomingNumber) { 612 long ident = Binder.clearCallingIdentity(); 613 try { 614 if (state == TelephonyManager.CALL_STATE_IDLE) { 615 mBatteryStats.notePhoneOff(); 616 } else { 617 mBatteryStats.notePhoneOn(); 618 } 619 } catch (RemoteException e) { 620 /* The remote entity disappeared, we can safely ignore the exception. */ 621 } finally { 622 Binder.restoreCallingIdentity(ident); 623 } 624 625 Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED); 626 intent.putExtra(PhoneConstants.STATE_KEY, 627 DefaultPhoneNotifier.convertCallState(state).toString()); 628 if (!TextUtils.isEmpty(incomingNumber)) { 629 intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber); 630 } 631 mContext.sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE); 632 } 633 634 private void broadcastDataConnectionStateChanged(int state, 635 boolean isDataConnectivityPossible, 636 String reason, String apn, String apnType, LinkProperties linkProperties, 637 LinkCapabilities linkCapabilities, boolean roaming) { 638 // Note: not reporting to the battery stats service here, because the 639 // status bar takes care of that after taking into account all of the 640 // required info. 641 Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); 642 intent.putExtra(PhoneConstants.STATE_KEY, 643 DefaultPhoneNotifier.convertDataState(state).toString()); 644 if (!isDataConnectivityPossible) { 645 intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true); 646 } 647 if (reason != null) { 648 intent.putExtra(PhoneConstants.STATE_CHANGE_REASON_KEY, reason); 649 } 650 if (linkProperties != null) { 651 intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties); 652 String iface = linkProperties.getInterfaceName(); 653 if (iface != null) { 654 intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface); 655 } 656 } 657 if (linkCapabilities != null) { 658 intent.putExtra(PhoneConstants.DATA_LINK_CAPABILITIES_KEY, linkCapabilities); 659 } 660 if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true); 661 662 intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); 663 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 664 mContext.sendStickyBroadcast(intent); 665 } 666 667 private void broadcastDataConnectionFailed(String reason, String apnType) { 668 Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED); 669 intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason); 670 intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); 671 mContext.sendStickyBroadcast(intent); 672 } 673 674 private boolean checkNotifyPermission(String method) { 675 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) 676 == PackageManager.PERMISSION_GRANTED) { 677 return true; 678 } 679 String msg = "Modify Phone State Permission Denial: " + method + " from pid=" 680 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid(); 681 if (DBG) Slog.w(TAG, msg); 682 return false; 683 } 684 685 private void checkListenerPermission(int events) { 686 if ((events & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { 687 mContext.enforceCallingOrSelfPermission( 688 android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 689 690 } 691 692 if ((events & PhoneStateListener.LISTEN_CELL_INFO) != 0) { 693 mContext.enforceCallingOrSelfPermission( 694 android.Manifest.permission.ACCESS_COARSE_LOCATION, null); 695 696 } 697 698 if ((events & PHONE_STATE_PERMISSION_MASK) != 0) { 699 mContext.enforceCallingOrSelfPermission( 700 android.Manifest.permission.READ_PHONE_STATE, null); 701 } 702 } 703 704 private void handleRemoveListLocked() { 705 if (mRemoveList.size() > 0) { 706 for (IBinder b: mRemoveList) { 707 remove(b); 708 } 709 mRemoveList.clear(); 710 } 711 } 712} 713