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.content.BroadcastReceiver; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.content.IntentFilter; 27 import android.hardware.display.DisplayManager; 28 import android.hardware.radio.V1_2.IndicationFilter; 29 import android.net.ConnectivityManager; 30 import android.os.BatteryManager; 31 import android.os.Handler; 32 import android.os.Message; 33 import android.os.PowerManager; 34 import android.telephony.AccessNetworkConstants.AccessNetworkType; 35 import android.telephony.CarrierConfigManager; 36 import android.telephony.Rlog; 37 import android.telephony.TelephonyManager; 38 import android.util.LocalLog; 39 import android.util.SparseIntArray; 40 import android.view.Display; 41 42 import com.android.internal.util.IndentingPrintWriter; 43 44 import java.io.FileDescriptor; 45 import java.io.PrintWriter; 46 import java.util.ArrayList; 47 48 /** 49 * The device state monitor monitors the device state such as charging state, power saving sate, 50 * and then passes down the information to the radio modem for the modem to perform its own 51 * proprietary power saving strategy. Device state monitor also turns off the unsolicited 52 * response from the modem when the device does not need to receive it, for example, device's 53 * screen is off and does not have activities like tethering, remote display, etc...This effectively 54 * prevents the CPU from waking up by those unnecessary unsolicited responses such as signal 55 * strength update. 56 */ 57 public class DeviceStateMonitor extends Handler { 58 protected static final boolean DBG = false; /* STOPSHIP if true */ 59 protected static final String TAG = DeviceStateMonitor.class.getSimpleName(); 60 61 private static final int EVENT_RIL_CONNECTED = 0; 62 private static final int EVENT_UPDATE_MODE_CHANGED = 1; 63 private static final int EVENT_SCREEN_STATE_CHANGED = 2; 64 private static final int EVENT_POWER_SAVE_MODE_CHANGED = 3; 65 private static final int EVENT_CHARGING_STATE_CHANGED = 4; 66 private static final int EVENT_TETHERING_STATE_CHANGED = 5; 67 68 // TODO(b/74006656) load hysteresis values from a property when DeviceStateMonitor starts 69 private static final int HYSTERESIS_KBPS = 50; 70 71 private final Phone mPhone; 72 73 private final LocalLog mLocalLog = new LocalLog(100); 74 75 /** 76 * Flag for wifi/usb/bluetooth tethering turned on or not 77 */ 78 private boolean mIsTetheringOn; 79 80 /** 81 * Screen state provided by Display Manager. True indicates one of the screen is on, otherwise 82 * all off. 83 */ 84 private boolean mIsScreenOn; 85 86 /** 87 * Indicating the device is plugged in and is supplying sufficient power that the battery level 88 * is going up (or the battery is fully charged). See BatteryManager.isCharging() for the 89 * details 90 */ 91 private boolean mIsCharging; 92 93 /** 94 * Flag for device power save mode. See PowerManager.isPowerSaveMode() for the details. 95 * Note that it is not possible both mIsCharging and mIsPowerSaveOn are true at the same time. 96 * The system will automatically end power save mode when the device starts charging. 97 */ 98 private boolean mIsPowerSaveOn; 99 100 /** 101 * Low data expected mode. True indicates low data traffic is expected, for example, when the 102 * device is idle (e.g. screen is off and not doing tethering in the background). Note this 103 * doesn't mean no data is expected. 104 */ 105 private boolean mIsLowDataExpected; 106 107 private SparseIntArray mUpdateModes = new SparseIntArray(); 108 109 /** 110 * The unsolicited response filter. See IndicationFilter defined in types.hal for the definition 111 * of each bit. 112 */ 113 private int mUnsolicitedResponseFilter = IndicationFilter.ALL; 114 115 private final DisplayManager.DisplayListener mDisplayListener = 116 new DisplayManager.DisplayListener() { 117 @Override 118 public void onDisplayAdded(int displayId) { } 119 120 @Override 121 public void onDisplayRemoved(int displayId) { } 122 123 @Override 124 public void onDisplayChanged(int displayId) { 125 boolean screenOn = isScreenOn(); 126 Message msg = obtainMessage(EVENT_SCREEN_STATE_CHANGED); 127 msg.arg1 = screenOn ? 1 : 0; 128 sendMessage(msg); 129 } 130 }; 131 132 /** 133 * Device state broadcast receiver 134 */ 135 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 136 @Override 137 public void onReceive(Context context, Intent intent) { 138 log("received: " + intent, true); 139 140 Message msg; 141 switch (intent.getAction()) { 142 case PowerManager.ACTION_POWER_SAVE_MODE_CHANGED: 143 msg = obtainMessage(EVENT_POWER_SAVE_MODE_CHANGED); 144 msg.arg1 = isPowerSaveModeOn() ? 1 : 0; 145 log("Power Save mode " + ((msg.arg1 == 1) ? "on" : "off"), true); 146 break; 147 case BatteryManager.ACTION_CHARGING: 148 msg = obtainMessage(EVENT_CHARGING_STATE_CHANGED); 149 msg.arg1 = 1; // charging 150 break; 151 case BatteryManager.ACTION_DISCHARGING: 152 msg = obtainMessage(EVENT_CHARGING_STATE_CHANGED); 153 msg.arg1 = 0; // not charging 154 break; 155 case ConnectivityManager.ACTION_TETHER_STATE_CHANGED: 156 ArrayList<String> activeTetherIfaces = intent.getStringArrayListExtra( 157 ConnectivityManager.EXTRA_ACTIVE_TETHER); 158 159 boolean isTetheringOn = activeTetherIfaces != null 160 && activeTetherIfaces.size() > 0; 161 log("Tethering " + (isTetheringOn ? "on" : "off"), true); 162 msg = obtainMessage(EVENT_TETHERING_STATE_CHANGED); 163 msg.arg1 = isTetheringOn ? 1 : 0; 164 break; 165 default: 166 log("Unexpected broadcast intent: " + intent, false); 167 return; 168 } 169 sendMessage(msg); 170 } 171 }; 172 173 /** 174 * Device state monitor constructor. Note that each phone object should have its own device 175 * state monitor, meaning there will be two device monitors on the multi-sim device. 176 * 177 * @param phone Phone object 178 */ DeviceStateMonitor(Phone phone)179 public DeviceStateMonitor(Phone phone) { 180 mPhone = phone; 181 DisplayManager dm = (DisplayManager) phone.getContext().getSystemService( 182 Context.DISPLAY_SERVICE); 183 dm.registerDisplayListener(mDisplayListener, null); 184 185 mIsPowerSaveOn = isPowerSaveModeOn(); 186 mIsCharging = isDeviceCharging(); 187 mIsScreenOn = isScreenOn(); 188 // Assuming tethering is always off after boot up. 189 mIsTetheringOn = false; 190 mIsLowDataExpected = false; 191 192 log("DeviceStateMonitor mIsPowerSaveOn=" + mIsPowerSaveOn + ",mIsScreenOn=" 193 + mIsScreenOn + ",mIsCharging=" + mIsCharging, false); 194 195 final IntentFilter filter = new IntentFilter(); 196 filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); 197 filter.addAction(BatteryManager.ACTION_CHARGING); 198 filter.addAction(BatteryManager.ACTION_DISCHARGING); 199 filter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); 200 mPhone.getContext().registerReceiver(mBroadcastReceiver, filter, null, mPhone); 201 202 mPhone.mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null); 203 } 204 205 /** 206 * @return True if low data is expected 207 */ isLowDataExpected()208 private boolean isLowDataExpected() { 209 return !mIsCharging && !mIsTetheringOn && !mIsScreenOn; 210 } 211 212 /** 213 * @return True if signal strength update should be turned off. 214 */ shouldTurnOffSignalStrength()215 private boolean shouldTurnOffSignalStrength() { 216 // We should not turn off signal strength update if one of the following condition is true. 217 // 1. The device is charging. 218 // 2. When the screen is on. 219 // 3. When the update mode is IGNORE_SCREEN_OFF. This mode is used in some corner cases like 220 // when Bluetooth carkit is connected, we still want to update signal strength even 221 // when screen is off. 222 if (mIsCharging || mIsScreenOn 223 || mUpdateModes.get(TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH) 224 == TelephonyManager.INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF) { 225 return false; 226 } 227 228 // In all other cases, we turn off signal strength update. 229 return true; 230 } 231 232 /** 233 * @return True if full network update should be turned off. Only significant changes will 234 * trigger the network update unsolicited response. 235 */ shouldTurnOffFullNetworkUpdate()236 private boolean shouldTurnOffFullNetworkUpdate() { 237 // We should not turn off full network update if one of the following condition is true. 238 // 1. The device is charging. 239 // 2. When the screen is on. 240 // 3. When data tethering is on. 241 // 4. When the update mode is IGNORE_SCREEN_OFF. 242 if (mIsCharging || mIsScreenOn || mIsTetheringOn 243 || mUpdateModes.get(TelephonyManager.INDICATION_FILTER_FULL_NETWORK_STATE) 244 == TelephonyManager.INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF) { 245 return false; 246 } 247 248 // In all other cases, we turn off full network state update. 249 return true; 250 } 251 252 /** 253 * @return True if data dormancy status update should be turned off. 254 */ shouldTurnOffDormancyUpdate()255 private boolean shouldTurnOffDormancyUpdate() { 256 // We should not turn off data dormancy update if one of the following condition is true. 257 // 1. The device is charging. 258 // 2. When the screen is on. 259 // 3. When data tethering is on. 260 // 4. When the update mode is IGNORE_SCREEN_OFF. 261 if (mIsCharging || mIsScreenOn || mIsTetheringOn 262 || mUpdateModes.get(TelephonyManager.INDICATION_FILTER_DATA_CALL_DORMANCY_CHANGED) 263 == TelephonyManager.INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF) { 264 return false; 265 } 266 267 // In all other cases, we turn off data dormancy update. 268 return true; 269 } 270 271 /** 272 * @return True if link capacity estimate update should be turned off. 273 */ shouldTurnOffLinkCapacityEstimate()274 private boolean shouldTurnOffLinkCapacityEstimate() { 275 // We should not turn off link capacity update if one of the following condition is true. 276 // 1. The device is charging. 277 // 2. When the screen is on. 278 // 3. When data tethering is on. 279 // 4. When the update mode is IGNORE_SCREEN_OFF. 280 if (mIsCharging || mIsScreenOn || mIsTetheringOn 281 || mUpdateModes.get(TelephonyManager.INDICATION_FILTER_LINK_CAPACITY_ESTIMATE) 282 == TelephonyManager.INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF) { 283 return false; 284 } 285 286 // In all other cases, we turn off link capacity update. 287 return true; 288 } 289 290 /** 291 * @return True if physical channel config update should be turned off. 292 */ shouldTurnOffPhysicalChannelConfig()293 private boolean shouldTurnOffPhysicalChannelConfig() { 294 // We should not turn off physical channel update if one of the following condition is true. 295 // 1. The device is charging. 296 // 2. When the screen is on. 297 // 3. When data tethering is on. 298 // 4. When the update mode is IGNORE_SCREEN_OFF. 299 if (mIsCharging || mIsScreenOn || mIsTetheringOn 300 || mUpdateModes.get(TelephonyManager.INDICATION_FILTER_PHYSICAL_CHANNEL_CONFIG) 301 == TelephonyManager.INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF) { 302 return false; 303 } 304 305 // In all other cases, we turn off physical channel config update. 306 return true; 307 } 308 309 /** 310 * Set indication update mode 311 * 312 * @param filters Indication filters. Should be a bitmask of INDICATION_FILTER_XXX. 313 * @param mode The voice activation state 314 */ setIndicationUpdateMode(int filters, int mode)315 public void setIndicationUpdateMode(int filters, int mode) { 316 sendMessage(obtainMessage(EVENT_UPDATE_MODE_CHANGED, filters, mode)); 317 } 318 onSetIndicationUpdateMode(int filters, int mode)319 private void onSetIndicationUpdateMode(int filters, int mode) { 320 if ((filters & TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH) != 0) { 321 mUpdateModes.put(TelephonyManager.INDICATION_FILTER_SIGNAL_STRENGTH, mode); 322 } 323 if ((filters & TelephonyManager.INDICATION_FILTER_FULL_NETWORK_STATE) != 0) { 324 mUpdateModes.put(TelephonyManager.INDICATION_FILTER_FULL_NETWORK_STATE, mode); 325 } 326 if ((filters & TelephonyManager.INDICATION_FILTER_DATA_CALL_DORMANCY_CHANGED) != 0) { 327 mUpdateModes.put(TelephonyManager.INDICATION_FILTER_DATA_CALL_DORMANCY_CHANGED, mode); 328 } 329 if ((filters & TelephonyManager.INDICATION_FILTER_LINK_CAPACITY_ESTIMATE) != 0) { 330 mUpdateModes.put(TelephonyManager.INDICATION_FILTER_LINK_CAPACITY_ESTIMATE, mode); 331 } 332 if ((filters & TelephonyManager.INDICATION_FILTER_PHYSICAL_CHANNEL_CONFIG) != 0) { 333 mUpdateModes.put(TelephonyManager.INDICATION_FILTER_PHYSICAL_CHANNEL_CONFIG, mode); 334 } 335 } 336 337 /** 338 * Message handler 339 * 340 * @param msg The message 341 */ 342 @Override handleMessage(Message msg)343 public void handleMessage(Message msg) { 344 log("handleMessage msg=" + msg, false); 345 switch (msg.what) { 346 case EVENT_RIL_CONNECTED: 347 onRilConnected(); 348 break; 349 case EVENT_UPDATE_MODE_CHANGED: 350 onSetIndicationUpdateMode(msg.arg1, msg.arg2); 351 break; 352 case EVENT_SCREEN_STATE_CHANGED: 353 case EVENT_POWER_SAVE_MODE_CHANGED: 354 case EVENT_CHARGING_STATE_CHANGED: 355 case EVENT_TETHERING_STATE_CHANGED: 356 onUpdateDeviceState(msg.what, msg.arg1 != 0); 357 break; 358 default: 359 throw new IllegalStateException("Unexpected message arrives. msg = " + msg.what); 360 } 361 } 362 363 /** 364 * Update the device and send the information to the modem. 365 * 366 * @param eventType Device state event type 367 * @param state True if enabled/on, otherwise disabled/off. 368 */ onUpdateDeviceState(int eventType, boolean state)369 private void onUpdateDeviceState(int eventType, boolean state) { 370 switch (eventType) { 371 case EVENT_SCREEN_STATE_CHANGED: 372 if (mIsScreenOn == state) return; 373 mIsScreenOn = state; 374 break; 375 case EVENT_CHARGING_STATE_CHANGED: 376 if (mIsCharging == state) return; 377 mIsCharging = state; 378 sendDeviceState(CHARGING_STATE, mIsCharging); 379 break; 380 case EVENT_TETHERING_STATE_CHANGED: 381 if (mIsTetheringOn == state) return; 382 mIsTetheringOn = state; 383 break; 384 case EVENT_POWER_SAVE_MODE_CHANGED: 385 if (mIsPowerSaveOn == state) return; 386 mIsPowerSaveOn = state; 387 sendDeviceState(POWER_SAVE_MODE, mIsPowerSaveOn); 388 break; 389 default: 390 return; 391 } 392 393 if (mIsLowDataExpected != isLowDataExpected()) { 394 mIsLowDataExpected = !mIsLowDataExpected; 395 sendDeviceState(LOW_DATA_EXPECTED, mIsLowDataExpected); 396 } 397 398 int newFilter = 0; 399 if (!shouldTurnOffSignalStrength()) { 400 newFilter |= IndicationFilter.SIGNAL_STRENGTH; 401 } 402 403 if (!shouldTurnOffFullNetworkUpdate()) { 404 newFilter |= IndicationFilter.FULL_NETWORK_STATE; 405 } 406 407 if (!shouldTurnOffDormancyUpdate()) { 408 newFilter |= IndicationFilter.DATA_CALL_DORMANCY_CHANGED; 409 } 410 411 if (!shouldTurnOffLinkCapacityEstimate()) { 412 newFilter |= IndicationFilter.LINK_CAPACITY_ESTIMATE; 413 } 414 415 if (!shouldTurnOffPhysicalChannelConfig()) { 416 newFilter |= IndicationFilter.PHYSICAL_CHANNEL_CONFIG; 417 } 418 419 setUnsolResponseFilter(newFilter, false); 420 } 421 422 /** 423 * Called when RIL is connected during boot up or reconnected after modem restart. 424 * 425 * When modem crashes, if the user turns the screen off before RIL reconnects, device 426 * state and filter cannot be sent to modem. Resend the state here so that modem 427 * has the correct state (to stop signal strength reporting, etc). 428 */ onRilConnected()429 private void onRilConnected() { 430 log("RIL connected.", true); 431 sendDeviceState(CHARGING_STATE, mIsCharging); 432 sendDeviceState(LOW_DATA_EXPECTED, mIsLowDataExpected); 433 sendDeviceState(POWER_SAVE_MODE, mIsPowerSaveOn); 434 setUnsolResponseFilter(mUnsolicitedResponseFilter, true); 435 setSignalStrengthReportingCriteria(); 436 setLinkCapacityReportingCriteria(); 437 } 438 439 /** 440 * Convert the device state type into string 441 * 442 * @param type Device state type 443 * @return The converted string 444 */ deviceTypeToString(int type)445 private String deviceTypeToString(int type) { 446 switch (type) { 447 case CHARGING_STATE: return "CHARGING_STATE"; 448 case LOW_DATA_EXPECTED: return "LOW_DATA_EXPECTED"; 449 case POWER_SAVE_MODE: return "POWER_SAVE_MODE"; 450 default: return "UNKNOWN"; 451 } 452 } 453 454 /** 455 * Send the device state to the modem. 456 * 457 * @param type Device state type. See DeviceStateType defined in types.hal. 458 * @param state True if enabled/on, otherwise disabled/off 459 */ sendDeviceState(int type, boolean state)460 private void sendDeviceState(int type, boolean state) { 461 log("send type: " + deviceTypeToString(type) + ", state=" + state, true); 462 mPhone.mCi.sendDeviceState(type, state, null); 463 } 464 465 /** 466 * Turn on/off the unsolicited response from the modem. 467 * 468 * @param newFilter See UnsolicitedResponseFilter in types.hal for the definition of each bit. 469 * @param force Always set the filter when true. 470 */ setUnsolResponseFilter(int newFilter, boolean force)471 private void setUnsolResponseFilter(int newFilter, boolean force) { 472 if (force || newFilter != mUnsolicitedResponseFilter) { 473 log("old filter: " + mUnsolicitedResponseFilter + ", new filter: " + newFilter, true); 474 mPhone.mCi.setUnsolResponseFilter(newFilter, null); 475 mUnsolicitedResponseFilter = newFilter; 476 } 477 } 478 setSignalStrengthReportingCriteria()479 private void setSignalStrengthReportingCriteria() { 480 mPhone.setSignalStrengthReportingCriteria( 481 AccessNetworkThresholds.GERAN, AccessNetworkType.GERAN); 482 mPhone.setSignalStrengthReportingCriteria( 483 AccessNetworkThresholds.UTRAN, AccessNetworkType.UTRAN); 484 mPhone.setSignalStrengthReportingCriteria( 485 AccessNetworkThresholds.EUTRAN, AccessNetworkType.EUTRAN); 486 mPhone.setSignalStrengthReportingCriteria( 487 AccessNetworkThresholds.CDMA2000, AccessNetworkType.CDMA2000); 488 } 489 setLinkCapacityReportingCriteria()490 private void setLinkCapacityReportingCriteria() { 491 mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS, 492 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.GERAN); 493 mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS, 494 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.UTRAN); 495 mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS, 496 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.EUTRAN); 497 mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS, 498 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.CDMA2000); 499 } 500 501 /** 502 * @return True if the device is currently in power save mode. 503 * See {@link android.os.BatteryManager#isPowerSaveMode BatteryManager.isPowerSaveMode()}. 504 */ isPowerSaveModeOn()505 private boolean isPowerSaveModeOn() { 506 final PowerManager pm = (PowerManager) mPhone.getContext().getSystemService( 507 Context.POWER_SERVICE); 508 return pm.isPowerSaveMode(); 509 } 510 511 /** 512 * @return Return true if the battery is currently considered to be charging. This means that 513 * the device is plugged in and is supplying sufficient power that the battery level is 514 * going up (or the battery is fully charged). 515 * See {@link android.os.BatteryManager#isCharging BatteryManager.isCharging()}. 516 */ isDeviceCharging()517 private boolean isDeviceCharging() { 518 final BatteryManager bm = (BatteryManager) mPhone.getContext().getSystemService( 519 Context.BATTERY_SERVICE); 520 return bm.isCharging(); 521 } 522 523 /** 524 * @return True if one the device's screen (e.g. main screen, wifi display, HDMI display, or 525 * Android auto, etc...) is on. 526 */ isScreenOn()527 private boolean isScreenOn() { 528 // Note that we don't listen to Intent.SCREEN_ON and Intent.SCREEN_OFF because they are no 529 // longer adequate for monitoring the screen state since they are not sent in cases where 530 // the screen is turned off transiently such as due to the proximity sensor. 531 final DisplayManager dm = (DisplayManager) mPhone.getContext().getSystemService( 532 Context.DISPLAY_SERVICE); 533 Display[] displays = dm.getDisplays(); 534 535 if (displays != null) { 536 for (Display display : displays) { 537 // Anything other than STATE_ON is treated as screen off, such as STATE_DOZE, 538 // STATE_DOZE_SUSPEND, etc... 539 if (display.getState() == Display.STATE_ON) { 540 log("Screen " + Display.typeToString(display.getType()) + " on", true); 541 return true; 542 } 543 } 544 log("Screens all off", true); 545 return false; 546 } 547 548 log("No displays found", true); 549 return false; 550 } 551 552 /** 553 * @param msg Debug message 554 * @param logIntoLocalLog True if log into the local log 555 */ log(String msg, boolean logIntoLocalLog)556 private void log(String msg, boolean logIntoLocalLog) { 557 if (DBG) Rlog.d(TAG, msg); 558 if (logIntoLocalLog) { 559 mLocalLog.log(msg); 560 } 561 } 562 563 /** 564 * Print the DeviceStateMonitor into the given stream. 565 * 566 * @param fd The raw file descriptor that the dump is being sent to. 567 * @param pw A PrintWriter to which the dump is to be set. 568 * @param args Additional arguments to the dump request. 569 */ dump(FileDescriptor fd, PrintWriter pw, String[] args)570 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 571 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 572 ipw.increaseIndent(); 573 ipw.println("mIsTetheringOn=" + mIsTetheringOn); 574 ipw.println("mIsScreenOn=" + mIsScreenOn); 575 ipw.println("mIsCharging=" + mIsCharging); 576 ipw.println("mIsPowerSaveOn=" + mIsPowerSaveOn); 577 ipw.println("mIsLowDataExpected=" + mIsLowDataExpected); 578 ipw.println("mUnsolicitedResponseFilter=" + mUnsolicitedResponseFilter); 579 ipw.println("Local logs:"); 580 ipw.increaseIndent(); 581 mLocalLog.dump(fd, ipw, args); 582 ipw.decreaseIndent(); 583 ipw.decreaseIndent(); 584 ipw.flush(); 585 } 586 587 /** 588 * dBm thresholds that correspond to changes in signal strength indications. 589 */ 590 private static final class AccessNetworkThresholds { 591 592 /** 593 * List of dBm thresholds for GERAN {@link AccessNetworkType}. 594 * 595 * Calculated from GSM asu level thresholds - TS 27.007 Sec 8.5 596 */ 597 public static final int[] GERAN = new int[] { 598 -109, 599 -103, 600 -97, 601 -89, 602 }; 603 604 /** 605 * List of default dBm thresholds for UTRAN {@link AccessNetworkType}. 606 * 607 * These thresholds are taken from the WCDMA RSCP defaults in {@link CarrierConfigManager}. 608 * See TS 27.007 Sec 8.69. 609 */ 610 public static final int[] UTRAN = new int[] { 611 -114, /* SIGNAL_STRENGTH_POOR */ 612 -104, /* SIGNAL_STRENGTH_MODERATE */ 613 -94, /* SIGNAL_STRENGTH_GOOD */ 614 -84 /* SIGNAL_STRENGTH_GREAT */ 615 }; 616 617 /** 618 * List of default dBm thresholds for EUTRAN {@link AccessNetworkType}. 619 * 620 * These thresholds are taken from the LTE RSRP defaults in {@link CarrierConfigManager}. 621 */ 622 public static final int[] EUTRAN = new int[] { 623 -140, /* SIGNAL_STRENGTH_NONE_OR_UNKNOWN */ 624 -128, /* SIGNAL_STRENGTH_POOR */ 625 -118, /* SIGNAL_STRENGTH_MODERATE */ 626 -108, /* SIGNAL_STRENGTH_GOOD */ 627 -98, /* SIGNAL_STRENGTH_GREAT */ 628 -44 /* SIGNAL_STRENGTH_NONE_OR_UNKNOWN */ 629 }; 630 631 /** 632 * List of dBm thresholds for CDMA2000 {@link AccessNetworkType}. 633 * 634 * These correspond to EVDO level thresholds. 635 */ 636 public static final int[] CDMA2000 = new int[] { 637 -105, 638 -90, 639 -75, 640 -65 641 }; 642 } 643 644 /** 645 * Downlink reporting thresholds in kbps 646 * 647 * <p>Threshold values taken from FCC Speed Guide 648 * (https://www.fcc.gov/reports-research/guides/broadband-speed-guide) and Android WiFi speed 649 * labels (https://support.google.com/pixelphone/answer/2819519#strength_speed). 650 */ 651 private static final int[] LINK_CAPACITY_DOWNLINK_THRESHOLDS = new int[] { 652 500, // Web browsing 653 1000, // SD video streaming 654 5000, // HD video streaming 655 10000, // file downloading 656 20000, // 4K video streaming 657 }; 658 659 /** Uplink reporting thresholds in kbps */ 660 private static final int[] LINK_CAPACITY_UPLINK_THRESHOLDS = new int[] { 661 100, // VoIP calls 662 500, 663 1000, 664 5000, 665 10000, 666 }; 667 } 668