Home | History | Annotate | Download | only in telephony
      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      */
    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      */
    208     private boolean isLowDataExpected() {
    209         return !mIsCharging && !mIsTetheringOn && !mIsScreenOn;
    210     }
    211 
    212     /**
    213      * @return True if signal strength update should be turned off.
    214      */
    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      */
    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      */
    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      */
    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      */
    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      */
    315     public void setIndicationUpdateMode(int filters, int mode) {
    316         sendMessage(obtainMessage(EVENT_UPDATE_MODE_CHANGED, filters, mode));
    317     }
    318 
    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
    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      */
    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      */
    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      */
    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      */
    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      */
    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 
    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 
    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      */
    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      */
    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      */
    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      */
    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      */
    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