1bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan/*
2bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * Copyright 2014 Intel Corporation All Rights Reserved.
3bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan *
4bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * Licensed under the Apache License, Version 2.0 (the "License");
5bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * you may not use this file except in compliance with the License.
6bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * You may obtain a copy of the License at
7bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan *
8bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan *      http://www.apache.org/licenses/LICENSE-2.0
9bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan *
10bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * Unless required by applicable law or agreed to in writing, software
11bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * distributed under the License is distributed on an "AS IS" BASIS,
12bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * See the License for the specific language governing permissions and
14bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * limitations under the License.
15bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan */
16bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
17bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanpackage com.intel.thermal;
18bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
19bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport android.content.Context;
20bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport android.os.SystemProperties;
21bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport android.util.Log;
22bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
23bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.io.IOException;
24bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.io.File;
25bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
26bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan/* importing static variables */
27bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport static com.intel.thermal.ThermalManager.*;
28bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
29bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan/**
30bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * The ThermalUtils class contains all common utility functionality
31bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * implementations
32bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan *
33bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * @hide
34bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan */
35bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanpublic class ThermalUtils {
36bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static final String TAG = "ThermalUtils";
37bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
38bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* Native methods to access Sysfs Interfaces */
39bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private native static String native_readSysfs(String path);
40c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan    private native static int native_readSysfsTemp(String path);
41bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private native static int native_writeSysfs(String path, int val);
42bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private native static int native_getThermalZoneIndex(String name);
43bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private native static int native_getThermalZoneIndexContains(String name);
44bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private native static int native_getCoolingDeviceIndex(String name);
45bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private native static int native_getCoolingDeviceIndexContains(String name);
46bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private native static boolean native_isFileExists(String name);
47bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
48bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    // native methods to access kernel sysfs layer
49bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static String readSysfs(String path) {
50bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        try {
51bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return native_readSysfs(path);
52bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        } catch (UnsatisfiedLinkError e) {
53bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.w(TAG, "caught UnsatisfiedLinkError in readSysfs");
54bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return null;
55bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
56bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
57bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
58c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan    public static int readSysfsTemp(String path) {
59c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan        try {
60c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan            return native_readSysfsTemp(path);
61c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan        } catch (UnsatisfiedLinkError e) {
62c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan            Log.i(TAG, "caught UnsatisfiedLinkError in readSysfsTemp");
63c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan            return INVALID_TEMP;
64c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan        }
65c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan    }
66c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan
67bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static int writeSysfs(String path, int val) {
68bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        try {
69bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return native_writeSysfs(path, val);
70bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        } catch (UnsatisfiedLinkError e) {
71bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.w(TAG, "caught UnsatisfiedLinkError in writeSysfs");
72bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return -1;
73bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
74bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
75bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
76bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static int getThermalZoneIndex(String name) {
77bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        try {
78bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return native_getThermalZoneIndex(name);
79bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        } catch (UnsatisfiedLinkError e) {
80bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.w(TAG, "caught UnsatisfiedLinkError in getThermalZoneIndex");
81bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return -1;
82bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
83bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
84bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
85bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static int getThermalZoneIndexContains(String name) {
86bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        try {
87bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return native_getThermalZoneIndexContains(name);
88bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        } catch (UnsatisfiedLinkError e) {
89bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.w(TAG, "caught UnsatisfiedLinkError in getThermalZoneIndexContains");
90bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return -1;
91bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
92bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
93bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
94bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static int getCoolingDeviceIndex(String name) {
95bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        try {
96bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return native_getCoolingDeviceIndex(name);
97bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        } catch (UnsatisfiedLinkError e) {
98bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.w(TAG, "caught UnsatisfiedLinkError in getCoolingDeviceIndex");
99bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return -1;
100bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
101bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
102bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
103bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static int getCoolingDeviceIndexContains(String name) {
104bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        try {
105bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return native_getCoolingDeviceIndexContains(name);
106bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        } catch (UnsatisfiedLinkError e) {
107bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.w(TAG, "caught UnsatisfiedLinkError in getCoolingDeviceIndexContains");
108bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return -1;
109bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
110bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
111bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
112bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static boolean isFileExists(String path) {
113bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        try {
114bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return native_isFileExists(path);
115bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        } catch (UnsatisfiedLinkError e) {
116bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.w(TAG, "caught UnsatisfiedLinkError in isFileExists");
117bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return false;
118bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
119bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
120bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
121bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
122bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static int calculateThermalState(int temp, Integer thresholds[]) {
123bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if (thresholds == null) return THERMAL_STATE_OFF;
124bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        // Return OFF state if temperature less than starting of thresholds
125bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if (temp < thresholds[0])
126bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return THERMAL_STATE_OFF;
127bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
128bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if (temp >= thresholds[thresholds.length - 2])
129bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return (thresholds.length - 2);
130bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
131bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        for (int i = 0; i < thresholds.length - 1; i++) {
132bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (temp >= thresholds[i] && temp < thresholds[i + 1]) {
133bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                return i;
134bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
135bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
136bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
137bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        // should never come here
138bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        return THERMAL_STATE_OFF;
139bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
140bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
141bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static int getLowerThresholdTemp(int index, Integer thresholds[]) {
142bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if (thresholds == null) return INVALID_TEMP;
143bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if (index < 0 || index >= thresholds.length)
144bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return INVALID_TEMP;
145bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        return thresholds[index];
146bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
147bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
148bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static int getUpperThresholdTemp(int index, Integer thresholds[]) {
149bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if (thresholds == null) return INVALID_TEMP;
150bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if (index < 0 || index >= thresholds.length)
151bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return INVALID_TEMP;
152bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        return thresholds[index + 1];
153bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
154bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
155bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static void getTjMax() {
156c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan        ThermalManager.sTjMaxTemp = readSysfsTemp(ThermalManager.TJMAX_PATH);
157c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan        if (ThermalManager.sTjMaxTemp <= ThermalManager.ABS_ZERO) {
158bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.i(TAG, "TjMax temp read failed, Default TjMax value =" +
159bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    ThermalManager.sTjMaxTemp);
160c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan            ThermalManager.sTjMaxTemp = ThermalManager.sDefaultTjMax;
161bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
162bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
163bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
164bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static void initialiseConfigFiles(Context context) {
165bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if ("1".equals(SystemProperties.get("persist.thermal.debug.xml", "0"))) {
166bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (isFileExists(DEBUG_DIR_PATH + SENSOR_FILE_NAME) &&
167bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    isFileExists(DEBUG_DIR_PATH + THROTTLE_FILE_NAME)) {
168bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                sSensorFilePath = DEBUG_DIR_PATH + SENSOR_FILE_NAME;
169bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                sThrottleFilePath = DEBUG_DIR_PATH + THROTTLE_FILE_NAME;
170bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                Log.i(TAG, "Reading thermal config files from /data/");
171bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                sIsConfigFiles = true;
172bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            } else {
173bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                Log.i(TAG, "systemProperty set to read config files from /data/, but files absent");
174bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
175bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        } else if (isFileExists(DEFAULT_DIR_PATH + SENSOR_FILE_NAME) &&
176bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                isFileExists(DEFAULT_DIR_PATH + THROTTLE_FILE_NAME)) {
177bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            sSensorFilePath = DEFAULT_DIR_PATH + SENSOR_FILE_NAME;
178bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            sThrottleFilePath = DEFAULT_DIR_PATH + THROTTLE_FILE_NAME;
179bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.i(TAG, "Reading thermal config files from /system/etc/");
180bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            sIsConfigFiles = true;
181bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        } else {
182bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            sSensorFileXmlId = context.getResources().
183bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                getIdentifier("thermal_sensor_config", "xml", "com.intel.thermal");
184bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            sThrottleFileXmlId = context.getResources().
185bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                getIdentifier("thermal_throttle_config", "xml", "com.intel.thermal");
186bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (sSensorFileXmlId != 0 && sThrottleFileXmlId != 0) {
187bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                Log.i(TAG, "Reading thermal config files from overlays");
188bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                sIsOverlays = true;
189bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            } else {
190bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                Log.i(TAG, "Unable to retrieve config files from overlays");
191bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
192bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
193bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
194bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan}
195