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.app.UiModeManager.PROJECTION_TYPE_AUTOMOTIVE; 20 import static android.hardware.radio.V1_0.DeviceStateType.CHARGING_STATE; 21 import static android.hardware.radio.V1_0.DeviceStateType.LOW_DATA_EXPECTED; 22 import static android.hardware.radio.V1_0.DeviceStateType.POWER_SAVE_MODE; 23 24 import android.app.UiModeManager; 25 import android.content.BroadcastReceiver; 26 import android.content.Context; 27 import android.content.Intent; 28 import android.content.IntentFilter; 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_AUTOMOTIVE_PROJECTION_STATE_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 * Automotive projection is active. True means the device is currently connected to Android 177 * Auto. This should be handled by mIsScreenOn, but the Android Auto display is private and not 178 * accessible by DeviceStateMonitor from DisplayMonitor. 179 */ 180 private boolean mIsAutomotiveProjectionActive; 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 default: 252 log("Unexpected broadcast intent: " + intent, false); 253 return; 254 } 255 sendMessage(msg); 256 } 257 }; 258 259 /** 260 * Device state monitor constructor. Note that each phone object should have its own device 261 * state monitor, meaning there will be two device monitors on the multi-sim device. 262 * 263 * @param phone Phone object 264 */ DeviceStateMonitor(Phone phone)265 public DeviceStateMonitor(Phone phone) { 266 mPhone = phone; 267 DisplayManager dm = (DisplayManager) phone.getContext().getSystemService( 268 Context.DISPLAY_SERVICE); 269 dm.registerDisplayListener(mDisplayListener, null); 270 271 mIsPowerSaveOn = isPowerSaveModeOn(); 272 mIsCharging = isDeviceCharging(); 273 mIsScreenOn = isScreenOn(); 274 mIsAutomotiveProjectionActive = isAutomotiveProjectionActive(); 275 // Assuming tethering is always off after boot up. 276 mIsTetheringOn = false; 277 mIsLowDataExpected = false; 278 279 log("DeviceStateMonitor mIsTetheringOn=" + mIsTetheringOn 280 + ", mIsScreenOn=" + mIsScreenOn 281 + ", mIsCharging=" + mIsCharging 282 + ", mIsPowerSaveOn=" + mIsPowerSaveOn 283 + ", mIsLowDataExpected=" + mIsLowDataExpected 284 + ", mIsAutomotiveProjectionActive=" + mIsAutomotiveProjectionActive 285 + ", mIsWifiConnected=" + mIsWifiConnected 286 + ", mIsAlwaysSignalStrengthReportingEnabled=" 287 + mIsAlwaysSignalStrengthReportingEnabled, false); 288 289 final IntentFilter filter = new IntentFilter(); 290 filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); 291 filter.addAction(BatteryManager.ACTION_CHARGING); 292 filter.addAction(BatteryManager.ACTION_DISCHARGING); 293 filter.addAction(TetheringManager.ACTION_TETHER_STATE_CHANGED); 294 mPhone.getContext().registerReceiver(mBroadcastReceiver, filter, null, mPhone); 295 296 mPhone.mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null); 297 mPhone.mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); 298 299 ConnectivityManager cm = (ConnectivityManager) phone.getContext().getSystemService( 300 Context.CONNECTIVITY_SERVICE); 301 cm.registerNetworkCallback(mWifiNetworkRequest, mNetworkCallback); 302 303 UiModeManager umm = (UiModeManager) phone.getContext().getSystemService( 304 Context.UI_MODE_SERVICE); 305 umm.addOnProjectionStateChangedListener(PROJECTION_TYPE_AUTOMOTIVE, 306 phone.getContext().getMainExecutor(), 307 (t, pkgs) -> { 308 Message msg = obtainMessage(EVENT_AUTOMOTIVE_PROJECTION_STATE_CHANGED); 309 msg.arg1 = Math.min(pkgs.size(), 1); 310 sendMessage(msg); 311 }); 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 public 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 automotive projection (Android Auto) is on. 407 return mIsCharging || mIsScreenOn || mIsTetheringOn || mIsAutomotiveProjectionActive; 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 Message msg = obtainMessage(EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH); 441 msg.arg1 = isEnable ? 1 : 0; 442 sendMessage(msg); 443 } 444 445 /** 446 * Message handler 447 * 448 * @param msg The message 449 */ 450 @Override handleMessage(Message msg)451 public void handleMessage(Message msg) { 452 log("handleMessage msg=" + msg, false); 453 switch (msg.what) { 454 case EVENT_RIL_CONNECTED: 455 case EVENT_RADIO_AVAILABLE: 456 onReset(); 457 break; 458 case EVENT_SCREEN_STATE_CHANGED: 459 case EVENT_POWER_SAVE_MODE_CHANGED: 460 case EVENT_CHARGING_STATE_CHANGED: 461 case EVENT_TETHERING_STATE_CHANGED: 462 case EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH: 463 case EVENT_AUTOMOTIVE_PROJECTION_STATE_CHANGED: 464 onUpdateDeviceState(msg.what, msg.arg1 != 0); 465 break; 466 case EVENT_WIFI_CONNECTION_CHANGED: 467 onUpdateDeviceState(msg.what, msg.arg1 != WIFI_UNAVAILABLE); 468 break; 469 default: 470 throw new IllegalStateException("Unexpected message arrives. msg = " + msg.what); 471 } 472 } 473 474 /** 475 * Update the device and send the information to the modem. 476 * 477 * @param eventType Device state event type 478 * @param state True if enabled/on, otherwise disabled/off. 479 */ onUpdateDeviceState(int eventType, boolean state)480 private void onUpdateDeviceState(int eventType, boolean state) { 481 final boolean shouldEnableBarringInfoReportsOld = shouldEnableBarringInfoReports(); 482 final boolean wasHighPowerEnabled = shouldEnableHighPowerConsumptionIndications(); 483 switch (eventType) { 484 case EVENT_SCREEN_STATE_CHANGED: 485 if (mIsScreenOn == state) return; 486 mIsScreenOn = state; 487 break; 488 case EVENT_CHARGING_STATE_CHANGED: 489 if (mIsCharging == state) return; 490 mIsCharging = state; 491 sendDeviceState(CHARGING_STATE, mIsCharging); 492 break; 493 case EVENT_TETHERING_STATE_CHANGED: 494 if (mIsTetheringOn == state) return; 495 mIsTetheringOn = state; 496 break; 497 case EVENT_POWER_SAVE_MODE_CHANGED: 498 if (mIsPowerSaveOn == state) return; 499 mIsPowerSaveOn = state; 500 sendDeviceState(POWER_SAVE_MODE, mIsPowerSaveOn); 501 break; 502 case EVENT_WIFI_CONNECTION_CHANGED: 503 if (mIsWifiConnected == state) return; 504 mIsWifiConnected = state; 505 break; 506 case EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH: 507 if (mIsAlwaysSignalStrengthReportingEnabled == state) return; 508 mIsAlwaysSignalStrengthReportingEnabled = state; 509 break; 510 case EVENT_AUTOMOTIVE_PROJECTION_STATE_CHANGED: 511 if (mIsAutomotiveProjectionActive == state) return; 512 mIsAutomotiveProjectionActive = state; 513 break; 514 default: 515 return; 516 } 517 518 final boolean isHighPowerEnabled = shouldEnableHighPowerConsumptionIndications(); 519 if (wasHighPowerEnabled != isHighPowerEnabled) { 520 mPhone.notifyDeviceIdleStateChanged(!isHighPowerEnabled /*isIdle*/); 521 } 522 523 final int newCellInfoMinInterval = computeCellInfoMinInterval(); 524 if (mCellInfoMinInterval != newCellInfoMinInterval) { 525 mCellInfoMinInterval = newCellInfoMinInterval; 526 setCellInfoMinInterval(mCellInfoMinInterval); 527 log("CellInfo Min Interval Updated to " + newCellInfoMinInterval, true); 528 } 529 530 if (mIsLowDataExpected != isLowDataExpected()) { 531 mIsLowDataExpected = !mIsLowDataExpected; 532 sendDeviceState(LOW_DATA_EXPECTED, mIsLowDataExpected); 533 } 534 535 // Registration Failure is always reported. 536 int newFilter = IndicationFilter.REGISTRATION_FAILURE; 537 538 if (shouldEnableSignalStrengthReports()) { 539 newFilter |= IndicationFilter.SIGNAL_STRENGTH; 540 } 541 542 if (shouldEnableFullNetworkStateReports()) { 543 newFilter |= IndicationFilter.FULL_NETWORK_STATE; 544 } 545 546 if (shouldEnableDataCallDormancyChangedReports()) { 547 newFilter |= IndicationFilter.DATA_CALL_DORMANCY_CHANGED; 548 } 549 550 if (shouldEnableLinkCapacityEstimateReports()) { 551 newFilter |= IndicationFilter.LINK_CAPACITY_ESTIMATE; 552 } 553 554 if (shouldEnablePhysicalChannelConfigReports()) { 555 newFilter |= IndicationFilter.PHYSICAL_CHANNEL_CONFIG; 556 } 557 558 final boolean shouldEnableBarringInfoReports = shouldEnableBarringInfoReports(); 559 if (shouldEnableBarringInfoReports) { 560 newFilter |= IndicationFilter.BARRING_INFO; 561 } 562 563 // notify PhysicalChannelConfig registrants if state changes 564 if ((newFilter & IndicationFilter.PHYSICAL_CHANNEL_CONFIG) 565 != (mUnsolicitedResponseFilter & IndicationFilter.PHYSICAL_CHANNEL_CONFIG)) { 566 mPhysicalChannelConfigRegistrants.notifyResult( 567 (newFilter & IndicationFilter.PHYSICAL_CHANNEL_CONFIG) != 0); 568 } 569 570 setUnsolResponseFilter(newFilter, false); 571 572 // Pull barring info AFTER setting filter, the order matters 573 if (shouldEnableBarringInfoReports && !shouldEnableBarringInfoReportsOld) { 574 if (DBG) log("Manually pull barring info...", true); 575 // use a null message since we don't care of receiving response 576 mPhone.mCi.getBarringInfo(null); 577 } 578 } 579 580 /** 581 * Called when RIL is connected during boot up or radio becomes available after modem restart. 582 * 583 * When modem crashes, if the user turns the screen off before RIL reconnects, device 584 * state and filter cannot be sent to modem. Resend the state here so that modem 585 * has the correct state (to stop signal strength reporting, etc). 586 */ onReset()587 private void onReset() { 588 log("onReset.", true); 589 sendDeviceState(CHARGING_STATE, mIsCharging); 590 sendDeviceState(LOW_DATA_EXPECTED, mIsLowDataExpected); 591 sendDeviceState(POWER_SAVE_MODE, mIsPowerSaveOn); 592 setUnsolResponseFilter(mUnsolicitedResponseFilter, true); 593 setSignalStrengthReportingCriteria(); 594 setLinkCapacityReportingCriteria(); 595 setCellInfoMinInterval(mCellInfoMinInterval); 596 } 597 598 /** 599 * Convert the device state type into string 600 * 601 * @param type Device state type 602 * @return The converted string 603 */ deviceTypeToString(int type)604 private String deviceTypeToString(int type) { 605 switch (type) { 606 case CHARGING_STATE: return "CHARGING_STATE"; 607 case LOW_DATA_EXPECTED: return "LOW_DATA_EXPECTED"; 608 case POWER_SAVE_MODE: return "POWER_SAVE_MODE"; 609 default: return "UNKNOWN"; 610 } 611 } 612 613 /** 614 * Send the device state to the modem. 615 * 616 * @param type Device state type. See DeviceStateType defined in types.hal. 617 * @param state True if enabled/on, otherwise disabled/off 618 */ sendDeviceState(int type, boolean state)619 private void sendDeviceState(int type, boolean state) { 620 log("send type: " + deviceTypeToString(type) + ", state=" + state, true); 621 mPhone.mCi.sendDeviceState(type, state, null); 622 } 623 624 /** 625 * Turn on/off the unsolicited response from the modem. 626 * 627 * @param newFilter See UnsolicitedResponseFilter in types.hal for the definition of each bit. 628 * @param force Always set the filter when true. 629 */ setUnsolResponseFilter(int newFilter, boolean force)630 private void setUnsolResponseFilter(int newFilter, boolean force) { 631 if (force || newFilter != mUnsolicitedResponseFilter) { 632 log("old filter: " + mUnsolicitedResponseFilter + ", new filter: " + newFilter, true); 633 mPhone.mCi.setUnsolResponseFilter(newFilter, null); 634 mUnsolicitedResponseFilter = newFilter; 635 } 636 } 637 setSignalStrengthReportingCriteria()638 private void setSignalStrengthReportingCriteria() { 639 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI, 640 AccessNetworkThresholds.GERAN, AccessNetworkType.GERAN, true); 641 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP, 642 AccessNetworkThresholds.UTRAN, AccessNetworkType.UTRAN, true); 643 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP, 644 AccessNetworkThresholds.EUTRAN_RSRP, AccessNetworkType.EUTRAN, true); 645 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI, 646 AccessNetworkThresholds.CDMA2000, AccessNetworkType.CDMA2000, true); 647 if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) { 648 mPhone.setSignalStrengthReportingCriteria( 649 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ, 650 AccessNetworkThresholds.EUTRAN_RSRQ, AccessNetworkType.EUTRAN, false); 651 mPhone.setSignalStrengthReportingCriteria( 652 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR, 653 AccessNetworkThresholds.EUTRAN_RSSNR, AccessNetworkType.EUTRAN, true); 654 655 // Defaultly we only need SSRSRP for NGRAN signal criteria reporting 656 mPhone.setSignalStrengthReportingCriteria( 657 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP, 658 AccessNetworkThresholds.NGRAN_RSRSRP, AccessNetworkType.NGRAN, true); 659 mPhone.setSignalStrengthReportingCriteria( 660 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ, 661 AccessNetworkThresholds.NGRAN_RSRSRQ, AccessNetworkType.NGRAN, false); 662 mPhone.setSignalStrengthReportingCriteria( 663 SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR, 664 AccessNetworkThresholds.NGRAN_SSSINR, AccessNetworkType.NGRAN, false); 665 } 666 } 667 setLinkCapacityReportingCriteria()668 private void setLinkCapacityReportingCriteria() { 669 mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS, 670 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.GERAN); 671 mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS, 672 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.UTRAN); 673 mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS, 674 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.EUTRAN); 675 mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS, 676 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.CDMA2000); 677 if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) { 678 mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS, 679 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.NGRAN); 680 } 681 } 682 setCellInfoMinInterval(int rate)683 private void setCellInfoMinInterval(int rate) { 684 mPhone.setCellInfoMinInterval(rate); 685 } 686 687 /** 688 * @return True if the device is currently in power save mode. 689 * See {@link android.os.BatteryManager#isPowerSaveMode BatteryManager.isPowerSaveMode()}. 690 */ isPowerSaveModeOn()691 private boolean isPowerSaveModeOn() { 692 final PowerManager pm = (PowerManager) mPhone.getContext().getSystemService( 693 Context.POWER_SERVICE); 694 boolean retval = pm.isPowerSaveMode(); 695 log("isPowerSaveModeOn=" + retval, true); 696 return retval; 697 } 698 699 /** 700 * @return Return true if the battery is currently considered to be charging. This means that 701 * the device is plugged in and is supplying sufficient power that the battery level is 702 * going up (or the battery is fully charged). 703 * See {@link android.os.BatteryManager#isCharging BatteryManager.isCharging()}. 704 */ isDeviceCharging()705 private boolean isDeviceCharging() { 706 final BatteryManager bm = (BatteryManager) mPhone.getContext().getSystemService( 707 Context.BATTERY_SERVICE); 708 boolean retval = bm.isCharging(); 709 log("isDeviceCharging=" + retval, true); 710 return retval; 711 } 712 713 /** 714 * @return True if one the device's screen (e.g. main screen, wifi display, HDMI display etc...) 715 * is on. 716 */ isScreenOn()717 private boolean isScreenOn() { 718 // Note that we don't listen to Intent.SCREEN_ON and Intent.SCREEN_OFF because they are no 719 // longer adequate for monitoring the screen state since they are not sent in cases where 720 // the screen is turned off transiently such as due to the proximity sensor. 721 final DisplayManager dm = (DisplayManager) mPhone.getContext().getSystemService( 722 Context.DISPLAY_SERVICE); 723 Display[] displays = dm.getDisplays(); 724 725 if (displays != null) { 726 for (Display display : displays) { 727 // Anything other than STATE_ON is treated as screen off, such as STATE_DOZE, 728 // STATE_DOZE_SUSPEND, etc... 729 if (display.getState() == Display.STATE_ON) { 730 log("Screen on for display=" + display, true); 731 return true; 732 } 733 } 734 log("Screens all off", true); 735 return false; 736 } 737 738 log("No displays found", true); 739 return false; 740 } 741 742 /** 743 * @return True if automotive projection (Android Auto) is active. 744 */ isAutomotiveProjectionActive()745 private boolean isAutomotiveProjectionActive() { 746 final UiModeManager umm = (UiModeManager) mPhone.getContext().getSystemService( 747 Context.UI_MODE_SERVICE); 748 if (umm == null) return false; 749 boolean isAutomotiveProjectionActive = (umm.getActiveProjectionTypes() 750 & PROJECTION_TYPE_AUTOMOTIVE) != 0; 751 log("isAutomotiveProjectionActive=" + isAutomotiveProjectionActive, true); 752 return isAutomotiveProjectionActive; 753 } 754 755 /** 756 * Register for PhysicalChannelConfig notifications changed. On change, msg.obj will be an 757 * AsyncResult with a boolean result. AsyncResult.result is true if notifications are enabled 758 * and false if they are disabled. 759 * 760 * @param h Handler to notify 761 * @param what msg.what when the message is delivered 762 * @param obj AsyncResult.userObj when the message is delivered 763 */ registerForPhysicalChannelConfigNotifChanged(Handler h, int what, Object obj)764 public void registerForPhysicalChannelConfigNotifChanged(Handler h, int what, Object obj) { 765 Registrant r = new Registrant(h, what, obj); 766 mPhysicalChannelConfigRegistrants.add(r); 767 } 768 769 /** 770 * Unregister for PhysicalChannelConfig notifications changed. 771 * @param h Handler to notify 772 */ unregisterForPhysicalChannelConfigNotifChanged(Handler h)773 public void unregisterForPhysicalChannelConfigNotifChanged(Handler h) { 774 mPhysicalChannelConfigRegistrants.remove(h); 775 } 776 777 /** 778 * @param msg Debug message 779 * @param logIntoLocalLog True if log into the local log 780 */ log(String msg, boolean logIntoLocalLog)781 private void log(String msg, boolean logIntoLocalLog) { 782 if (DBG) Rlog.d(TAG, msg); 783 if (logIntoLocalLog) { 784 mLocalLog.log(msg); 785 } 786 } 787 788 /** 789 * Print the DeviceStateMonitor into the given stream. 790 * 791 * @param fd The raw file descriptor that the dump is being sent to. 792 * @param pw A PrintWriter to which the dump is to be set. 793 * @param args Additional arguments to the dump request. 794 */ dump(FileDescriptor fd, PrintWriter pw, String[] args)795 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 796 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 797 ipw.increaseIndent(); 798 ipw.println("mIsTetheringOn=" + mIsTetheringOn); 799 ipw.println("mIsScreenOn=" + mIsScreenOn); 800 ipw.println("mIsCharging=" + mIsCharging); 801 ipw.println("mIsPowerSaveOn=" + mIsPowerSaveOn); 802 ipw.println("mIsLowDataExpected=" + mIsLowDataExpected); 803 ipw.println("mIsAutomotiveProjectionActive=" + mIsAutomotiveProjectionActive); 804 ipw.println("mUnsolicitedResponseFilter=" + mUnsolicitedResponseFilter); 805 ipw.println("mIsWifiConnected=" + mIsWifiConnected); 806 ipw.println("mIsAlwaysSignalStrengthReportingEnabled=" 807 + mIsAlwaysSignalStrengthReportingEnabled); 808 ipw.println("Local logs:"); 809 ipw.increaseIndent(); 810 mLocalLog.dump(fd, ipw, args); 811 ipw.decreaseIndent(); 812 ipw.decreaseIndent(); 813 ipw.flush(); 814 } 815 816 /** 817 * dBm thresholds that correspond to changes in signal strength indications. 818 */ 819 private static final class AccessNetworkThresholds { 820 821 /** 822 * List of dBm thresholds for GERAN {@link AccessNetworkType}. 823 * 824 * Calculated from GSM asu level thresholds - TS 27.007 Sec 8.5 825 */ 826 public static final int[] GERAN = new int[] { 827 -109, 828 -103, 829 -97, 830 -89, 831 }; 832 833 /** 834 * List of default dBm thresholds for UTRAN {@link AccessNetworkType}. 835 * 836 * These thresholds are taken from the WCDMA RSCP defaults in {@link CarrierConfigManager}. 837 * See TS 27.007 Sec 8.69. 838 */ 839 public static final int[] UTRAN = new int[] { 840 -114, /* SIGNAL_STRENGTH_POOR */ 841 -104, /* SIGNAL_STRENGTH_MODERATE */ 842 -94, /* SIGNAL_STRENGTH_GOOD */ 843 -84 /* SIGNAL_STRENGTH_GREAT */ 844 }; 845 846 /** 847 * List of default dBm RSRP thresholds for EUTRAN {@link AccessNetworkType}. 848 * 849 * These thresholds are taken from the LTE RSRP defaults in {@link CarrierConfigManager}. 850 */ 851 public static final int[] EUTRAN_RSRP = new int[] { 852 -128, /* SIGNAL_STRENGTH_POOR */ 853 -118, /* SIGNAL_STRENGTH_MODERATE */ 854 -108, /* SIGNAL_STRENGTH_GOOD */ 855 -98, /* SIGNAL_STRENGTH_GREAT */ 856 }; 857 858 /** 859 * List of default dB RSRQ thresholds for EUTRAN {@link AccessNetworkType}. 860 * 861 * These thresholds are taken from the LTE RSRQ defaults in {@link CarrierConfigManager}. 862 */ 863 public static final int[] EUTRAN_RSRQ = new int[] { 864 -20, /* SIGNAL_STRENGTH_POOR */ 865 -17, /* SIGNAL_STRENGTH_MODERATE */ 866 -14, /* SIGNAL_STRENGTH_GOOD */ 867 -11 /* SIGNAL_STRENGTH_GREAT */ 868 }; 869 870 /** 871 * List of default dB RSSNR thresholds for EUTRAN {@link AccessNetworkType}. 872 * 873 * These thresholds are taken from the LTE RSSNR defaults in {@link CarrierConfigManager}. 874 */ 875 public static final int[] EUTRAN_RSSNR = new int[] { 876 -3, /* SIGNAL_STRENGTH_POOR */ 877 1, /* SIGNAL_STRENGTH_MODERATE */ 878 5, /* SIGNAL_STRENGTH_GOOD */ 879 13 /* SIGNAL_STRENGTH_GREAT */ 880 }; 881 882 /** 883 * List of dBm thresholds for CDMA2000 {@link AccessNetworkType}. 884 * 885 * These correspond to EVDO level thresholds. 886 */ 887 public static final int[] CDMA2000 = new int[] { 888 -105, 889 -90, 890 -75, 891 -65 892 }; 893 894 /** 895 * List of dB thresholds for NGRAN {@link AccessNetworkType} RSRSRP 896 */ 897 public static final int[] NGRAN_RSRSRP = new int[] { 898 -110, /* SIGNAL_STRENGTH_POOR */ 899 -90, /* SIGNAL_STRENGTH_MODERATE */ 900 -80, /* SIGNAL_STRENGTH_GOOD */ 901 -65, /* SIGNAL_STRENGTH_GREAT */ 902 }; 903 904 /** 905 * List of dB thresholds for NGRAN {@link AccessNetworkType} RSRSRP 906 */ 907 public static final int[] NGRAN_RSRSRQ = new int[] { 908 -31, /* SIGNAL_STRENGTH_POOR */ 909 -19, /* SIGNAL_STRENGTH_MODERATE */ 910 -7, /* SIGNAL_STRENGTH_GOOD */ 911 6 /* SIGNAL_STRENGTH_GREAT */ 912 }; 913 914 /** 915 * List of dB thresholds for NGRAN {@link AccessNetworkType} SSSINR 916 */ 917 public static final int[] NGRAN_SSSINR = new int[] { 918 -5, /* SIGNAL_STRENGTH_POOR */ 919 5, /* SIGNAL_STRENGTH_MODERATE */ 920 15, /* SIGNAL_STRENGTH_GOOD */ 921 30 /* SIGNAL_STRENGTH_GREAT */ 922 }; 923 } 924 925 /** 926 * Downlink reporting thresholds in kbps 927 * 928 * <p>Threshold values taken from FCC Speed Guide when available 929 * (https://www.fcc.gov/reports-research/guides/broadband-speed-guide) and Android WiFi speed 930 * labels (https://support.google.com/pixelphone/answer/2819519#strength_speed). 931 * 932 */ 933 private static final int[] LINK_CAPACITY_DOWNLINK_THRESHOLDS = new int[] { 934 100, // VoIP 935 500, // Web browsing 936 1000, // SD video streaming 937 5000, // HD video streaming 938 10000, // file downloading 939 20000, // 4K video streaming 940 50000, // LTE-Advanced speeds 941 75000, 942 100000, 943 200000, // 5G speeds 944 500000, 945 1000000, 946 1500000, 947 2000000 948 }; 949 950 /** Uplink reporting thresholds in kbps */ 951 private static final int[] LINK_CAPACITY_UPLINK_THRESHOLDS = new int[] { 952 100, // VoIP calls 953 500, 954 1000, // SD video calling 955 5000, // HD video calling 956 10000, // file uploading 957 20000, // 4K video calling 958 50000, 959 75000, 960 100000, 961 200000, 962 500000 963 }; 964 } 965