1 /* 2 * Copyright 2014 Intel Corporation All Rights Reserved. 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.intel.thermal; 18 19 import com.intel.thermal.ThermalManager; 20 21 import android.util.Log; 22 23 import java.io.File; 24 import java.util.ArrayList; 25 import java.util.Arrays; 26 27 /** 28 * The ThermalSensor class describes the attributes of a Thermal Sensor. This 29 * class implements methods that retrieve temperature sensor information from 30 * the kernel through the native interface. 31 * 32 * @hide 33 */ 34 public class ThermalSensor { 35 36 private static final String TAG = "ThermalSensor"; 37 private String mSensorPath; /* sys path to read temp from */ 38 private String mSensorName; /* name of the sensor */ 39 private String mInputTempPath; /* sys path to read the current temp */ 40 private String mHighTempPath; /* sys path to set the intermediate upper threshold */ 41 private String mLowTempPath; /* sys path to set the intermediate lower threshold */ 42 private String mUEventDevPath; /* sys path for uevent listener */ 43 private int mErrorCorrectionTemp; /* Temperature difference in mC */ 44 private int mSensorID = -1; 45 private int mSensorState; /* Thermal state of the sensor */ 46 private int mCurrTemp; /* Holds the latest temperature of the sensor */ 47 private int mSensorSysfsIndx; /* Index of this sensor in the sysfs */ 48 private boolean mIsSensorActive = false; /* Whether this sensor is active */ 49 printAttrs()50 public void printAttrs() { 51 Log.i(TAG, "mSensorName: " + mSensorName); 52 Log.i(TAG, "mSensorPath: " + mSensorPath); 53 Log.i(TAG, "mInputTempPath: " + mInputTempPath); 54 Log.i(TAG, "mHighTempPath: " + mHighTempPath); 55 Log.i(TAG, "mLowTempPath: " + mLowTempPath); 56 Log.i(TAG, "mUEventDevPath: " + mUEventDevPath); 57 Log.i(TAG, "mErrorCorrection: " + mErrorCorrectionTemp); 58 } 59 setSensorSysfsPath()60 private void setSensorSysfsPath() { 61 int indx = ThermalUtils.getThermalZoneIndex(mSensorName); 62 // The battery subsystem exposes sensors under different names. 63 // The only commonality among them is that all of them contain 64 // the string "battery". 65 if (indx == -1 && mSensorName.contains("battery")) { 66 indx = ThermalUtils.getThermalZoneIndexContains("battery"); 67 } 68 69 if (indx != -1) { 70 mSensorPath = ThermalManager.sSysfsSensorBasePath + indx + "/"; 71 } 72 73 mSensorSysfsIndx = indx; 74 } 75 getSensorActiveStatus()76 public boolean getSensorActiveStatus() { 77 return mIsSensorActive; 78 } 79 getSensorSysfsPath()80 public String getSensorSysfsPath() { 81 return mSensorPath; 82 } 83 ThermalSensor()84 public ThermalSensor() { 85 mSensorState = ThermalManager.THERMAL_STATE_OFF; 86 mCurrTemp = ThermalManager.INVALID_TEMP; 87 mSensorPath = "auto"; 88 mInputTempPath = "auto"; 89 mHighTempPath = "auto"; 90 mLowTempPath = "auto"; 91 mUEventDevPath = "auto"; 92 93 // Set default value of 'correction temperature' to 1000mC 94 mErrorCorrectionTemp = 1000; 95 } 96 getSensorID()97 public int getSensorID() { 98 return mSensorID; 99 } 100 getSensorSysfsIndx()101 public int getSensorSysfsIndx() { 102 return mSensorSysfsIndx; 103 } 104 getSensorPath()105 public String getSensorPath() { 106 return mSensorPath; 107 } 108 109 /** 110 * This function sets the sensor path to the given String value. If the 111 * String is "auto" it loops through the standard sysfs path, to obtain the 112 * 'mSensorPath'. The standard sysfs path is /sys/class/ 113 * thermal/thermal_zoneX and the look up is based on 'mSensorName'. 114 * If sensor path is "none", sensor temp is not read via any sysfs 115 */ setSensorPath(String path)116 public void setSensorPath(String path) { 117 if (path.equalsIgnoreCase("auto")) { 118 setSensorSysfsPath(); 119 } else { 120 mSensorPath = path; 121 } 122 } 123 isSensorSysfsValid(String path)124 private boolean isSensorSysfsValid(String path) { 125 return ThermalUtils.isFileExists(path); 126 } 127 getSensorName()128 public String getSensorName() { 129 return mSensorName; 130 } 131 setSensorName(String name)132 public void setSensorName(String name) { 133 mSensorName = name; 134 } 135 setUEventDevPath(String devPath)136 public void setUEventDevPath(String devPath) { 137 mUEventDevPath = devPath; 138 } 139 getUEventDevPath()140 public String getUEventDevPath() { 141 return mUEventDevPath; 142 } 143 setErrorCorrectionTemp(int temp)144 public void setErrorCorrectionTemp(int temp) { 145 mErrorCorrectionTemp = temp; 146 } 147 getErrorCorrectionTemp()148 public int getErrorCorrectionTemp() { 149 return mErrorCorrectionTemp; 150 } 151 152 setInputTempPath(String name)153 public void setInputTempPath(String name) { 154 // sensor path is none, it means sensor temperature reporting is 155 // not sysfs based. So turn sensor active by default. 156 // If the sensor path does not exist, deactivate the sensor. 157 if (mSensorPath != null && mSensorPath.equalsIgnoreCase("none")) { 158 mIsSensorActive = true; 159 } else { 160 if (name != null && name.equalsIgnoreCase("auto")) { 161 name = "temp"; 162 } 163 mInputTempPath = mSensorPath + name; 164 if (!isSensorSysfsValid(mInputTempPath)) { 165 mIsSensorActive = false; 166 Log.i(TAG, "Sensor:" + mSensorName + " path:" + mInputTempPath 167 + " is invalid...deactivaing Sensor"); 168 } else { 169 mIsSensorActive = true; 170 } 171 } 172 } 173 getSensorInputTempPath()174 public String getSensorInputTempPath() { 175 return mInputTempPath; 176 } 177 setHighTempPath(String name)178 public void setHighTempPath(String name) { 179 if (name != null && name.equalsIgnoreCase("auto")) { 180 mHighTempPath = mSensorPath + ThermalManager.sSysfsSensorHighTempPath; 181 } else { 182 if (mSensorPath != null && mSensorPath.equalsIgnoreCase("none")) { 183 mHighTempPath = "invalid"; 184 } else { 185 mHighTempPath = mSensorPath + name; 186 } 187 } 188 } 189 getSensorHighTempPath()190 public String getSensorHighTempPath() { 191 return mHighTempPath; 192 } 193 setLowTempPath(String name)194 public void setLowTempPath(String name) { 195 if (name != null && name.equalsIgnoreCase("auto")) { 196 mLowTempPath = mSensorPath + ThermalManager.sSysfsSensorLowTempPath; 197 } else { 198 if (mSensorPath != null && mSensorPath.equalsIgnoreCase("none")) { 199 mLowTempPath = "invalid"; 200 } else { 201 mLowTempPath = mSensorPath + name; 202 } 203 } 204 } 205 getSensorLowTempPath()206 public String getSensorLowTempPath() { 207 return mLowTempPath; 208 } 209 setCurrTemp(int temp)210 public void setCurrTemp(int temp) { 211 mCurrTemp = temp; 212 } 213 getCurrTemp()214 public int getCurrTemp() { 215 return mCurrTemp; 216 } 217 218 /** 219 * Method that actually does a Sysfs read. 220 */ readSensorTemp()221 public int readSensorTemp() { 222 int val = ThermalUtils.readSysfsTemp(mInputTempPath); 223 if (val <= ThermalManager.ABS_ZERO) { 224 // Error will be returned as negative offset from absolute zero in milli degree C 225 Log.e(TAG, "readSensorTemp failed with error:" + (val - ThermalManager.ABS_ZERO)); 226 val = ThermalManager.INVALID_TEMP; 227 } 228 return val; 229 } 230 231 /** 232 * Method to read the current temperature from sensor. This method should be 233 * used only when we want to obtain the latest temperature from sensors. 234 * Otherwise, the getCurrTemp method should be used, which returns the 235 * previously read value. 236 */ updateSensorTemp()237 public void updateSensorTemp() { 238 int val = readSensorTemp(); 239 if (val != ThermalManager.INVALID_TEMP) { 240 setCurrTemp(val); 241 } 242 } 243 getSensorThermalState()244 public int getSensorThermalState() { 245 return mSensorState; 246 } 247 setSensorThermalState(int state)248 public void setSensorThermalState(int state) { 249 mSensorState = state; 250 } 251 setAutoValues()252 public void setAutoValues() { 253 if (mSensorPath.equalsIgnoreCase("auto")) { 254 setSensorPath(mSensorPath); 255 } 256 if (mInputTempPath.equalsIgnoreCase("auto")) { 257 setInputTempPath(mInputTempPath); 258 } 259 if (mHighTempPath.equalsIgnoreCase("auto")) { 260 setHighTempPath(mHighTempPath); 261 } 262 if (mLowTempPath.equalsIgnoreCase("auto")) { 263 setLowTempPath(mLowTempPath); 264 } 265 if (mUEventDevPath.equalsIgnoreCase("auto")) { 266 // build the sensor UEvent listener path 267 if (mSensorSysfsIndx == -1) { 268 mUEventDevPath = "invalid"; 269 Log.i(TAG, "Cannot build UEvent path for sensor:" + mSensorName); 270 return; 271 } else { 272 mUEventDevPath = ThermalManager.sUEventDevPath + mSensorSysfsIndx; 273 } 274 } else if (!mUEventDevPath.contains("DEVPATH=")) { 275 mUEventDevPath = "DEVPATH=" + mUEventDevPath; 276 } 277 } 278 279 } 280