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.app.UiModeManager;
24 import android.content.BroadcastReceiver;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.IntentFilter;
28 import android.content.res.Configuration;
29 import android.hardware.display.DisplayManager;
30 import android.hardware.radio.V1_5.IndicationFilter;
31 import android.net.ConnectivityManager;
32 import android.net.Network;
33 import android.net.NetworkCapabilities;
34 import android.net.NetworkRequest;
35 import android.net.TetheringManager;
36 import android.os.BatteryManager;
37 import android.os.Handler;
38 import android.os.Message;
39 import android.os.PowerManager;
40 import android.os.Registrant;
41 import android.os.RegistrantList;
42 import android.provider.Settings;
43 import android.telephony.AccessNetworkConstants.AccessNetworkType;
44 import android.telephony.CarrierConfigManager;
45 import android.telephony.NetworkRegistrationInfo;
46 import android.telephony.SignalThresholdInfo;
47 import android.util.LocalLog;
48 import android.view.Display;
49 
50 import com.android.internal.annotations.VisibleForTesting;
51 import com.android.internal.util.IndentingPrintWriter;
52 import com.android.telephony.Rlog;
53 
54 import java.io.FileDescriptor;
55 import java.io.PrintWriter;
56 import java.util.ArrayList;
57 import java.util.HashSet;
58 import java.util.Set;
59 
60 /**
61  * The device state monitor monitors the device state such as charging state, power saving sate,
62  * and then passes down the information to the radio modem for the modem to perform its own
63  * proprietary power saving strategy. Device state monitor also turns off the unsolicited
64  * response from the modem when the device does not need to receive it, for example, device's
65  * screen is off and does not have activities like tethering, remote display, etc...This effectively
66  * prevents the CPU from waking up by those unnecessary unsolicited responses such as signal
67  * strength update.
68  */
69 public class DeviceStateMonitor extends Handler {
70     protected static final boolean DBG = false;      /* STOPSHIP if true */
71     protected static final String TAG = DeviceStateMonitor.class.getSimpleName();
72 
73     static final int EVENT_RIL_CONNECTED                = 0;
74     static final int EVENT_CAR_MODE_CHANGED             = 1;
75     @VisibleForTesting
76     static final int EVENT_SCREEN_STATE_CHANGED         = 2;
77     static final int EVENT_POWER_SAVE_MODE_CHANGED      = 3;
78     @VisibleForTesting
79     static final int EVENT_CHARGING_STATE_CHANGED       = 4;
80     static final int EVENT_TETHERING_STATE_CHANGED      = 5;
81     static final int EVENT_RADIO_AVAILABLE              = 6;
82     @VisibleForTesting
83     static final int EVENT_WIFI_CONNECTION_CHANGED      = 7;
84     static final int EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH = 8;
85 
86     private static final int WIFI_UNAVAILABLE = 0;
87     private static final int WIFI_AVAILABLE = 1;
88 
89     private static final int NR_NSA_TRACKING_INDICATIONS_OFF = 0;
90     private static final int NR_NSA_TRACKING_INDICATIONS_EXTENDED = 1;
91     private static final int NR_NSA_TRACKING_INDICATIONS_ALWAYS_ON = 2;
92 
93     private final Phone mPhone;
94 
95     private final LocalLog mLocalLog = new LocalLog(100);
96 
97     private final RegistrantList mPhysicalChannelConfigRegistrants = new RegistrantList();
98 
99     private final NetworkRequest mWifiNetworkRequest =
100             new NetworkRequest.Builder()
101             .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
102             .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
103             .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
104             .build();
105 
106     private final ConnectivityManager.NetworkCallback mNetworkCallback =
107             new ConnectivityManager.NetworkCallback() {
108         Set<Network> mWifiNetworks = new HashSet<>();
109 
110         @Override
111         public void onAvailable(Network network) {
112             synchronized (mWifiNetworks) {
113                 if (mWifiNetworks.size() == 0) {
114                     // We just connected to Wifi, so send an update.
115                     obtainMessage(EVENT_WIFI_CONNECTION_CHANGED, WIFI_AVAILABLE, 0).sendToTarget();
116                     log("Wifi (default) connected", true);
117                 }
118                 mWifiNetworks.add(network);
119             }
120         }
121 
122         @Override
123         public void onLost(Network network) {
124             synchronized (mWifiNetworks) {
125                 mWifiNetworks.remove(network);
126                 if (mWifiNetworks.size() == 0) {
127                     // We just disconnected from the last connected wifi, so send an update.
128                     obtainMessage(
129                             EVENT_WIFI_CONNECTION_CHANGED, WIFI_UNAVAILABLE, 0).sendToTarget();
130                     log("Wifi (default) disconnected", true);
131                 }
132             }
133         }
134     };
135 
136     /**
137      * Flag for wifi/usb/bluetooth tethering turned on or not
138      */
139     private boolean mIsTetheringOn;
140 
141     /**
142      * Screen state provided by Display Manager. True indicates one of the screen is on, otherwise
143      * all off.
144      */
145     private boolean mIsScreenOn;
146 
147     /**
148      * Indicating the device is plugged in and is supplying sufficient power that the battery level
149      * is going up (or the battery is fully charged). See BatteryManager.isCharging() for the
150      * details
151      */
152     private boolean mIsCharging;
153 
154     /**
155      * Flag for device power save mode. See PowerManager.isPowerSaveMode() for the details.
156      * Note that it is not possible both mIsCharging and mIsPowerSaveOn are true at the same time.
157      * The system will automatically end power save mode when the device starts charging.
158      */
159     private boolean mIsPowerSaveOn;
160 
161     /**
162      * Low data expected mode. True indicates low data traffic is expected, for example, when the
163      * device is idle (e.g. screen is off and not doing tethering in the background). Note this
164      * doesn't mean no data is expected.
165      */
166     private boolean mIsLowDataExpected;
167 
168     /**
169      * Wifi is connected. True means both that cellular is likely to be asleep when the screen is
170      * on and that in most cases the device location is relatively close to the WiFi AP. This means
171      * that fewer location updates should be provided by cellular.
172      */
173     private boolean mIsWifiConnected;
174 
175     /**
176      * Car mode is on. True means the device is currently connected to Android Auto. This should be
177      * handled by mIsScreenOn, but the Android Auto display is private and not accessible by
178      * DeviceStateMonitor from DisplayMonitor.
179      */
180     private boolean mIsCarModeOn;
181 
182     /**
183      * True indicates we should always enable the signal strength reporting from radio.
184      */
185     private boolean mIsAlwaysSignalStrengthReportingEnabled;
186 
187     @VisibleForTesting
188     static final int CELL_INFO_INTERVAL_SHORT_MS = 2000;
189     @VisibleForTesting
190     static final int CELL_INFO_INTERVAL_LONG_MS = 10000;
191 
192     /** The minimum required wait time between cell info requests to the modem */
193     private int mCellInfoMinInterval = CELL_INFO_INTERVAL_SHORT_MS;
194 
195     /**
196      * The unsolicited response filter. See IndicationFilter defined in types.hal for the definition
197      * of each bit.
198      */
199     private int mUnsolicitedResponseFilter = IndicationFilter.ALL;
200 
201     private final DisplayManager.DisplayListener mDisplayListener =
202             new DisplayManager.DisplayListener() {
203                 @Override
204                 public void onDisplayAdded(int displayId) { }
205 
206                 @Override
207                 public void onDisplayRemoved(int displayId) { }
208 
209                 @Override
210                 public void onDisplayChanged(int displayId) {
211                     boolean screenOn = isScreenOn();
212                     Message msg = obtainMessage(EVENT_SCREEN_STATE_CHANGED);
213                     msg.arg1 = screenOn ? 1 : 0;
214                     sendMessage(msg);
215                 }
216             };
217 
218     /**
219      * Device state broadcast receiver
220      */
221     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
222         @Override
223         public void onReceive(Context context, Intent intent) {
224             log("received: " + intent, true);
225 
226             Message msg;
227             switch (intent.getAction()) {
228                 case PowerManager.ACTION_POWER_SAVE_MODE_CHANGED:
229                     msg = obtainMessage(EVENT_POWER_SAVE_MODE_CHANGED);
230                     msg.arg1 = isPowerSaveModeOn() ? 1 : 0;
231                     log("Power Save mode " + ((msg.arg1 == 1) ? "on" : "off"), true);
232                     break;
233                 case BatteryManager.ACTION_CHARGING:
234                     msg = obtainMessage(EVENT_CHARGING_STATE_CHANGED);
235                     msg.arg1 = 1;   // charging
236                     break;
237                 case BatteryManager.ACTION_DISCHARGING:
238                     msg = obtainMessage(EVENT_CHARGING_STATE_CHANGED);
239                     msg.arg1 = 0;   // not charging
240                     break;
241                 case TetheringManager.ACTION_TETHER_STATE_CHANGED:
242                     ArrayList<String> activeTetherIfaces = intent.getStringArrayListExtra(
243                             TetheringManager.EXTRA_ACTIVE_TETHER);
244 
245                     boolean isTetheringOn = activeTetherIfaces != null
246                             && activeTetherIfaces.size() > 0;
247                     log("Tethering " + (isTetheringOn ? "on" : "off"), true);
248                     msg = obtainMessage(EVENT_TETHERING_STATE_CHANGED);
249                     msg.arg1 = isTetheringOn ? 1 : 0;
250                     break;
251                 case UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED:
252                     msg = obtainMessage(EVENT_CAR_MODE_CHANGED);
253                     msg.arg1 = 1; // car mode on
254                     break;
255                 case UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED:
256                     msg = obtainMessage(EVENT_CAR_MODE_CHANGED);
257                     msg.arg1 = 0; // car mode off
258                     break;
259                 default:
260                     log("Unexpected broadcast intent: " + intent, false);
261                     return;
262             }
263             sendMessage(msg);
264         }
265     };
266 
267     /**
268      * Device state monitor constructor. Note that each phone object should have its own device
269      * state monitor, meaning there will be two device monitors on the multi-sim device.
270      *
271      * @param phone Phone object
272      */
DeviceStateMonitor(Phone phone)273     public DeviceStateMonitor(Phone phone) {
274         mPhone = phone;
275         DisplayManager dm = (DisplayManager) phone.getContext().getSystemService(
276                 Context.DISPLAY_SERVICE);
277         dm.registerDisplayListener(mDisplayListener, null);
278 
279         mIsPowerSaveOn = isPowerSaveModeOn();
280         mIsCharging = isDeviceCharging();
281         mIsScreenOn = isScreenOn();
282         mIsCarModeOn = isCarModeOn();
283         // Assuming tethering is always off after boot up.
284         mIsTetheringOn = false;
285         mIsLowDataExpected = false;
286 
287         log("DeviceStateMonitor mIsTetheringOn=" + mIsTetheringOn
288                 + ", mIsScreenOn=" + mIsScreenOn
289                 + ", mIsCharging=" + mIsCharging
290                 + ", mIsPowerSaveOn=" + mIsPowerSaveOn
291                 + ", mIsLowDataExpected=" + mIsLowDataExpected
292                 + ", mIsCarModeOn=" + mIsCarModeOn
293                 + ", mIsWifiConnected=" + mIsWifiConnected
294                 + ", mIsAlwaysSignalStrengthReportingEnabled="
295                 + mIsAlwaysSignalStrengthReportingEnabled, false);
296 
297         final IntentFilter filter = new IntentFilter();
298         filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
299         filter.addAction(BatteryManager.ACTION_CHARGING);
300         filter.addAction(BatteryManager.ACTION_DISCHARGING);
301         filter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
302         filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE_PRIORITIZED);
303         filter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE_PRIORITIZED);
304         mPhone.getContext().registerReceiver(mBroadcastReceiver, filter, null, mPhone);
305 
306         mPhone.mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null);
307         mPhone.mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
308 
309         ConnectivityManager cm = (ConnectivityManager) phone.getContext().getSystemService(
310                 Context.CONNECTIVITY_SERVICE);
311         cm.registerNetworkCallback(mWifiNetworkRequest, mNetworkCallback);
312     }
313 
314     /**
315      * @return True if low data is expected
316      */
isLowDataExpected()317     private boolean isLowDataExpected() {
318         return !mIsCharging && !mIsTetheringOn && !mIsScreenOn;
319     }
320 
321     /**
322      * @return The minimum period between CellInfo requests to the modem
323      */
324     @VisibleForTesting
computeCellInfoMinInterval()325     public int computeCellInfoMinInterval() {
326         // The screen is on and we're either on cellular or charging. Screen on + Charging is
327         // a likely vehicular scenario, even if there is a nomadic AP.
328         if (mIsScreenOn && !mIsWifiConnected) {
329             // Screen on without WiFi - We are in a high power likely mobile situation.
330             return CELL_INFO_INTERVAL_SHORT_MS;
331         } else if (mIsScreenOn && mIsCharging) {
332             // Screen is on and we're charging, so we favor accuracy over power.
333             return CELL_INFO_INTERVAL_SHORT_MS;
334         } else {
335             // If the screen is off, apps should not need cellular location at rapid intervals.
336             // If the screen is on but we are on wifi and not charging then cellular location
337             // accuracy is not crucial, so favor modem power saving over high accuracy.
338             return CELL_INFO_INTERVAL_LONG_MS;
339         }
340     }
341 
342     /**
343      * @return True if signal strength update should be enabled. See details in
344      *         android.hardware.radio@1.2::IndicationFilter::SIGNAL_STRENGTH.
345      */
shouldEnableSignalStrengthReports()346     private boolean shouldEnableSignalStrengthReports() {
347         // We should enable signal strength update if one of the following condition is true.
348         // 1. The device is charging.
349         // 2. When the screen is on.
350         // 3. Any of system services is registrating to always listen to signal strength changes
351         return mIsAlwaysSignalStrengthReportingEnabled || mIsCharging || mIsScreenOn;
352     }
353 
354     /**
355      * @return True if full network state update should be enabled. When off, only significant
356      *         changes will trigger the network update unsolicited response. See details in
357      *         android.hardware.radio@1.2::IndicationFilter::FULL_NETWORK_STATE.
358      */
shouldEnableFullNetworkStateReports()359     private boolean shouldEnableFullNetworkStateReports() {
360         return shouldEnableNrTrackingIndications();
361     }
362 
363     /**
364      * @return True if data call dormancy changed update should be enabled. See details in
365      *         android.hardware.radio@1.2::IndicationFilter::DATA_CALL_DORMANCY_CHANGED.
366      */
shouldEnableDataCallDormancyChangedReports()367     private boolean shouldEnableDataCallDormancyChangedReports() {
368         return shouldEnableNrTrackingIndications();
369     }
370 
371     /**
372      * @return True if link capacity estimate update should be enabled. See details in
373      *         android.hardware.radio@1.2::IndicationFilter::LINK_CAPACITY_ESTIMATE.
374      */
shouldEnableLinkCapacityEstimateReports()375     private boolean shouldEnableLinkCapacityEstimateReports() {
376         return shouldEnableHighPowerConsumptionIndications();
377     }
378 
379     /**
380      * @return True if physical channel config update should be enabled. See details in
381      *         android.hardware.radio@1.2::IndicationFilter::PHYSICAL_CHANNEL_CONFIG.
382      */
shouldEnablePhysicalChannelConfigReports()383     private boolean shouldEnablePhysicalChannelConfigReports() {
384         return shouldEnableNrTrackingIndications();
385     }
386 
387     /**
388      * @return True if barring info update should be enabled. See details in
389      *         android.hardware.radio@1.5::IndicationFilter::BARRING_INFO.
390      */
shouldEnableBarringInfoReports()391     private boolean shouldEnableBarringInfoReports() {
392         return shouldEnableHighPowerConsumptionIndications();
393     }
394 
395     /**
396      * A common policy to determine if we should enable the necessary indications update,
397      * for power consumption's sake.
398      *
399      * @return True if the response update should be enabled.
400      */
shouldEnableHighPowerConsumptionIndications()401     private boolean shouldEnableHighPowerConsumptionIndications() {
402         // We should enable indications reports if one of the following condition is true.
403         // 1. The device is charging.
404         // 2. When the screen is on.
405         // 3. When the tethering is on.
406         // 4. When car mode (Android Auto) is on.
407         return mIsCharging || mIsScreenOn || mIsTetheringOn || mIsCarModeOn;
408     }
409 
410     /**
411      * For 5G NSA devices, a policy to determine if we should enable NR tracking indications.
412      *
413      * @return True if the response update should be enabled.
414      */
shouldEnableNrTrackingIndications()415     private boolean shouldEnableNrTrackingIndications() {
416         int trackingMode = Settings.Global.getInt(mPhone.getContext().getContentResolver(),
417                 Settings.Global.NR_NSA_TRACKING_SCREEN_OFF_MODE, NR_NSA_TRACKING_INDICATIONS_OFF);
418         switch (trackingMode) {
419             case NR_NSA_TRACKING_INDICATIONS_ALWAYS_ON:
420                 return true;
421             case NR_NSA_TRACKING_INDICATIONS_EXTENDED:
422                 if (mPhone.getServiceState().getNrState()
423                         == NetworkRegistrationInfo.NR_STATE_CONNECTED) {
424                     return true;
425                 }
426                 // fallthrough
427             case NR_NSA_TRACKING_INDICATIONS_OFF:
428                 return shouldEnableHighPowerConsumptionIndications();
429             default:
430                 return shouldEnableHighPowerConsumptionIndications();
431         }
432     }
433 
434     /**
435      * Set if Telephony need always report signal strength.
436      *
437      * @param isEnable
438      */
setAlwaysReportSignalStrength(boolean isEnable)439     public void setAlwaysReportSignalStrength(boolean isEnable) {
440         sendMessage(obtainMessage(EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH, isEnable ? 1 : 0));
441     }
442 
443     /**
444      * Message handler
445      *
446      * @param msg The message
447      */
448     @Override
handleMessage(Message msg)449     public void handleMessage(Message msg) {
450         log("handleMessage msg=" + msg, false);
451         switch (msg.what) {
452             case EVENT_RIL_CONNECTED:
453             case EVENT_RADIO_AVAILABLE:
454                 onReset();
455                 break;
456             case EVENT_SCREEN_STATE_CHANGED:
457             case EVENT_POWER_SAVE_MODE_CHANGED:
458             case EVENT_CHARGING_STATE_CHANGED:
459             case EVENT_TETHERING_STATE_CHANGED:
460             case EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH:
461             case EVENT_CAR_MODE_CHANGED:
462                 onUpdateDeviceState(msg.what, msg.arg1 != 0);
463                 break;
464             case EVENT_WIFI_CONNECTION_CHANGED:
465                 onUpdateDeviceState(msg.what, msg.arg1 != WIFI_UNAVAILABLE);
466                 break;
467             default:
468                 throw new IllegalStateException("Unexpected message arrives. msg = " + msg.what);
469         }
470     }
471 
472     /**
473      * Update the device and send the information to the modem.
474      *
475      * @param eventType Device state event type
476      * @param state True if enabled/on, otherwise disabled/off.
477      */
onUpdateDeviceState(int eventType, boolean state)478     private void onUpdateDeviceState(int eventType, boolean state) {
479         final boolean shouldEnableBarringInfoReportsOld = shouldEnableBarringInfoReports();
480         switch (eventType) {
481             case EVENT_SCREEN_STATE_CHANGED:
482                 if (mIsScreenOn == state) return;
483                 mIsScreenOn = state;
484                 break;
485             case EVENT_CHARGING_STATE_CHANGED:
486                 if (mIsCharging == state) return;
487                 mIsCharging = state;
488                 sendDeviceState(CHARGING_STATE, mIsCharging);
489                 break;
490             case EVENT_TETHERING_STATE_CHANGED:
491                 if (mIsTetheringOn == state) return;
492                 mIsTetheringOn = state;
493                 break;
494             case EVENT_POWER_SAVE_MODE_CHANGED:
495                 if (mIsPowerSaveOn == state) return;
496                 mIsPowerSaveOn = state;
497                 sendDeviceState(POWER_SAVE_MODE, mIsPowerSaveOn);
498                 break;
499             case EVENT_WIFI_CONNECTION_CHANGED:
500                 if (mIsWifiConnected == state) return;
501                 mIsWifiConnected = state;
502                 break;
503             case EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH:
504                 if (mIsAlwaysSignalStrengthReportingEnabled == state) return;
505                 mIsAlwaysSignalStrengthReportingEnabled = state;
506                 break;
507             case EVENT_CAR_MODE_CHANGED:
508                 if (mIsCarModeOn == state) return;
509                 mIsCarModeOn = state;
510                 break;
511             default:
512                 return;
513         }
514 
515         final int newCellInfoMinInterval = computeCellInfoMinInterval();
516         if (mCellInfoMinInterval != newCellInfoMinInterval) {
517             mCellInfoMinInterval = newCellInfoMinInterval;
518             setCellInfoMinInterval(mCellInfoMinInterval);
519             log("CellInfo Min Interval Updated to " + newCellInfoMinInterval, true);
520         }
521 
522         if (mIsLowDataExpected != isLowDataExpected()) {
523             mIsLowDataExpected = !mIsLowDataExpected;
524             sendDeviceState(LOW_DATA_EXPECTED, mIsLowDataExpected);
525         }
526 
527         // Registration Failure is always reported.
528         int newFilter = IndicationFilter.REGISTRATION_FAILURE;
529 
530         if (shouldEnableSignalStrengthReports()) {
531             newFilter |= IndicationFilter.SIGNAL_STRENGTH;
532         }
533 
534         if (shouldEnableFullNetworkStateReports()) {
535             newFilter |= IndicationFilter.FULL_NETWORK_STATE;
536         }
537 
538         if (shouldEnableDataCallDormancyChangedReports()) {
539             newFilter |= IndicationFilter.DATA_CALL_DORMANCY_CHANGED;
540         }
541 
542         if (shouldEnableLinkCapacityEstimateReports()) {
543             newFilter |= IndicationFilter.LINK_CAPACITY_ESTIMATE;
544         }
545 
546         if (shouldEnablePhysicalChannelConfigReports()) {
547             newFilter |= IndicationFilter.PHYSICAL_CHANNEL_CONFIG;
548         }
549 
550         final boolean shouldEnableBarringInfoReports = shouldEnableBarringInfoReports();
551         if (shouldEnableBarringInfoReports) {
552             newFilter |= IndicationFilter.BARRING_INFO;
553         }
554 
555         // notify PhysicalChannelConfig registrants if state changes
556         if ((newFilter & IndicationFilter.PHYSICAL_CHANNEL_CONFIG)
557                 != (mUnsolicitedResponseFilter & IndicationFilter.PHYSICAL_CHANNEL_CONFIG)) {
558             mPhysicalChannelConfigRegistrants.notifyResult(
559                     (newFilter & IndicationFilter.PHYSICAL_CHANNEL_CONFIG) != 0);
560         }
561 
562         setUnsolResponseFilter(newFilter, false);
563 
564         // Pull barring info AFTER setting filter, the order matters
565         if (shouldEnableBarringInfoReports && !shouldEnableBarringInfoReportsOld) {
566             if (DBG) log("Manually pull barring info...", true);
567             // use a null message since we don't care of receiving response
568             mPhone.mCi.getBarringInfo(null);
569         }
570     }
571 
572     /**
573      * Called when RIL is connected during boot up or radio becomes available after modem restart.
574      *
575      * When modem crashes, if the user turns the screen off before RIL reconnects, device
576      * state and filter cannot be sent to modem. Resend the state here so that modem
577      * has the correct state (to stop signal strength reporting, etc).
578      */
onReset()579     private void onReset() {
580         log("onReset.", true);
581         sendDeviceState(CHARGING_STATE, mIsCharging);
582         sendDeviceState(LOW_DATA_EXPECTED, mIsLowDataExpected);
583         sendDeviceState(POWER_SAVE_MODE, mIsPowerSaveOn);
584         setUnsolResponseFilter(mUnsolicitedResponseFilter, true);
585         setSignalStrengthReportingCriteria();
586         setLinkCapacityReportingCriteria();
587         setCellInfoMinInterval(mCellInfoMinInterval);
588     }
589 
590     /**
591      * Convert the device state type into string
592      *
593      * @param type Device state type
594      * @return The converted string
595      */
deviceTypeToString(int type)596     private String deviceTypeToString(int type) {
597         switch (type) {
598             case CHARGING_STATE: return "CHARGING_STATE";
599             case LOW_DATA_EXPECTED: return "LOW_DATA_EXPECTED";
600             case POWER_SAVE_MODE: return "POWER_SAVE_MODE";
601             default: return "UNKNOWN";
602         }
603     }
604 
605     /**
606      * Send the device state to the modem.
607      *
608      * @param type Device state type. See DeviceStateType defined in types.hal.
609      * @param state True if enabled/on, otherwise disabled/off
610      */
sendDeviceState(int type, boolean state)611     private void sendDeviceState(int type, boolean state) {
612         log("send type: " + deviceTypeToString(type) + ", state=" + state, true);
613         mPhone.mCi.sendDeviceState(type, state, null);
614     }
615 
616     /**
617      * Turn on/off the unsolicited response from the modem.
618      *
619      * @param newFilter See UnsolicitedResponseFilter in types.hal for the definition of each bit.
620      * @param force Always set the filter when true.
621      */
setUnsolResponseFilter(int newFilter, boolean force)622     private void setUnsolResponseFilter(int newFilter, boolean force) {
623         if (force || newFilter != mUnsolicitedResponseFilter) {
624             log("old filter: " + mUnsolicitedResponseFilter + ", new filter: " + newFilter, true);
625             mPhone.mCi.setUnsolResponseFilter(newFilter, null);
626             mUnsolicitedResponseFilter = newFilter;
627         }
628     }
629 
setSignalStrengthReportingCriteria()630     private void setSignalStrengthReportingCriteria() {
631         mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSSI,
632                 AccessNetworkThresholds.GERAN, AccessNetworkType.GERAN, true);
633         mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSCP,
634                 AccessNetworkThresholds.UTRAN, AccessNetworkType.UTRAN, true);
635         mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSRP,
636                 AccessNetworkThresholds.EUTRAN_RSRP, AccessNetworkType.EUTRAN, true);
637         mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSSI,
638                 AccessNetworkThresholds.CDMA2000, AccessNetworkType.CDMA2000, true);
639         if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
640             mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSRQ,
641                     AccessNetworkThresholds.EUTRAN_RSRQ, AccessNetworkType.EUTRAN, false);
642             mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSSNR,
643                     AccessNetworkThresholds.EUTRAN_RSSNR, AccessNetworkType.EUTRAN, true);
644 
645             // Defaultly we only need SSRSRP for NGRAN signal criteria reporting
646             mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_SSRSRP,
647                     AccessNetworkThresholds.NGRAN_RSRSRP, AccessNetworkType.NGRAN, true);
648             mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_SSRSRQ,
649                     AccessNetworkThresholds.NGRAN_RSRSRQ, AccessNetworkType.NGRAN, false);
650             mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_SSSINR,
651                     AccessNetworkThresholds.NGRAN_SSSINR, AccessNetworkType.NGRAN, false);
652         }
653     }
654 
setLinkCapacityReportingCriteria()655     private void setLinkCapacityReportingCriteria() {
656         mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS,
657                 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.GERAN);
658         mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS,
659                 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.UTRAN);
660         mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS,
661                 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.EUTRAN);
662         mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS,
663                 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.CDMA2000);
664         if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
665             mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS,
666                     LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.NGRAN);
667         }
668     }
669 
setCellInfoMinInterval(int rate)670     private void setCellInfoMinInterval(int rate) {
671         mPhone.setCellInfoMinInterval(rate);
672     }
673 
674     /**
675      * @return True if the device is currently in power save mode.
676      * See {@link android.os.BatteryManager#isPowerSaveMode BatteryManager.isPowerSaveMode()}.
677      */
isPowerSaveModeOn()678     private boolean isPowerSaveModeOn() {
679         final PowerManager pm = (PowerManager) mPhone.getContext().getSystemService(
680                 Context.POWER_SERVICE);
681         boolean retval = pm.isPowerSaveMode();
682         log("isPowerSaveModeOn=" + retval, true);
683         return retval;
684     }
685 
686     /**
687      * @return Return true if the battery is currently considered to be charging. This means that
688      * the device is plugged in and is supplying sufficient power that the battery level is
689      * going up (or the battery is fully charged).
690      * See {@link android.os.BatteryManager#isCharging BatteryManager.isCharging()}.
691      */
isDeviceCharging()692     private boolean isDeviceCharging() {
693         final BatteryManager bm = (BatteryManager) mPhone.getContext().getSystemService(
694                 Context.BATTERY_SERVICE);
695         boolean retval = bm.isCharging();
696         log("isDeviceCharging=" + retval, true);
697         return retval;
698     }
699 
700     /**
701      * @return True if one the device's screen (e.g. main screen, wifi display, HDMI display etc...)
702      * is on.
703      */
isScreenOn()704     private boolean isScreenOn() {
705         // Note that we don't listen to Intent.SCREEN_ON and Intent.SCREEN_OFF because they are no
706         // longer adequate for monitoring the screen state since they are not sent in cases where
707         // the screen is turned off transiently such as due to the proximity sensor.
708         final DisplayManager dm = (DisplayManager) mPhone.getContext().getSystemService(
709                 Context.DISPLAY_SERVICE);
710         Display[] displays = dm.getDisplays();
711 
712         if (displays != null) {
713             for (Display display : displays) {
714                 // Anything other than STATE_ON is treated as screen off, such as STATE_DOZE,
715                 // STATE_DOZE_SUSPEND, etc...
716                 if (display.getState() == Display.STATE_ON) {
717                     log("Screen on for display=" + display, true);
718                     return true;
719                 }
720             }
721             log("Screens all off", true);
722             return false;
723         }
724 
725         log("No displays found", true);
726         return false;
727     }
728 
729     /**
730      * @return True if car mode (Android Auto) is on.
731      */
isCarModeOn()732     private boolean isCarModeOn() {
733         final UiModeManager umm = (UiModeManager) mPhone.getContext().getSystemService(
734                 Context.UI_MODE_SERVICE);
735         if (umm == null) return false;
736         boolean retval = umm.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR;
737         log("isCarModeOn=" + retval, true);
738         return retval;
739     }
740 
741     /**
742      * Register for PhysicalChannelConfig notifications changed. On change, msg.obj will be an
743      * AsyncResult with a boolean result. AsyncResult.result is true if notifications are enabled
744      * and false if they are disabled.
745      *
746      * @param h Handler to notify
747      * @param what msg.what when the message is delivered
748      * @param obj AsyncResult.userObj when the message is delivered
749      */
registerForPhysicalChannelConfigNotifChanged(Handler h, int what, Object obj)750     public void registerForPhysicalChannelConfigNotifChanged(Handler h, int what, Object obj) {
751         Registrant r = new Registrant(h, what, obj);
752         mPhysicalChannelConfigRegistrants.add(r);
753     }
754 
755     /**
756      * Unregister for PhysicalChannelConfig notifications changed.
757      * @param h Handler to notify
758      */
unregisterForPhysicalChannelConfigNotifChanged(Handler h)759     public void unregisterForPhysicalChannelConfigNotifChanged(Handler h) {
760         mPhysicalChannelConfigRegistrants.remove(h);
761     }
762 
763     /**
764      * @param msg Debug message
765      * @param logIntoLocalLog True if log into the local log
766      */
log(String msg, boolean logIntoLocalLog)767     private void log(String msg, boolean logIntoLocalLog) {
768         if (DBG) Rlog.d(TAG, msg);
769         if (logIntoLocalLog) {
770             mLocalLog.log(msg);
771         }
772     }
773 
774     /**
775      * Print the DeviceStateMonitor into the given stream.
776      *
777      * @param fd The raw file descriptor that the dump is being sent to.
778      * @param pw A PrintWriter to which the dump is to be set.
779      * @param args Additional arguments to the dump request.
780      */
dump(FileDescriptor fd, PrintWriter pw, String[] args)781     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
782         final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
783         ipw.increaseIndent();
784         ipw.println("mIsTetheringOn=" + mIsTetheringOn);
785         ipw.println("mIsScreenOn=" + mIsScreenOn);
786         ipw.println("mIsCharging=" + mIsCharging);
787         ipw.println("mIsPowerSaveOn=" + mIsPowerSaveOn);
788         ipw.println("mIsLowDataExpected=" + mIsLowDataExpected);
789         ipw.println("mIsCarModeOn=" + mIsCarModeOn);
790         ipw.println("mUnsolicitedResponseFilter=" + mUnsolicitedResponseFilter);
791         ipw.println("mIsWifiConnected=" + mIsWifiConnected);
792         ipw.println("mIsAlwaysSignalStrengthReportingEnabled="
793                 + mIsAlwaysSignalStrengthReportingEnabled);
794         ipw.println("Local logs:");
795         ipw.increaseIndent();
796         mLocalLog.dump(fd, ipw, args);
797         ipw.decreaseIndent();
798         ipw.decreaseIndent();
799         ipw.flush();
800     }
801 
802     /**
803      * dBm thresholds that correspond to changes in signal strength indications.
804      */
805     private static final class AccessNetworkThresholds {
806 
807         /**
808          * List of dBm thresholds for GERAN {@link AccessNetworkType}.
809          *
810          * Calculated from GSM asu level thresholds - TS 27.007 Sec 8.5
811          */
812         public static final int[] GERAN = new int[] {
813             -109,
814             -103,
815             -97,
816             -89,
817         };
818 
819         /**
820          * List of default dBm thresholds for UTRAN {@link AccessNetworkType}.
821          *
822          * These thresholds are taken from the WCDMA RSCP defaults in {@link CarrierConfigManager}.
823          * See TS 27.007 Sec 8.69.
824          */
825         public static final int[] UTRAN = new int[] {
826             -114, /* SIGNAL_STRENGTH_POOR */
827             -104, /* SIGNAL_STRENGTH_MODERATE */
828             -94,  /* SIGNAL_STRENGTH_GOOD */
829             -84   /* SIGNAL_STRENGTH_GREAT */
830         };
831 
832         /**
833          * List of default dBm RSRP thresholds for EUTRAN {@link AccessNetworkType}.
834          *
835          * These thresholds are taken from the LTE RSRP defaults in {@link CarrierConfigManager}.
836          */
837         public static final int[] EUTRAN_RSRP = new int[] {
838             -128, /* SIGNAL_STRENGTH_POOR */
839             -118, /* SIGNAL_STRENGTH_MODERATE */
840             -108, /* SIGNAL_STRENGTH_GOOD */
841             -98,  /* SIGNAL_STRENGTH_GREAT */
842         };
843 
844         /**
845          * List of default dB RSRQ thresholds for EUTRAN {@link AccessNetworkType}.
846          *
847          * These thresholds are taken from the LTE RSRQ defaults in {@link CarrierConfigManager}.
848          */
849         public static final int[] EUTRAN_RSRQ = new int[] {
850             -20,  /* SIGNAL_STRENGTH_POOR */
851             -17,  /* SIGNAL_STRENGTH_MODERATE */
852             -14,  /* SIGNAL_STRENGTH_GOOD */
853             -11   /* SIGNAL_STRENGTH_GREAT */
854         };
855 
856         /**
857          * List of default dB RSSNR thresholds for EUTRAN {@link AccessNetworkType}.
858          *
859          * These thresholds are taken from the LTE RSSNR defaults in {@link CarrierConfigManager}.
860          */
861         public static final int[] EUTRAN_RSSNR = new int[] {
862             -3,  /* SIGNAL_STRENGTH_POOR */
863             1,   /* SIGNAL_STRENGTH_MODERATE */
864             5,   /* SIGNAL_STRENGTH_GOOD */
865             13   /* SIGNAL_STRENGTH_GREAT */
866         };
867 
868         /**
869          * List of dBm thresholds for CDMA2000 {@link AccessNetworkType}.
870          *
871          * These correspond to EVDO level thresholds.
872          */
873         public static final int[] CDMA2000 = new int[] {
874             -105,
875             -90,
876             -75,
877             -65
878         };
879 
880         /**
881          * List of dB thresholds for NGRAN {@link AccessNetworkType} RSRSRP
882          */
883         public static final int[] NGRAN_RSRSRP = new int[] {
884             -110, /* SIGNAL_STRENGTH_POOR */
885             -90, /* SIGNAL_STRENGTH_MODERATE */
886             -80, /* SIGNAL_STRENGTH_GOOD */
887             -65,  /* SIGNAL_STRENGTH_GREAT */
888         };
889 
890         /**
891          * List of dB thresholds for NGRAN {@link AccessNetworkType} RSRSRP
892          */
893         public static final int[] NGRAN_RSRSRQ = new int[] {
894             -31, /* SIGNAL_STRENGTH_POOR */
895             -19, /* SIGNAL_STRENGTH_MODERATE */
896             -7, /* SIGNAL_STRENGTH_GOOD */
897             6  /* SIGNAL_STRENGTH_GREAT */
898         };
899 
900         /**
901          * List of dB thresholds for NGRAN {@link AccessNetworkType} SSSINR
902          */
903         public static final int[] NGRAN_SSSINR = new int[] {
904             -5, /* SIGNAL_STRENGTH_POOR */
905             5, /* SIGNAL_STRENGTH_MODERATE */
906             15, /* SIGNAL_STRENGTH_GOOD */
907             30  /* SIGNAL_STRENGTH_GREAT */
908         };
909     }
910 
911     /**
912      * Downlink reporting thresholds in kbps
913      *
914      * <p>Threshold values taken from FCC Speed Guide when available
915      * (https://www.fcc.gov/reports-research/guides/broadband-speed-guide) and Android WiFi speed
916      * labels (https://support.google.com/pixelphone/answer/2819519#strength_speed).
917      *
918      */
919     private static final int[] LINK_CAPACITY_DOWNLINK_THRESHOLDS = new int[] {
920             100,    // VoIP
921             500,    // Web browsing
922             1000,   // SD video streaming
923             5000,   // HD video streaming
924             10000,  // file downloading
925             20000,  // 4K video streaming
926             50000,  // LTE-Advanced speeds
927             75000,
928             100000,
929             200000, // 5G speeds
930             500000,
931             1000000,
932             1500000,
933             2000000
934     };
935 
936     /** Uplink reporting thresholds in kbps */
937     private static final int[] LINK_CAPACITY_UPLINK_THRESHOLDS = new int[] {
938             100,    // VoIP calls
939             500,
940             1000,   // SD video calling
941             5000,   // HD video calling
942             10000,  // file uploading
943             20000,  // 4K video calling
944             50000,
945             75000,
946             100000,
947             200000,
948             500000
949     };
950 }
951