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