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