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