• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.server.wifi;
18 
19 import java.io.FileDescriptor;
20 import java.io.PrintWriter;
21 
22 /**
23  * This class represents the list of SAR inputs that will be used to select the proper
24  * power profile.
25  * This includes:
26  *  - Is there an ongoing voice call
27  *  - Is SoftAP active
28  * It also contains info about state of the other Wifi modes
29  *  - Client mode (Sta)
30  *  - ScanOnly mode
31  * It also keeps history for the reporting of SAR states/scenario to avoid unnecessary reporting
32  *  - keeps track of the last reported states
33  *  - keeps track of the last reported SAR scenario
34  *  - keeps track of if all wifi modes were disabled (no reporting should happen then)
35  */
36 public class SarInfo {
37     /**
38      * This value is used as an initial value for the last reported scenario
39      * It is intended to be different than all valid SAR scenario values (including the
40      * reset value).
41      * Using this to initialize the lastReportedScenario results in that the first scenario
42      * (including reset) would be reported.
43      */
44     public static final int INITIAL_SAR_SCENARIO = -2;
45 
46     /**
47      * This value is used for the reset scenario (no TX Power backoff)
48      * Valid scenario values only include scenarios with Tx Power backoff,
49      * so we need this one to represent the "No backoff" case.
50      */
51     public static final int RESET_SAR_SCENARIO = -1;
52 
53     /* For Logging */
54     private static final String TAG = "WifiSarInfo";
55 
56     /* SAR support configs */
57     public boolean sarVoiceCallSupported;
58     public boolean sarSapSupported;
59 
60     public boolean isWifiClientEnabled = false;
61     public boolean isWifiSapEnabled = false;
62     public boolean isWifiScanOnlyEnabled = false;
63     public boolean isVoiceCall = false;
64     public boolean isEarPieceActive = false;
65     public int attemptedSarScenario = RESET_SAR_SCENARIO;
66 
67     private boolean mAllWifiDisabled = true;
68 
69     /* Variables representing the last successfully reported values to hal */
70     private boolean mLastReportedIsWifiSapEnabled = false;
71     private boolean mLastReportedIsVoiceCall = false;
72     private boolean mLastReportedIsEarPieceActive = false;
73     private int mLastReportedScenario = INITIAL_SAR_SCENARIO;
74     private long mLastReportedScenarioTs = 0;
75 
76     /**
77      * shouldReport()
78      * This method returns false in the following cases:
79      * 1. If all Wifi modes are disabled.
80      * 2. Values contributing to the SAR scenario selection have not changed
81      *    since last successful reporting.
82      *
83      * Special cases to allow for devices that require setting the SAR scenario value
84      * when the chip comes up (initial startup, or during operation)
85      * 1. This method would report true even with unchanged values from last reporting,
86      *    if any wifi mode is just enabled after all wifi modes were disabled.
87      * 2. This method would report true the first time it is called with any wifi mode enabled.
88      */
shouldReport()89     public boolean shouldReport() {
90         /* Check if all Wifi modes are disabled */
91         if (!isWifiClientEnabled && !isWifiSapEnabled && !isWifiScanOnlyEnabled) {
92             mAllWifiDisabled = true;
93             return false;
94         }
95 
96         /* Check if Wifi was all disabled before this call */
97         if (mAllWifiDisabled) {
98             return true;
99         }
100 
101         /* Check if some change happened since last successful reporting */
102         return ((isWifiSapEnabled != mLastReportedIsWifiSapEnabled)
103                 || (isVoiceCall != mLastReportedIsVoiceCall)
104                 || (isEarPieceActive != mLastReportedIsEarPieceActive));
105     }
106 
107     /**
108      * reportingSuccessful()
109      * This method is called when reporting SAR scenario is fully successful
110      * This results in caching the last reported inputs for future comparison.
111      */
reportingSuccessful()112     public void reportingSuccessful() {
113         mLastReportedIsWifiSapEnabled = isWifiSapEnabled;
114         mLastReportedIsVoiceCall = isVoiceCall;
115         mLastReportedIsEarPieceActive = isEarPieceActive;
116         mLastReportedScenario = attemptedSarScenario;
117         mLastReportedScenarioTs = System.currentTimeMillis();
118 
119         mAllWifiDisabled = false;
120     }
121 
122     /**
123      *  resetSarScenarioNeeded()
124      *  Returns true if a call towards HAL to reset SAR scenario would be necessary.
125      *  Returns false if the last call to HAL was already a reset, and hence
126      *  another call to reset the SAR scenario would be redundant.
127      */
resetSarScenarioNeeded()128     public boolean resetSarScenarioNeeded() {
129         return setSarScenarioNeeded(RESET_SAR_SCENARIO);
130     }
131 
132     /**
133      * setSarScenarioNeeded()
134      * Returns true if a call towards HAL to set SAR scenario to that value would be
135      * necessary. This happens in the following cases:
136      *   1. All Wifi modes were disabled, hence we need to init the SAR scenario value.
137      *   2. The new scenario is different from the last reported one.
138      *
139      * Returns false if the last call to HAL was to set the scenario to that value, hence,
140      * another call to set the SAR scenario to the same value would be redundant.
141      */
setSarScenarioNeeded(int scenario)142     public boolean setSarScenarioNeeded(int scenario) {
143         attemptedSarScenario = scenario;
144 
145         if (mAllWifiDisabled || (mLastReportedScenario != scenario)) {
146             return true;
147         }
148         return false;
149     }
150 
151     /**
152      * dump()
153      * Dumps the state of SarInfo
154      */
dump(FileDescriptor fd, PrintWriter pw, String[] args)155     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
156         pw.println("Dump of SarInfo");
157         pw.println("Current values:");
158         pw.println("    Voice Call state is: " + isVoiceCall);
159         pw.println("    Wifi Client state is: " + isWifiClientEnabled);
160         pw.println("    Wifi Soft AP state is: " + isWifiSapEnabled);
161         pw.println("    Wifi ScanOnly state is: " + isWifiScanOnlyEnabled);
162         pw.println("    Earpiece state is : " + isEarPieceActive);
163         pw.println("Last reported values:");
164         pw.println("    Soft AP state is: " + mLastReportedIsWifiSapEnabled);
165         pw.println("    Voice Call state is: " + mLastReportedIsVoiceCall);
166         pw.println("    Earpiece state is: " + mLastReportedIsEarPieceActive);
167         pw.println("Last reported scenario: " + mLastReportedScenario);
168         pw.println("Reported " +  (System.currentTimeMillis() - mLastReportedScenarioTs) / 1000
169                 + " seconds ago");
170     }
171 }
172