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