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.os.UEventObserver; 20bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport android.util.Log; 21bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 22bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.util.ArrayList; 23bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.util.Arrays; 24bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.util.Hashtable; 25bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.util.Iterator; 26bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 27bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan/** 28bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * The ThermalZone class contains attributes of a Thermal zone. A Thermal zone 29bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * can have one or more sensors associated with it. Whenever the temperature of a 30bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * thermal zone crosses the thresholds configured, actions are taken. 31bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan */ 32bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanpublic class ThermalZone { 33bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 34bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private static final String TAG = "ThermalZone"; 35bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 36bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan protected int mZoneID; /* ID of the Thermal zone */ 37bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan protected int mCurrThermalState; /* Current thermal state of the zone */ 38bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan protected int mCurrEventType; /* specifies thermal event type, HIGH or LOW */ 39bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan protected String mZoneName; /* Name of the Thermal zone */ 40bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan protected int mMaxStates; 41bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan /* List of sensors under this thermal zone */ 42bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan protected ArrayList<ThermalSensor> mThermalSensors = null; 43bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // sensor name - sensorAttrib object hash to improve lookup performace 44bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // during runtime thermal monitoring like re-programming sensor thresholds 45bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // calculating weighted zone temp. 46bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan protected Hashtable<String, ThermalSensorAttrib> mThermalSensorsAttribMap = null; 47bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan protected int mZoneTemp; /* Temperature of the Thermal Zone */ 48bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan protected boolean mSupportsEmulTemp = true; 49bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private int mDebounceInterval; /* Debounce value to avoid thrashing of throttling actions */ 50bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private Integer mPollDelay[]; /* Delay between sucessive polls in milli seconds */ 51bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan protected boolean mSupportsUEvent; /* Determines if Sensor supports Uevents */ 52bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private String mZoneLogic; /* Logic to be used to determine thermal state of zone */ 53bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private boolean mIsZoneActive = false; 54bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private boolean mMaxThreshExceeded = false; 55bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private int mTripMax; 56bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private int mOffset = 0; 57bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan protected Integer mZoneTempThresholds[]; /* Array containing temperature thresholds */ 58bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // mZoneTempThresholdsRaw contains the Raw thresholds (as specified in xml). 59bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // mZoneTempThresholds contsins the calibrated thresholds that are used 60bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // to detect zone state change at runtime. 61bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan protected Integer mZoneTempThresholdsRaw[]; 62bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 63bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan /* MovingAverage related declarations */ 64bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private int mRecordedValuesHead = -1; /* Index pointing to the head of past values of sensor */ 65bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private int mRecordedValues[]; /* Recorded values of sensor */ 66bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private int mNumberOfInstances[]; /* Number of recorded instances to be considered */ 67bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private ArrayList<Integer> mWindowList = null; 68bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private boolean mIsMovingAverage = false; /* By default false */ 69bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 70bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // override this method in ModemZone to limit num states to default 71bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setMaxStates(int state) { 72bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mMaxStates = state; 73bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 74bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 75bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void updateMaxStates(int state) { 76bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan setMaxStates(state); 77bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 78bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 79bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public int getMaxStates() { 80bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mMaxStates; 81bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 82bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 83bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public boolean getMovingAverageFlag() { 84bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mIsMovingAverage; 85bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 86bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 87bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setMovingAvgWindow(ArrayList<Integer> windowList) { 88bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan int maxValue = Integer.MIN_VALUE; // -2^31 89bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 90bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (windowList == null || mPollDelay == null) { 91bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "setMovingAvgWindow input is null"); 92bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mIsMovingAverage = false; 93bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return; 94bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 95bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mNumberOfInstances = new int[windowList.size()]; 96bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mNumberOfInstances == null) { 97bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "failed to create poll windowlist"); 98bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mIsMovingAverage = false; 99bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return; 100bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 101bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mIsMovingAverage = true; 102bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan for (int i = 0; i < windowList.size(); i++) { 103bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mPollDelay[i] == 0) { 104bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mIsMovingAverage = false; 105bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "Polling delay is zero, WMA disabled\n"); 106bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return; 107bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 108bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mNumberOfInstances[i] = windowList.get(i) / mPollDelay[i]; 109bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mNumberOfInstances[i] <= 0) { 110bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mIsMovingAverage = false; 111bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "Polling delay greater than moving average window, WMA disabled\n"); 112bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return; 113bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 114bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan maxValue = Math.max(mNumberOfInstances[i], maxValue); 115bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 116bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mRecordedValues = new int[maxValue]; 117bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 118bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 119bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public int movingAverageTemp() { 120bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan int index, calIndex; 121bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan int predictedTemp = 0; 122bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 123bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mRecordedValuesHead = (mRecordedValuesHead + 1) % mRecordedValues.length; 124bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mRecordedValues[mRecordedValuesHead] = mZoneTemp; 125bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 126bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // Sensor State starts with -1, InstancesList starts with 0 127bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan for (index = 0; index < mNumberOfInstances[mCurrThermalState + 1]; index++) { 128bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan calIndex = mRecordedValuesHead - index; 129bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (calIndex < 0) { 130bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan calIndex = mRecordedValues.length + calIndex; 131bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 132bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan predictedTemp += mRecordedValues[calIndex]; 133bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 134bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return predictedTemp / index; 135bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 136bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 137bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void printAttrs() { 138bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "mZoneID:" + Integer.toString(mZoneID)); 139bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "mDBInterval: " + Integer.toString(mDebounceInterval)); 140bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "mZoneName:" + mZoneName); 141bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "mSupportsUEvent:" + Boolean.toString(mSupportsUEvent)); 142bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "mZoneLogic:" + mZoneLogic); 143bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "mOffset:" + mOffset); 144bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "mPollDelay[]:" + Arrays.toString(mPollDelay)); 145bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "mZoneTempThresholds[]: " + Arrays.toString(mZoneTempThresholds)); 146bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "mNumberOfInstances[]: " + Arrays.toString(mNumberOfInstances)); 147bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "mEmulTempFlag:" + mSupportsEmulTemp); 148bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "MaxStates:" + getMaxStates()); 149bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan printStateThresholdMap(); 150bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan printSensors(); 151bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan printSensorAttribList(); 152bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 153bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 154bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void printStateThresholdMap() { 155bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mZoneTempThresholds == null 156bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan || mZoneTempThresholds.length < ThermalManager.DEFAULT_NUM_ZONE_STATES) return; 157bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan StringBuilder s = new StringBuilder(); 158bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan s.append("[" + "State0" + "<" + mZoneTempThresholds[1] + "];"); 159bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan for (int index = 2; index < getMaxStates(); index++) { 160bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan int curstate = index - 1; 161bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan s.append("[" + mZoneTempThresholds[index - 1] + "<=" + "State" 162bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan + curstate + "<" + mZoneTempThresholds[index] + "];"); 163bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 164bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "states-threshold map:" + s.toString()); 165bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 166bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 167bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private void printSensors() { 168bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mThermalSensors == null) return; 169bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan StringBuilder s = new StringBuilder(); 170bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan for (ThermalSensor ts : mThermalSensors) { 171bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (ts != null) { 172bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan s.append(ts.getSensorName()); 173bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan s.append(","); 174bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 175bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 176bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "zoneID: " + mZoneID + " sensors mapped:" + s.toString()); 177bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 178bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 179bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan private void printSensorAttribList() { 180bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mThermalSensorsAttribMap == null) return; 181bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Iterator it = (Iterator) mThermalSensorsAttribMap.keySet().iterator(); 182bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (it == null) return; 183bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan ThermalSensorAttrib sensorAttrib = null; 184bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan while (it.hasNext()) { 185bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan sensorAttrib = mThermalSensorsAttribMap.get((String) it.next()); 186bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (sensorAttrib != null) sensorAttrib.printAttrs(); 187bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 188bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 189bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 190bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public ThermalZone() { 191bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mCurrThermalState = ThermalManager.THERMAL_STATE_OFF; 192bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mZoneTemp = ThermalManager.INVALID_TEMP; 193bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 194bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 195bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public static String getStateAsString(int index) { 196bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (index < -1 || index > 3) 197bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return "Invalid"; 198bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return ThermalManager.STATE_NAMES[index + 1]; 199bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 200bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 201bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public static String getEventTypeAsString(int type) { 202bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return type == 0 ? "LOW" : "HIGH"; 203bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 204bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 205bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setSensorList(ArrayList<ThermalSensorAttrib> sensorAtribList) { 206bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (sensorAtribList == null || ThermalManager.sSensorMap == null) return; 207bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan for (ThermalSensorAttrib sa : sensorAtribList) { 208bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // since each object of sensor attrib list is already validated during 209bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // parsing it is gauranteed that 'sa != null' and a valid sensor object 's' 210bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // will be returned. Hence skipping null check.. 211bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mThermalSensors == null) { 212bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // first time allocation 213bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mThermalSensors = new ArrayList<ThermalSensor>(); 214bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mThermalSensors == null) { 215bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // allocation failure. return 216bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return; 217bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 218bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 219bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mThermalSensorsAttribMap == null) { 220bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // first time allocation 221bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mThermalSensorsAttribMap = new Hashtable<String, ThermalSensorAttrib>(); 222bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mThermalSensorsAttribMap == null) return; 223bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 224bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mThermalSensors.add(ThermalManager.getSensor(sa.getSensorName())); 225bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mThermalSensorsAttribMap.put(sa.getSensorName(), sa); 226bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 227bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 228bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 229bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public ArrayList<ThermalSensor> getThermalSensorList() { 230bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mThermalSensors; 231bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 232bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 233bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public int getZoneState() { 234bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mCurrThermalState; 235bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 236bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 237bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setZoneState(int state) { 238bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mCurrThermalState = state; 239bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 240bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 241bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public int getEventType() { 242bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mCurrEventType; 243bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 244bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 245bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setEventType(int type) { 246bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mCurrEventType = type; 247bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 248bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 249bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setZoneTemp(int temp) { 250bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mZoneTemp = temp; 251bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 252bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 253bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public int getZoneTemp() { 254bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mZoneTemp; 255bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 256bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 257bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setZoneId(int id) { 258bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mZoneID = id; 259bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 260bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 261bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public int getZoneId() { 262bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mZoneID; 263bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 264bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 265bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setZoneName(String name) { 266bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mZoneName = name; 267bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 268bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 269bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public String getZoneName() { 270bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mZoneName; 271bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 272bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 273bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setSupportsUEvent(int flag) { 274bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mSupportsUEvent = (flag == 1); 275bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 276bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 277bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public boolean isUEventSupported() { 278bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mSupportsUEvent; 279bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 280bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 281bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public boolean isMaxThreshExceed() { 282bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mMaxThreshExceeded; 283bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 284bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 285bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setZoneLogic(String type) { 286bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mZoneLogic = type; 287bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 288bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 289bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public String getZoneLogic() { 290bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mZoneLogic; 291bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 292bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 293bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setDBInterval(int interval) { 294bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mDebounceInterval = interval; 295bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 296bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 297bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public int getDBInterval() { 298bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mDebounceInterval; 299bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 300bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 301bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public int getOffset() { 302bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mOffset; 303bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 304bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 305bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setOffset(int offset) { 306bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mOffset = offset; 307bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 308bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 309bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setPollDelay(ArrayList<Integer> delayList) { 310bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (delayList != null) { 311bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mPollDelay = new Integer[delayList.size()]; 312bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mPollDelay != null) { 313bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mPollDelay = delayList.toArray(mPollDelay); 314bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 315bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 316bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 317bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 318bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public Integer[] getPollDelay() { 319bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mPollDelay; 320bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 321bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 322bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan /** 323bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * In polldelay array, index of TOFF = 0, Normal = 1, Warning = 2, Alert = 324bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * 3, Critical = 4. Whereas a ThermalZone states are enumerated as TOFF = 325bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * -1, Normal = 0, Warning = 1, Alert = 2, Critical = 3. Hence we add 1 326bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * while querying poll delay 327bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan */ 328bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public int getPollDelay(int index) { 329bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan index++; 330bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 331bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // If poll delay is requested for an invalid state, return the delay 332bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // corresponding to normal state 333bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (index < 0 || index >= mPollDelay.length) 334bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan index = 1; 335bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 336bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mPollDelay[index]; 337bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 338bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 339bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setZoneTempThreshold(ArrayList<Integer> thresholdList) { 340bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mZoneName.contains("CPU") || mZoneName.contains("SoC")) 341bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mTripMax = ThermalManager.sTjMaxTemp; 342bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan else 343bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mTripMax = ThermalManager.sMaxSkinTrip; 344bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 345bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (thresholdList != null ) { 346bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // In Uevent mode, if any threshold specified for a particular 347bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // zone exceeds the max threshold temp, we de-activate that zone. 348bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mSupportsUEvent) { 349bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan for (int i = 0; i < thresholdList.size(); i++) { 350bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (thresholdList.get(i) <= mTripMax) 351bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan continue; 352bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan else 353bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mMaxThreshExceeded = true; 354bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 355bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 356bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mMaxThreshExceeded == false) { 357bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mZoneTempThresholds = new Integer[thresholdList.size()]; 358bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mZoneTempThresholdsRaw = new Integer[thresholdList.size()]; 359bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mZoneTempThresholds != null) { 360bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mZoneTempThresholds = thresholdList.toArray(mZoneTempThresholds); 361bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 362bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mZoneTempThresholdsRaw != null) { 363bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mZoneTempThresholdsRaw = thresholdList.toArray(mZoneTempThresholdsRaw); 364bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 365bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 366bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 367bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 368bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 369bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public int getZoneTempThreshold(int index) { 370bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (index < 0 || index >= mZoneTempThresholds.length) 371bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return -1; 372bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mZoneTempThresholds[index]; 373bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 374bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 375bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public Integer[] getZoneTempThreshold() { 376bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mZoneTempThresholds; 377bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 378bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 379bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public boolean getZoneActiveStatus() { 380bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mIsZoneActive; 381bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 382bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 383bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void computeZoneActiveStatus() { 384bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // init again. needed because of a profile change 385bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mIsZoneActive = false; 386bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mSupportsUEvent) { 387bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // Zone de-activated when any threshold for that zone is 388bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // above the allowed Max threshold. 389bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mMaxThreshExceeded == true) { 390bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "deactivate zone:" + mZoneName + 391bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan ". Zone Threshold exceeds max trip temp:" + mTripMax); 392bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mIsZoneActive = false; 393bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return; 394bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 395bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 396bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mZoneTempThresholds == null) { 397bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "deactivate zone:" + getZoneName() + " threshold list is NULL! "); 398bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mIsZoneActive = false; 399bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return; 400bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 401bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // 1. minimum number of states supported must be DEFAULT NUM STATES 402bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // 2. if sensor list null disable zone 403bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mMaxStates < ThermalManager.DEFAULT_NUM_ZONE_STATES) { 404bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // substract by 1 since TOFF is transparent to USER 405bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan int minStateSupport = ThermalManager.DEFAULT_NUM_ZONE_STATES - 1; 406bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "deactivate zone:" + getZoneName() + " supports < " 407bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan + minStateSupport + " states"); 408bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mIsZoneActive = false; 409bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return; 410bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 411bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mThermalSensors == null) { 412bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "deactivate zone:" + getZoneName() + " sensor list null! "); 413bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mIsZoneActive = false; 414bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return; 415bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 416bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 417bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mSupportsUEvent) { 418bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // if uevent just check the first sensor 419bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan ThermalSensor s = mThermalSensors.get(0); 420bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (s != null && s.getSensorActiveStatus()) { 421bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mIsZoneActive = true; 422bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return; 423bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 424bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } else { 425bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mPollDelay == null) { 426bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "deactivate zone:" + getZoneName() 427bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan + " polldelay list null in poll mode! "); 428bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mIsZoneActive = false; 429bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return; 430bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 431bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mZoneTempThresholds.length != mPollDelay.length) { 432bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "deactivate zone:" + getZoneName() 433bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan + " mismatch of polldelay and threshold list in polling mode!"); 434bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mIsZoneActive = false; 435bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return; 436bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 437bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan for (ThermalSensor ts : mThermalSensors) { 438bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (ts != null && ts.getSensorActiveStatus()) { 439bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mIsZoneActive = true; 440bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return; 441bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 442bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 443bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 444bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 445bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 446bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void setEmulTempFlag(int flag) { 447bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mSupportsEmulTemp = (flag == 1); 448bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 449bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 450bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public boolean getEmulTempFlag() { 451bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return mSupportsEmulTemp; 452bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 453bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 454bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // override in Specific zone class which inherit ThermalZone 455bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void startMonitoring() { 456bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 457bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 458bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // override in Specific zone class which inherit ThermalZone 459bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void stopMonitoring() { 460bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 461bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 462bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // override in ModemZone to unregister Modem specific intents 463bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // override in VirtualThermalZone to stop UEvent observers 464bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void unregisterReceiver() { 465bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (isUEventSupported()) { 466bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mUEventObserver.stopObserving(); 467bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 468bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 469bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 470bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // override in VirtualThermalZone class 471bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void startEmulTempObserver() { 472bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 473bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 474bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // override in VirtualThermalZone class 475bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void calibrateThresholds() { 476bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 477bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 478bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan /** 479bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * Function that calculates the state of the Thermal Zone after reading 480bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * temperatures of all sensors in the zone. This function is used when a 481bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * zone operates in polling mode. 482bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan */ 483bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public boolean isZoneStateChanged() { 484c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan for (int i = 0; i < mThermalSensors.size(); i++) { 485c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan if (mThermalSensors.get(i).getSensorActiveStatus()) { 486c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan mThermalSensors.get(i).updateSensorTemp(); 487bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 488bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 489bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return updateZoneParams(); 490bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 491bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 492bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan /** 493bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * Function that calculates the state of the Thermal Zone after reading 494bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * temperatures of all sensors in the zone. This is an overloaded function 495bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * used when a zone supports UEvent notifications from kernel. When a 496bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * sensor sends an UEvent, it also sends its current temperature as a 497bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * parameter of the UEvent. 498bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan */ 499bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public boolean isZoneStateChanged(ThermalSensor s, int temp) { 500bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (s == null) return false; 501bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan s.setCurrTemp(temp); 502bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan setZoneTemp(temp); 503bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return updateZoneParams(); 504bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 505bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 506bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan /** 507bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * Method to update Zone Temperature and Zone Thermal State 508bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan */ 509bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public boolean updateZoneParams() { 510bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan int newZoneState; 511bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan int prevZoneState = mCurrThermalState; 512bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 513bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (!updateZoneTemp()) { 514bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return false; 515bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 516bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 517bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan newZoneState = ThermalUtils.calculateThermalState(mZoneTemp, mZoneTempThresholds); 518bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (newZoneState == prevZoneState) { 519bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return false; 520bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 521bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 522bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (newZoneState == ThermalManager.THERMAL_STATE_OFF) { 523bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan setZoneState(newZoneState); 524bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return true; 525bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 526bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 527bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan int threshold = ThermalUtils.getLowerThresholdTemp(prevZoneState, mZoneTempThresholds); 528bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // For Interrupt based zones, HW (should) takes care of the debounce. 529bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (!isUEventSupported()) { 530bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (newZoneState < prevZoneState && getZoneTemp() > (threshold - getDBInterval())) { 531bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, " THERMAL_LOW_EVENT for zone:" + getZoneName() 532bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan + " rejected due to debounce interval"); 533bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return false; 534bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 535bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 536bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 537bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan setZoneState(newZoneState); 538bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan setEventType(newZoneState > prevZoneState 539bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan ? ThermalManager.THERMAL_HIGH_EVENT 540bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan : ThermalManager.THERMAL_LOW_EVENT); 541bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return true; 542bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 543bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 544bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public boolean updateZoneTemp() { 545bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan return false; 546bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 547bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 548bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void registerUevent() { 549bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan int indx; 550bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 551bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mThermalSensors == null) return; 552bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mThermalSensors.size() > 1) { 553bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "for zone:" + getZoneName() + " in uevent mode only first sensor used!"); 554bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 555bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan ThermalSensor sensor = mThermalSensors.get(0); 556bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (sensor == null) return; 557bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan String path = sensor.getUEventDevPath(); 558bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (path.equalsIgnoreCase("invalid")) return; 559bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // first time update of sensor temp and zone temp 560bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan sensor.updateSensorTemp(); 561bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan setZoneTemp(sensor.getCurrTemp()); 562bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (updateZoneParams()) { 563bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // first intent after initialization 564bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan sendThermalEvent(); 565bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 566bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mUEventObserver.startObserving(path); 567bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan programThresholds(sensor); 568bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 569bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 570bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public UEventObserver mUEventObserver = new UEventObserver() { 571bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan @Override 572bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void onUEvent(UEventObserver.UEvent event) { 573bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan String sensorName; 574bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan int sensorTemp, errorVal, eventType = -1; 575bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan ThermalZone zone; 576bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (mThermalSensors == null) return; 577bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 578bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // Name of the sensor and current temperature are mandatory parameters of an UEvent 579bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan sensorName = event.get("NAME"); 580bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan sensorTemp = Integer.parseInt(event.get("TEMP")); 581bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 582bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // eventType is an optional parameter. so, check for null case 583bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (event.get("EVENT") != null) 584bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan eventType = Integer.parseInt(event.get("EVENT")); 585bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 586bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (sensorName != null) { 587bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "UEvent received for sensor:" + sensorName + " temp:" + sensorTemp); 588bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // check the name against the first sensor 589bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan ThermalSensor sensor = mThermalSensors.get(0); 590bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (sensor != null && sensor.getSensorName() != null 591bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan && sensor.getSensorName().equalsIgnoreCase(sensorName)) { 592bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // Adjust the sensor temperature based on the 'error correction' temperature. 593bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // For 'LOW' event, debounce interval will take care of this. 594bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan errorVal = sensor.getErrorCorrectionTemp(); 595bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (eventType == ThermalManager.THERMAL_HIGH_EVENT) 596bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan sensorTemp += errorVal; 597bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 598bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (isZoneStateChanged(sensor, sensorTemp)) { 599bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan sendThermalEvent(); 600bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan // reprogram threshold 601bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan programThresholds(sensor); 602bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 603bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 604bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 605bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 606bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan }; 607bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 608bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void programThresholds(ThermalSensor s) { 609bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (s == null) return; 610bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan int zoneState = getZoneState(); 611bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (zoneState == ThermalManager.THERMAL_STATE_OFF) return; 612bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan int lowerTripPoint = ThermalUtils.getLowerThresholdTemp(zoneState, getZoneTempThreshold()); 613bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan int upperTripPoint = ThermalUtils.getUpperThresholdTemp(zoneState, getZoneTempThreshold()); 614bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (lowerTripPoint != ThermalManager.INVALID_TEMP 615bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan && upperTripPoint != ThermalManager.INVALID_TEMP) { 616bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (ThermalUtils.writeSysfs(s.getSensorLowTempPath(), lowerTripPoint) == -1) { 617bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "error while programming lower trip point:" + lowerTripPoint 618bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan + "for sensor:" + s.getSensorName()); 619bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 620bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan if (ThermalUtils.writeSysfs(s.getSensorHighTempPath(), upperTripPoint) == -1) { 621bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan Log.i(TAG, "error while programming upper trip point:" + upperTripPoint 622bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan + "for sensor:" + s.getSensorName()); 623bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 624bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 625bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 626bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan 627bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan public void sendThermalEvent() { 628bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan ThermalEvent event = new ThermalEvent(mZoneID, mCurrEventType, 629bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan mCurrThermalState, mZoneTemp, mZoneName, 630bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan ThermalManager.getCurProfileName()); 631bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan ThermalManager.addThermalEvent(event); 632bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan } 633bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan} 634