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