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