1 /* 2 * Copyright (C) 2017 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 17 package com.android.internal.telephony; 18 19 import static android.hardware.radio.V1_0.DeviceStateType.CHARGING_STATE; 20 import static android.hardware.radio.V1_0.DeviceStateType.LOW_DATA_EXPECTED; 21 import static android.hardware.radio.V1_0.DeviceStateType.POWER_SAVE_MODE; 22 23 import android.app.UiModeManager; 24 import android.content.BroadcastReceiver; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.content.IntentFilter; 28 import android.content.res.Configuration; 29 import android.hardware.display.DisplayManager; 30 import android.hardware.radio.V1_5.IndicationFilter; 31 import android.net.ConnectivityManager; 32 import android.net.Network; 33 import android.net.NetworkCapabilities; 34 import android.net.NetworkRequest; 35 import android.net.TetheringManager; 36 import android.os.BatteryManager; 37 import android.os.Handler; 38 import android.os.Message; 39 import android.os.PowerManager; 40 import android.os.Registrant; 41 import android.os.RegistrantList; 42 import android.provider.Settings; 43 import android.telephony.AccessNetworkConstants.AccessNetworkType; 44 import android.telephony.CarrierConfigManager; 45 import android.telephony.NetworkRegistrationInfo; 46 import android.telephony.SignalThresholdInfo; 47 import android.util.LocalLog; 48 import android.view.Display; 49 50 import com.android.internal.annotations.VisibleForTesting; 51 import com.android.internal.util.IndentingPrintWriter; 52 import com.android.telephony.Rlog; 53 54 import java.io.FileDescriptor; 55 import java.io.PrintWriter; 56 import java.util.ArrayList; 57 import java.util.HashSet; 58 import java.util.Set; 59 60 /** 61 * The device state monitor monitors the device state such as charging state, power saving sate, 62 * and then passes down the information to the radio modem for the modem to perform its own 63 * proprietary power saving strategy. Device state monitor also turns off the unsolicited 64 * response from the modem when the device does not need to receive it, for example, device's 65 * screen is off and does not have activities like tethering, remote display, etc...This effectively 66 * prevents the CPU from waking up by those unnecessary unsolicited responses such as signal 67 * strength update. 68 */ 69 public class DeviceStateMonitor extends Handler { 70 protected static final boolean DBG = false; /* STOPSHIP if true */ 71 protected static final String TAG = DeviceStateMonitor.class.getSimpleName(); 72 73 static final int EVENT_RIL_CONNECTED = 0; 74 static final int EVENT_CAR_MODE_CHANGED = 1; 75 @VisibleForTesting 76 static final int EVENT_SCREEN_STATE_CHANGED = 2; 77 static final int EVENT_POWER_SAVE_MODE_CHANGED = 3; 78 @VisibleForTesting 79 static final int EVENT_CHARGING_STATE_CHANGED = 4; 80 static final int EVENT_TETHERING_STATE_CHANGED = 5; 81 static final int EVENT_RADIO_AVAILABLE = 6; 82 @VisibleForTesting 83 static final int EVENT_WIFI_CONNECTION_CHANGED = 7; 84 static final int EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH = 8; 85 86 private static final int WIFI_UNAVAILABLE = 0; 87 private static final int WIFI_AVAILABLE = 1; 88 89 private static final int NR_NSA_TRACKING_INDICATIONS_OFF = 0; 90 private static final int NR_NSA_TRACKING_INDICATIONS_EXTENDED = 1; 91 private static final int NR_NSA_TRACKING_INDICATIONS_ALWAYS_ON = 2; 92 93 private final Phone mPhone; 94 95 private final LocalLog mLocalLog = new LocalLog(100); 96 97 private final RegistrantList mPhysicalChannelConfigRegistrants = new RegistrantList(); 98 99 private final NetworkRequest mWifiNetworkRequest = 100 new NetworkRequest.Builder() 101 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) 102 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 103 .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) 104 .build(); 105 106 private final ConnectivityManager.NetworkCallback mNetworkCallback = 107 new ConnectivityManager.NetworkCallback() { 108 Set<Network> mWifiNetworks = new HashSet<>(); 109 110 @Override 111 public void onAvailable(Network network) { 112 synchronized (mWifiNetworks) { 113 if (mWifiNetworks.size() == 0) { 114 // We just connected to Wifi, so send an update. 115 obtainMessage(EVENT_WIFI_CONNECTION_CHANGED, WIFI_AVAILABLE, 0).sendToTarget(); 116 log("Wifi (default) connected", true); 117 } 118 mWifiNetworks.add(network); 119 } 120 } 121 122 @Override 123 public void onLost(Network network) { 124 synchronized (mWifiNetworks) { 125 mWifiNetworks.remove(network); 126 if (mWifiNetworks.size() == 0) { 127 // We just disconnected from the last connected wifi, so send an update. 128 obtainMessage( 129 EVENT_WIFI_CONNECTION_CHANGED, WIFI_UNAVAILABLE, 0).sendToTarget(); 130 log("Wifi (default) disconnected", true); 131 } 132 } 133 } 134 }; 135 136 /** 137 * Flag for wifi/usb/bluetooth tethering turned on or not 138 */ 139 private boolean mIsTetheringOn; 140 141 /** 142 * Screen state provided by Display Manager. True indicates one of the screen is on, otherwise 143 * all off. 144 */ 145 private boolean mIsScreenOn; 146 147 /** 148 * Indicating the device is plugged in and is supplying sufficient power that the battery level 149 * is going up (or the battery is fully charged). See BatteryManager.isCharging() for the 150 * details 151 */ 152 private boolean mIsCharging; 153 154 /** 155 * Flag for device power save mode. See PowerManager.isPowerSaveMode() for the details. 156 * Note that it is not possible both mIsCharging and mIsPowerSaveOn are true at the same time. 157 * The system will automatically end power save mode when the device starts charging. 158 */ 159 private boolean mIsPowerSaveOn; 160 161 /** 162 * Low data expected mode. True indicates low data traffic is expected, for example, when the 163 * device is idle (e.g. screen is off and not doing tethering in the background). Note this 164 * doesn't mean no data is expected. 165 */ 166 private boolean mIsLowDataExpected; 167 168 /** 169 * Wifi is connected. True means both that cellular is likely to be asleep when the screen is 170 * on and that in most cases the device location is relatively close to the WiFi AP. This means 171 * that fewer location updates should be provided by cellular. 172 */ 173 private boolean mIsWifiConnected; 174 175 /** 176 * Car mode is on. True means the device is currently connected to Android Auto. This should be 177 * handled by mIsScreenOn, but the Android Auto display is private and not accessible by 178 * DeviceStateMonitor from DisplayMonitor. 179 */ 180 private boolean mIsCarModeOn; 181 182 /** 183 * True indicates we should always enable the signal strength reporting from radio. 184 */ 185 private boolean mIsAlwaysSignalStrengthReportingEnabled; 186 187 @VisibleForTesting 188 static final int CELL_INFO_INTERVAL_SHORT_MS = 2000; 189 @VisibleForTesting 190 static final int CELL_INFO_INTERVAL_LONG_MS = 10000; 191 192 /** The minimum required wait time between cell info requests to the modem */ 193 private int mCellInfoMinInterval = CELL_INFO_INTERVAL_SHORT_MS; 194 195 /** 196 * The unsolicited response filter. See IndicationFilter defined in types.hal for the definition 197 * of each bit. 198 */ 199 private int mUnsolicitedResponseFilter = IndicationFilter.ALL; 200 201 private final DisplayManager.DisplayListener mDisplayListener = 202 new DisplayManager.DisplayListener() { 203 @Override 204 public void onDisplayAdded(int displayId) { } 205 206 @Override 207 public void onDisplayRemoved(int displayId) { } 208 209 @Override 210 public void onDisplayChanged(int displayId) { 211 boolean screenOn = isScreenOn(); 212 Message msg = obtainMessage(EVENT_SCREEN_STATE_CHANGED); 213 msg.arg1 = screenOn ? 1 : 0; 214 sendMessage(msg); 215 } 216 }; 217 218 /** 219 * Device state broadcast receiver 220 */ 221 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 222 @Override 223 public void onReceive(Context context, Intent intent) { 224 log("received: " + intent, true); 225 226 Message msg; 227 switch (intent.getAction()) { 228 case PowerManager.ACTION_POWER_SAVE_MODE_CHANGED: 229 msg = obtainMessage(EVENT_POWER_SAVE_MODE_CHANGED); 230 msg.arg1 = isPowerSaveModeOn() ? 1 : 0; 231 log("Power Save mode " + ((msg.arg1 == 1) ? "on" : "off"), true); 232 break; 233 case BatteryManager.ACTION_CHARGING: 234 msg = obtainMessage(EVENT_CHARGING_STATE_CHANGED); 235 msg.arg1 = 1; // charging 236 break; 237 case BatteryManager.ACTION_DISCHARGING: 238 msg = obtainMessage(EVENT_CHARGING_STATE_CHANGED); 239 msg.arg1 = 0; // not charging 240 break; 241 case TetheringManager.ACTION_TETHER_STATE_CHANGED: 242 ArrayList<String> activeTetherIfaces = intent.getStringArrayListExtra( 243 TetheringManager.EXTRA_ACTIVE_TETHER); 244 245 boolean isTetheringOn = activeTetherIfaces != null 246 && activeTetherIfaces.size() > 0; 247 log("Tethering " + (isTetheringOn ? "on" : "off"), true); 248 msg = obtainMessage(EVENT_TETHERING_STATE_CHANGED); 249 msg.arg1 = isTetheringOn ? 1 : 0; 250 break; 251 case UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED: 252 msg = obtainMessage(EVENT_CAR_MODE_CHANGED); 253 msg.arg1 = 1; // car mode on 254 break; 255 case UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED: 256 msg = obtainMessage(EVENT_CAR_MODE_CHANGED); 257 msg.arg1 = 0; // car mode off 258 break; 259 default: 260 log("Unexpected broadcast intent: " + intent, false); 261 return; 262 } 263 sendMessage(msg); 264 } 265 }; 266 267 /** 268 * Device state monitor constructor. Note that each phone object should have its own device 269 * state monitor, meaning there will be two device monitors on the multi-sim device. 270 * 271 * @param phone Phone object 272 */ DeviceStateMonitor(Phone phone)273 public DeviceStateMonitor(Phone phone) { 274 mPhone = phone; 275 DisplayManager dm = (DisplayManager) phone.getContext().getSystemService( 276 Context.DISPLAY_SERVICE); 277 dm.registerDisplayListener(mDisplayListener, null); 278 279 mIsPowerSaveOn = isPowerSaveModeOn(); 280 mIsCharging = isDeviceCharging(); 281 mIsScreenOn = isScreenOn(); 282 mIsCarModeOn = isCarModeOn(); 283 // Assuming tethering is always off after boot up. 284 mIsTetheringOn = false; 285 mIsLowDataExpected = false; 286 287 log("DeviceStateMonitor mIsTetheringOn=" + mIsTetheringOn 288 + ", mIsScreenOn=" + mIsScreenOn 289 + ", mIsCharging=" + mIsCharging 290 + ", mIsPowerSaveOn=" + mIsPowerSaveOn 291 + ", mIsLowDataExpected=" + mIsLowDataExpected 292 + ", mIsCarModeOn=" + mIsCarModeOn 293 + ", mIsWifiConnected=" + mIsWifiConnected 294 + ", mIsAlwaysSignalStrengthReportingEnabled=" 295 + mIsAlwaysSignalStrengthReportingEnabled, false); 296 297 final IntentFilter filter = new IntentFilter(); 298 filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); 299 filter.addAction(BatteryManager.ACTION_CHARGING); 300 filter.addAction(BatteryManager.ACTION_DISCHARGING); 301 filter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); 302 filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED); 303 filter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED); 304 mPhone.getContext().registerReceiver(mBroadcastReceiver, filter, null, mPhone); 305 306 mPhone.mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null); 307 mPhone.mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); 308 309 ConnectivityManager cm = (ConnectivityManager) phone.getContext().getSystemService( 310 Context.CONNECTIVITY_SERVICE); 311 cm.registerNetworkCallback(mWifiNetworkRequest, mNetworkCallback); 312 } 313 314 /** 315 * @return True if low data is expected 316 */ isLowDataExpected()317 private boolean isLowDataExpected() { 318 return !mIsCharging && !mIsTetheringOn && !mIsScreenOn; 319 } 320 321 /** 322 * @return The minimum period between CellInfo requests to the modem 323 */ 324 @VisibleForTesting computeCellInfoMinInterval()325 public int computeCellInfoMinInterval() { 326 // The screen is on and we're either on cellular or charging. Screen on + Charging is 327 // a likely vehicular scenario, even if there is a nomadic AP. 328 if (mIsScreenOn && !mIsWifiConnected) { 329 // Screen on without WiFi - We are in a high power likely mobile situation. 330 return CELL_INFO_INTERVAL_SHORT_MS; 331 } else if (mIsScreenOn && mIsCharging) { 332 // Screen is on and we're charging, so we favor accuracy over power. 333 return CELL_INFO_INTERVAL_SHORT_MS; 334 } else { 335 // If the screen is off, apps should not need cellular location at rapid intervals. 336 // If the screen is on but we are on wifi and not charging then cellular location 337 // accuracy is not crucial, so favor modem power saving over high accuracy. 338 return CELL_INFO_INTERVAL_LONG_MS; 339 } 340 } 341 342 /** 343 * @return True if signal strength update should be enabled. See details in 344 * android.hardware.radio@1.2::IndicationFilter::SIGNAL_STRENGTH. 345 */ shouldEnableSignalStrengthReports()346 private boolean shouldEnableSignalStrengthReports() { 347 // We should enable signal strength update if one of the following condition is true. 348 // 1. The device is charging. 349 // 2. When the screen is on. 350 // 3. Any of system services is registrating to always listen to signal strength changes 351 return mIsAlwaysSignalStrengthReportingEnabled || mIsCharging || mIsScreenOn; 352 } 353 354 /** 355 * @return True if full network state update should be enabled. When off, only significant 356 * changes will trigger the network update unsolicited response. See details in 357 * android.hardware.radio@1.2::IndicationFilter::FULL_NETWORK_STATE. 358 */ shouldEnableFullNetworkStateReports()359 private boolean shouldEnableFullNetworkStateReports() { 360 return shouldEnableNrTrackingIndications(); 361 } 362 363 /** 364 * @return True if data call dormancy changed update should be enabled. See details in 365 * android.hardware.radio@1.2::IndicationFilter::DATA_CALL_DORMANCY_CHANGED. 366 */ shouldEnableDataCallDormancyChangedReports()367 private boolean shouldEnableDataCallDormancyChangedReports() { 368 return shouldEnableNrTrackingIndications(); 369 } 370 371 /** 372 * @return True if link capacity estimate update should be enabled. See details in 373 * android.hardware.radio@1.2::IndicationFilter::LINK_CAPACITY_ESTIMATE. 374 */ shouldEnableLinkCapacityEstimateReports()375 private boolean shouldEnableLinkCapacityEstimateReports() { 376 return shouldEnableHighPowerConsumptionIndications(); 377 } 378 379 /** 380 * @return True if physical channel config update should be enabled. See details in 381 * android.hardware.radio@1.2::IndicationFilter::PHYSICAL_CHANNEL_CONFIG. 382 */ shouldEnablePhysicalChannelConfigReports()383 private boolean shouldEnablePhysicalChannelConfigReports() { 384 return shouldEnableNrTrackingIndications(); 385 } 386 387 /** 388 * @return True if barring info update should be enabled. See details in 389 * android.hardware.radio@1.5::IndicationFilter::BARRING_INFO. 390 */ shouldEnableBarringInfoReports()391 private boolean shouldEnableBarringInfoReports() { 392 return shouldEnableHighPowerConsumptionIndications(); 393 } 394 395 /** 396 * A common policy to determine if we should enable the necessary indications update, 397 * for power consumption's sake. 398 * 399 * @return True if the response update should be enabled. 400 */ shouldEnableHighPowerConsumptionIndications()401 private boolean shouldEnableHighPowerConsumptionIndications() { 402 // We should enable indications reports if one of the following condition is true. 403 // 1. The device is charging. 404 // 2. When the screen is on. 405 // 3. When the tethering is on. 406 // 4. When car mode (Android Auto) is on. 407 return mIsCharging || mIsScreenOn || mIsTetheringOn || mIsCarModeOn; 408 } 409 410 /** 411 * For 5G NSA devices, a policy to determine if we should enable NR tracking indications. 412 * 413 * @return True if the response update should be enabled. 414 */ shouldEnableNrTrackingIndications()415 private boolean shouldEnableNrTrackingIndications() { 416 int trackingMode = Settings.Global.getInt(mPhone.getContext().getContentResolver(), 417 Settings.Global.NR_NSA_TRACKING_SCREEN_OFF_MODE, NR_NSA_TRACKING_INDICATIONS_OFF); 418 switch (trackingMode) { 419 case NR_NSA_TRACKING_INDICATIONS_ALWAYS_ON: 420 return true; 421 case NR_NSA_TRACKING_INDICATIONS_EXTENDED: 422 if (mPhone.getServiceState().getNrState() 423 == NetworkRegistrationInfo.NR_STATE_CONNECTED) { 424 return true; 425 } 426 // fallthrough 427 case NR_NSA_TRACKING_INDICATIONS_OFF: 428 return shouldEnableHighPowerConsumptionIndications(); 429 default: 430 return shouldEnableHighPowerConsumptionIndications(); 431 } 432 } 433 434 /** 435 * Set if Telephony need always report signal strength. 436 * 437 * @param isEnable 438 */ setAlwaysReportSignalStrength(boolean isEnable)439 public void setAlwaysReportSignalStrength(boolean isEnable) { 440 sendMessage(obtainMessage(EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH, isEnable ? 1 : 0)); 441 } 442 443 /** 444 * Message handler 445 * 446 * @param msg The message 447 */ 448 @Override handleMessage(Message msg)449 public void handleMessage(Message msg) { 450 log("handleMessage msg=" + msg, false); 451 switch (msg.what) { 452 case EVENT_RIL_CONNECTED: 453 case EVENT_RADIO_AVAILABLE: 454 onReset(); 455 break; 456 case EVENT_SCREEN_STATE_CHANGED: 457 case EVENT_POWER_SAVE_MODE_CHANGED: 458 case EVENT_CHARGING_STATE_CHANGED: 459 case EVENT_TETHERING_STATE_CHANGED: 460 case EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH: 461 case EVENT_CAR_MODE_CHANGED: 462 onUpdateDeviceState(msg.what, msg.arg1 != 0); 463 break; 464 case EVENT_WIFI_CONNECTION_CHANGED: 465 onUpdateDeviceState(msg.what, msg.arg1 != WIFI_UNAVAILABLE); 466 break; 467 default: 468 throw new IllegalStateException("Unexpected message arrives. msg = " + msg.what); 469 } 470 } 471 472 /** 473 * Update the device and send the information to the modem. 474 * 475 * @param eventType Device state event type 476 * @param state True if enabled/on, otherwise disabled/off. 477 */ onUpdateDeviceState(int eventType, boolean state)478 private void onUpdateDeviceState(int eventType, boolean state) { 479 final boolean shouldEnableBarringInfoReportsOld = shouldEnableBarringInfoReports(); 480 switch (eventType) { 481 case EVENT_SCREEN_STATE_CHANGED: 482 if (mIsScreenOn == state) return; 483 mIsScreenOn = state; 484 break; 485 case EVENT_CHARGING_STATE_CHANGED: 486 if (mIsCharging == state) return; 487 mIsCharging = state; 488 sendDeviceState(CHARGING_STATE, mIsCharging); 489 break; 490 case EVENT_TETHERING_STATE_CHANGED: 491 if (mIsTetheringOn == state) return; 492 mIsTetheringOn = state; 493 break; 494 case EVENT_POWER_SAVE_MODE_CHANGED: 495 if (mIsPowerSaveOn == state) return; 496 mIsPowerSaveOn = state; 497 sendDeviceState(POWER_SAVE_MODE, mIsPowerSaveOn); 498 break; 499 case EVENT_WIFI_CONNECTION_CHANGED: 500 if (mIsWifiConnected == state) return; 501 mIsWifiConnected = state; 502 break; 503 case EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH: 504 if (mIsAlwaysSignalStrengthReportingEnabled == state) return; 505 mIsAlwaysSignalStrengthReportingEnabled = state; 506 break; 507 case EVENT_CAR_MODE_CHANGED: 508 if (mIsCarModeOn == state) return; 509 mIsCarModeOn = state; 510 break; 511 default: 512 return; 513 } 514 515 final int newCellInfoMinInterval = computeCellInfoMinInterval(); 516 if (mCellInfoMinInterval != newCellInfoMinInterval) { 517 mCellInfoMinInterval = newCellInfoMinInterval; 518 setCellInfoMinInterval(mCellInfoMinInterval); 519 log("CellInfo Min Interval Updated to " + newCellInfoMinInterval, true); 520 } 521 522 if (mIsLowDataExpected != isLowDataExpected()) { 523 mIsLowDataExpected = !mIsLowDataExpected; 524 sendDeviceState(LOW_DATA_EXPECTED, mIsLowDataExpected); 525 } 526 527 // Registration Failure is always reported. 528 int newFilter = IndicationFilter.REGISTRATION_FAILURE; 529 530 if (shouldEnableSignalStrengthReports()) { 531 newFilter |= IndicationFilter.SIGNAL_STRENGTH; 532 } 533 534 if (shouldEnableFullNetworkStateReports()) { 535 newFilter |= IndicationFilter.FULL_NETWORK_STATE; 536 } 537 538 if (shouldEnableDataCallDormancyChangedReports()) { 539 newFilter |= IndicationFilter.DATA_CALL_DORMANCY_CHANGED; 540 } 541 542 if (shouldEnableLinkCapacityEstimateReports()) { 543 newFilter |= IndicationFilter.LINK_CAPACITY_ESTIMATE; 544 } 545 546 if (shouldEnablePhysicalChannelConfigReports()) { 547 newFilter |= IndicationFilter.PHYSICAL_CHANNEL_CONFIG; 548 } 549 550 final boolean shouldEnableBarringInfoReports = shouldEnableBarringInfoReports(); 551 if (shouldEnableBarringInfoReports) { 552 newFilter |= IndicationFilter.BARRING_INFO; 553 } 554 555 // notify PhysicalChannelConfig registrants if state changes 556 if ((newFilter & IndicationFilter.PHYSICAL_CHANNEL_CONFIG) 557 != (mUnsolicitedResponseFilter & IndicationFilter.PHYSICAL_CHANNEL_CONFIG)) { 558 mPhysicalChannelConfigRegistrants.notifyResult( 559 (newFilter & IndicationFilter.PHYSICAL_CHANNEL_CONFIG) != 0); 560 } 561 562 setUnsolResponseFilter(newFilter, false); 563 564 // Pull barring info AFTER setting filter, the order matters 565 if (shouldEnableBarringInfoReports && !shouldEnableBarringInfoReportsOld) { 566 if (DBG) log("Manually pull barring info...", true); 567 // use a null message since we don't care of receiving response 568 mPhone.mCi.getBarringInfo(null); 569 } 570 } 571 572 /** 573 * Called when RIL is connected during boot up or radio becomes available after modem restart. 574 * 575 * When modem crashes, if the user turns the screen off before RIL reconnects, device 576 * state and filter cannot be sent to modem. Resend the state here so that modem 577 * has the correct state (to stop signal strength reporting, etc). 578 */ onReset()579 private void onReset() { 580 log("onReset.", true); 581 sendDeviceState(CHARGING_STATE, mIsCharging); 582 sendDeviceState(LOW_DATA_EXPECTED, mIsLowDataExpected); 583 sendDeviceState(POWER_SAVE_MODE, mIsPowerSaveOn); 584 setUnsolResponseFilter(mUnsolicitedResponseFilter, true); 585 setSignalStrengthReportingCriteria(); 586 setLinkCapacityReportingCriteria(); 587 setCellInfoMinInterval(mCellInfoMinInterval); 588 } 589 590 /** 591 * Convert the device state type into string 592 * 593 * @param type Device state type 594 * @return The converted string 595 */ deviceTypeToString(int type)596 private String deviceTypeToString(int type) { 597 switch (type) { 598 case CHARGING_STATE: return "CHARGING_STATE"; 599 case LOW_DATA_EXPECTED: return "LOW_DATA_EXPECTED"; 600 case POWER_SAVE_MODE: return "POWER_SAVE_MODE"; 601 default: return "UNKNOWN"; 602 } 603 } 604 605 /** 606 * Send the device state to the modem. 607 * 608 * @param type Device state type. See DeviceStateType defined in types.hal. 609 * @param state True if enabled/on, otherwise disabled/off 610 */ sendDeviceState(int type, boolean state)611 private void sendDeviceState(int type, boolean state) { 612 log("send type: " + deviceTypeToString(type) + ", state=" + state, true); 613 mPhone.mCi.sendDeviceState(type, state, null); 614 } 615 616 /** 617 * Turn on/off the unsolicited response from the modem. 618 * 619 * @param newFilter See UnsolicitedResponseFilter in types.hal for the definition of each bit. 620 * @param force Always set the filter when true. 621 */ setUnsolResponseFilter(int newFilter, boolean force)622 private void setUnsolResponseFilter(int newFilter, boolean force) { 623 if (force || newFilter != mUnsolicitedResponseFilter) { 624 log("old filter: " + mUnsolicitedResponseFilter + ", new filter: " + newFilter, true); 625 mPhone.mCi.setUnsolResponseFilter(newFilter, null); 626 mUnsolicitedResponseFilter = newFilter; 627 } 628 } 629 setSignalStrengthReportingCriteria()630 private void setSignalStrengthReportingCriteria() { 631 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSSI, 632 AccessNetworkThresholds.GERAN, AccessNetworkType.GERAN, true); 633 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSCP, 634 AccessNetworkThresholds.UTRAN, AccessNetworkType.UTRAN, true); 635 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSRP, 636 AccessNetworkThresholds.EUTRAN_RSRP, AccessNetworkType.EUTRAN, true); 637 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSSI, 638 AccessNetworkThresholds.CDMA2000, AccessNetworkType.CDMA2000, true); 639 if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) { 640 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSRQ, 641 AccessNetworkThresholds.EUTRAN_RSRQ, AccessNetworkType.EUTRAN, false); 642 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSSNR, 643 AccessNetworkThresholds.EUTRAN_RSSNR, AccessNetworkType.EUTRAN, true); 644 645 // Defaultly we only need SSRSRP for NGRAN signal criteria reporting 646 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_SSRSRP, 647 AccessNetworkThresholds.NGRAN_RSRSRP, AccessNetworkType.NGRAN, true); 648 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_SSRSRQ, 649 AccessNetworkThresholds.NGRAN_RSRSRQ, AccessNetworkType.NGRAN, false); 650 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_SSSINR, 651 AccessNetworkThresholds.NGRAN_SSSINR, AccessNetworkType.NGRAN, false); 652 } 653 } 654 setLinkCapacityReportingCriteria()655 private void setLinkCapacityReportingCriteria() { 656 mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS, 657 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.GERAN); 658 mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS, 659 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.UTRAN); 660 mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS, 661 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.EUTRAN); 662 mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS, 663 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.CDMA2000); 664 if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) { 665 mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS, 666 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.NGRAN); 667 } 668 } 669 setCellInfoMinInterval(int rate)670 private void setCellInfoMinInterval(int rate) { 671 mPhone.setCellInfoMinInterval(rate); 672 } 673 674 /** 675 * @return True if the device is currently in power save mode. 676 * See {@link android.os.BatteryManager#isPowerSaveMode BatteryManager.isPowerSaveMode()}. 677 */ isPowerSaveModeOn()678 private boolean isPowerSaveModeOn() { 679 final PowerManager pm = (PowerManager) mPhone.getContext().getSystemService( 680 Context.POWER_SERVICE); 681 boolean retval = pm.isPowerSaveMode(); 682 log("isPowerSaveModeOn=" + retval, true); 683 return retval; 684 } 685 686 /** 687 * @return Return true if the battery is currently considered to be charging. This means that 688 * the device is plugged in and is supplying sufficient power that the battery level is 689 * going up (or the battery is fully charged). 690 * See {@link android.os.BatteryManager#isCharging BatteryManager.isCharging()}. 691 */ isDeviceCharging()692 private boolean isDeviceCharging() { 693 final BatteryManager bm = (BatteryManager) mPhone.getContext().getSystemService( 694 Context.BATTERY_SERVICE); 695 boolean retval = bm.isCharging(); 696 log("isDeviceCharging=" + retval, true); 697 return retval; 698 } 699 700 /** 701 * @return True if one the device's screen (e.g. main screen, wifi display, HDMI display etc...) 702 * is on. 703 */ isScreenOn()704 private boolean isScreenOn() { 705 // Note that we don't listen to Intent.SCREEN_ON and Intent.SCREEN_OFF because they are no 706 // longer adequate for monitoring the screen state since they are not sent in cases where 707 // the screen is turned off transiently such as due to the proximity sensor. 708 final DisplayManager dm = (DisplayManager) mPhone.getContext().getSystemService( 709 Context.DISPLAY_SERVICE); 710 Display[] displays = dm.getDisplays(); 711 712 if (displays != null) { 713 for (Display display : displays) { 714 // Anything other than STATE_ON is treated as screen off, such as STATE_DOZE, 715 // STATE_DOZE_SUSPEND, etc... 716 if (display.getState() == Display.STATE_ON) { 717 log("Screen on for display=" + display, true); 718 return true; 719 } 720 } 721 log("Screens all off", true); 722 return false; 723 } 724 725 log("No displays found", true); 726 return false; 727 } 728 729 /** 730 * @return True if car mode (Android Auto) is on. 731 */ isCarModeOn()732 private boolean isCarModeOn() { 733 final UiModeManager umm = (UiModeManager) mPhone.getContext().getSystemService( 734 Context.UI_MODE_SERVICE); 735 if (umm == null) return false; 736 boolean retval = umm.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR; 737 log("isCarModeOn=" + retval, true); 738 return retval; 739 } 740 741 /** 742 * Register for PhysicalChannelConfig notifications changed. On change, msg.obj will be an 743 * AsyncResult with a boolean result. AsyncResult.result is true if notifications are enabled 744 * and false if they are disabled. 745 * 746 * @param h Handler to notify 747 * @param what msg.what when the message is delivered 748 * @param obj AsyncResult.userObj when the message is delivered 749 */ registerForPhysicalChannelConfigNotifChanged(Handler h, int what, Object obj)750 public void registerForPhysicalChannelConfigNotifChanged(Handler h, int what, Object obj) { 751 Registrant r = new Registrant(h, what, obj); 752 mPhysicalChannelConfigRegistrants.add(r); 753 } 754 755 /** 756 * Unregister for PhysicalChannelConfig notifications changed. 757 * @param h Handler to notify 758 */ unregisterForPhysicalChannelConfigNotifChanged(Handler h)759 public void unregisterForPhysicalChannelConfigNotifChanged(Handler h) { 760 mPhysicalChannelConfigRegistrants.remove(h); 761 } 762 763 /** 764 * @param msg Debug message 765 * @param logIntoLocalLog True if log into the local log 766 */ log(String msg, boolean logIntoLocalLog)767 private void log(String msg, boolean logIntoLocalLog) { 768 if (DBG) Rlog.d(TAG, msg); 769 if (logIntoLocalLog) { 770 mLocalLog.log(msg); 771 } 772 } 773 774 /** 775 * Print the DeviceStateMonitor into the given stream. 776 * 777 * @param fd The raw file descriptor that the dump is being sent to. 778 * @param pw A PrintWriter to which the dump is to be set. 779 * @param args Additional arguments to the dump request. 780 */ dump(FileDescriptor fd, PrintWriter pw, String[] args)781 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 782 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 783 ipw.increaseIndent(); 784 ipw.println("mIsTetheringOn=" + mIsTetheringOn); 785 ipw.println("mIsScreenOn=" + mIsScreenOn); 786 ipw.println("mIsCharging=" + mIsCharging); 787 ipw.println("mIsPowerSaveOn=" + mIsPowerSaveOn); 788 ipw.println("mIsLowDataExpected=" + mIsLowDataExpected); 789 ipw.println("mIsCarModeOn=" + mIsCarModeOn); 790 ipw.println("mUnsolicitedResponseFilter=" + mUnsolicitedResponseFilter); 791 ipw.println("mIsWifiConnected=" + mIsWifiConnected); 792 ipw.println("mIsAlwaysSignalStrengthReportingEnabled=" 793 + mIsAlwaysSignalStrengthReportingEnabled); 794 ipw.println("Local logs:"); 795 ipw.increaseIndent(); 796 mLocalLog.dump(fd, ipw, args); 797 ipw.decreaseIndent(); 798 ipw.decreaseIndent(); 799 ipw.flush(); 800 } 801 802 /** 803 * dBm thresholds that correspond to changes in signal strength indications. 804 */ 805 private static final class AccessNetworkThresholds { 806 807 /** 808 * List of dBm thresholds for GERAN {@link AccessNetworkType}. 809 * 810 * Calculated from GSM asu level thresholds - TS 27.007 Sec 8.5 811 */ 812 public static final int[] GERAN = new int[] { 813 -109, 814 -103, 815 -97, 816 -89, 817 }; 818 819 /** 820 * List of default dBm thresholds for UTRAN {@link AccessNetworkType}. 821 * 822 * These thresholds are taken from the WCDMA RSCP defaults in {@link CarrierConfigManager}. 823 * See TS 27.007 Sec 8.69. 824 */ 825 public static final int[] UTRAN = new int[] { 826 -114, /* SIGNAL_STRENGTH_POOR */ 827 -104, /* SIGNAL_STRENGTH_MODERATE */ 828 -94, /* SIGNAL_STRENGTH_GOOD */ 829 -84 /* SIGNAL_STRENGTH_GREAT */ 830 }; 831 832 /** 833 * List of default dBm RSRP thresholds for EUTRAN {@link AccessNetworkType}. 834 * 835 * These thresholds are taken from the LTE RSRP defaults in {@link CarrierConfigManager}. 836 */ 837 public static final int[] EUTRAN_RSRP = new int[] { 838 -128, /* SIGNAL_STRENGTH_POOR */ 839 -118, /* SIGNAL_STRENGTH_MODERATE */ 840 -108, /* SIGNAL_STRENGTH_GOOD */ 841 -98, /* SIGNAL_STRENGTH_GREAT */ 842 }; 843 844 /** 845 * List of default dB RSRQ thresholds for EUTRAN {@link AccessNetworkType}. 846 * 847 * These thresholds are taken from the LTE RSRQ defaults in {@link CarrierConfigManager}. 848 */ 849 public static final int[] EUTRAN_RSRQ = new int[] { 850 -20, /* SIGNAL_STRENGTH_POOR */ 851 -17, /* SIGNAL_STRENGTH_MODERATE */ 852 -14, /* SIGNAL_STRENGTH_GOOD */ 853 -11 /* SIGNAL_STRENGTH_GREAT */ 854 }; 855 856 /** 857 * List of default dB RSSNR thresholds for EUTRAN {@link AccessNetworkType}. 858 * 859 * These thresholds are taken from the LTE RSSNR defaults in {@link CarrierConfigManager}. 860 */ 861 public static final int[] EUTRAN_RSSNR = new int[] { 862 -3, /* SIGNAL_STRENGTH_POOR */ 863 1, /* SIGNAL_STRENGTH_MODERATE */ 864 5, /* SIGNAL_STRENGTH_GOOD */ 865 13 /* SIGNAL_STRENGTH_GREAT */ 866 }; 867 868 /** 869 * List of dBm thresholds for CDMA2000 {@link AccessNetworkType}. 870 * 871 * These correspond to EVDO level thresholds. 872 */ 873 public static final int[] CDMA2000 = new int[] { 874 -105, 875 -90, 876 -75, 877 -65 878 }; 879 880 /** 881 * List of dB thresholds for NGRAN {@link AccessNetworkType} RSRSRP 882 */ 883 public static final int[] NGRAN_RSRSRP = new int[] { 884 -110, /* SIGNAL_STRENGTH_POOR */ 885 -90, /* SIGNAL_STRENGTH_MODERATE */ 886 -80, /* SIGNAL_STRENGTH_GOOD */ 887 -65, /* SIGNAL_STRENGTH_GREAT */ 888 }; 889 890 /** 891 * List of dB thresholds for NGRAN {@link AccessNetworkType} RSRSRP 892 */ 893 public static final int[] NGRAN_RSRSRQ = new int[] { 894 -31, /* SIGNAL_STRENGTH_POOR */ 895 -19, /* SIGNAL_STRENGTH_MODERATE */ 896 -7, /* SIGNAL_STRENGTH_GOOD */ 897 6 /* SIGNAL_STRENGTH_GREAT */ 898 }; 899 900 /** 901 * List of dB thresholds for NGRAN {@link AccessNetworkType} SSSINR 902 */ 903 public static final int[] NGRAN_SSSINR = new int[] { 904 -5, /* SIGNAL_STRENGTH_POOR */ 905 5, /* SIGNAL_STRENGTH_MODERATE */ 906 15, /* SIGNAL_STRENGTH_GOOD */ 907 30 /* SIGNAL_STRENGTH_GREAT */ 908 }; 909 } 910 911 /** 912 * Downlink reporting thresholds in kbps 913 * 914 * <p>Threshold values taken from FCC Speed Guide when available 915 * (https://www.fcc.gov/reports-research/guides/broadband-speed-guide) and Android WiFi speed 916 * labels (https://support.google.com/pixelphone/answer/2819519#strength_speed). 917 * 918 */ 919 private static final int[] LINK_CAPACITY_DOWNLINK_THRESHOLDS = new int[] { 920 100, // VoIP 921 500, // Web browsing 922 1000, // SD video streaming 923 5000, // HD video streaming 924 10000, // file downloading 925 20000, // 4K video streaming 926 50000, // LTE-Advanced speeds 927 75000, 928 100000, 929 200000, // 5G speeds 930 500000, 931 1000000, 932 1500000, 933 2000000 934 }; 935 936 /** Uplink reporting thresholds in kbps */ 937 private static final int[] LINK_CAPACITY_UPLINK_THRESHOLDS = new int[] { 938 100, // VoIP calls 939 500, 940 1000, // SD video calling 941 5000, // HD video calling 942 10000, // file uploading 943 20000, // 4K video calling 944 50000, 945 75000, 946 100000, 947 200000, 948 500000 949 }; 950 } 951