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