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