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.content.Intent;
21bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport android.os.SystemProperties;
22bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport android.os.UserHandle;
23bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport android.util.Log;
24bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
25bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.io.File;
26bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.io.IOException;
27bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.lang.NumberFormatException;
28bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.lang.StringBuilder;
29bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.util.ArrayList;
30bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.util.concurrent.ArrayBlockingQueue;
31bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.util.concurrent.BlockingQueue;
32bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.util.Enumeration;
33bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.util.Hashtable;
34bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.util.Iterator;
35bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.util.Map;
36bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanimport java.util.NoSuchElementException;
37bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan/**
38bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * The ThermalManager class contains data structures that are common to both
39bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * Thermal Sensor/Zone and Cooling device parts.
40bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan *
41bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan * @hide
42bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan */
43bc0b49155603ba1c0c1fc86d13127d04021e7c70shravanpublic class ThermalManager {
44bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static final String TAG = "ThermalManager";
45bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static Context sContext;
46bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static String sVersion;
47bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static String sCurProfileName;
48bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static String sProfileNameList;
49bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static int sProfileCount;
50bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static final String ITUX_VERSION_PROPERTY = "ro.thermal.ituxversion";
51bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* Parameter needed for reading configuration files */
52bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String SENSOR_FILE_NAME = "thermal_sensor_config.xml";
53bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String THROTTLE_FILE_NAME = "thermal_throttle_config.xml";
54bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String DEFAULT_DIR_PATH = "/system/etc/";
55bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String DEBUG_DIR_PATH = "/data/";
56bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static String sSensorFilePath;
57bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static String sThrottleFilePath;
58bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* *XmlId's are assigned if config files are choosen from overlays */
59bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static int sSensorFileXmlId = -1;
60bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static int sThrottleFileXmlId = -1;
61bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* Set to true if config are available in DEFAULT or DEBUG path */
62bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static boolean sIsConfigFiles = false;
63bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* Whether we are using the config files from overlays directory or from /etc/ */
64bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static boolean sIsOverlays = false;
65bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* Parameters required for MaxTrip data */
66bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String TJMAX_PATH = "/sys/devices/platform/coretemp.0/temp2_crit";
67bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int sDefaultTjMax = 90000;
68bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static int sTjMaxTemp;
69bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int sMaxSkinTrip = 150000;
70bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
71bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static String sUEventDevPath = "DEVPATH=/devices/virtual/thermal/thermal_zone";
72bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /**
73bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * Thermal Zone State Changed Action: This is broadcast when the state of a
74bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * thermal zone changes.
75bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     */
76bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String ACTION_THERMAL_ZONE_STATE_CHANGED =
77bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            "com.intel.thermal.action.THERMAL_ZONE_STATE_CHANGED";
78bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
79bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static PlatformInfo sPlatformInfo;
80bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static ThermalCooling sCoolingManager;
81bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* List of Thermal zones for current profile. Access protected by 'sProfileSwitchLock' */
82bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static ArrayList<ThermalZone> sThermalZonesList;
83bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
84bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* Hashtable of (ProfileName and ListOfZonesUnderThisProfile) */
85bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static Hashtable<String, ArrayList<ThermalZone>> sProfileZoneMap =
86bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            new Hashtable<String, ArrayList<ThermalZone>>();
87bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
88bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /**
89bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * This holds the map for the current profile. Access protected by 'sProfileSwitchLock'.
90bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * Should be initialized for every profile change.
91bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     */
92bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static Hashtable<Integer, ZoneCoolerBindingInfo> sZoneCoolerBindMap =
93bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            new Hashtable<Integer, ZoneCoolerBindingInfo>();
94bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
95bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* Hashtable of (ProfileName and Hashtable(zoneID, ZoneCoolerBindingInfo) object */
96bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static Hashtable<String, Hashtable<Integer, ZoneCoolerBindingInfo>> sProfileBindMap =
97bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            new Hashtable<String, Hashtable<Integer, ZoneCoolerBindingInfo>>();
98bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
99bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* Hashtable of (Cooling Device ID and ThermalCoolingDevice object) */
100bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static Hashtable<Integer, ThermalCoolingDevice> sCDevMap =
101bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            new Hashtable<Integer, ThermalCoolingDevice>();
102bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
103bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* Hashtable of sensor name and sensor object */
104bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static Hashtable<String, ThermalSensor> sSensorMap =
105bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            new Hashtable<String, ThermalSensor>();
106bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
107bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int CRITICAL_TRUE = 1;
108bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int CRITICAL_FALSE = 0;
109bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* sZoneCriticalPendingMap stores info whether a zone is in critical state and platform
110bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * shutdown has not yet occured due to some scenario like ongoing emergency call
111bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     **/
112bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static Hashtable<Integer, Integer> sZoneCriticalPendingMap = null;
113bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* this lock is to access sZoneCriticalPendingMap synchronously */
114bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static final Object sCriticalPendingLock = new Object();
115bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* this count keeps track of number of zones in pending critical state.When
116bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * sZoneCriticalPendingMap is updated, the count is either incremented or
117bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * decremented depending on whether criical pending flag for a zone is true/
118bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * false. By keeping a count we can avoid scanning through the entire map to
119bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * see if there is a pending critical shutdown
120bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     **/
121bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static int sCriticalZonesCount = 0;
122bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
123bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* Blocking queue to hold thermal events from thermal zones */
124bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static final int EVENT_QUEUE_SIZE = 10;
125bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
126bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static BlockingQueue<ThermalEvent> sEventQueue = new ArrayBlockingQueue<ThermalEvent>(EVENT_QUEUE_SIZE);
127bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* this lock is to handle uevent callbacks synchronously */
128bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static final Object sLock = new Object();
129bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
130bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /**
131bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * Extra for {@link ACTION_THERMAL_ZONE_STATE_CHANGED}:
132bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * integer containing the thermal zone.
133bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     */
134bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String EXTRA_ZONE = "zone";
135bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
136bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /**
137bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * Extra for {@link ACTION_THERMAL_ZONE_STATE_CHANGED}:
138bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * integer containing the thermal state of the zone.
139bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     */
140bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String EXTRA_STATE = "state";
141bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
142bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /**
143bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * Extra for {@link ACTION_THERMAL_ZONE_STATE_CHANGED}:
144bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * integer containing the thermal event type for the zone.
145bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     */
146bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String EXTRA_EVENT = "event";
147bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
148bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /**
149bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * Extra for {@link ACTION_THERMAL_ZONE_STATE_CHANGED}:
150bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * integer containing the temperature of the zone.
151bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     */
152bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String EXTRA_TEMP = "temp";
153bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String ACTION_CHANGE_THERMAL_PROFILE =
154bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            "android.intent.action.CHANGE_THERMAL_PROFILE";
155bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /**
156bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * Extra for {@link ACTION_THERMAL_ZONE_STATE_CHANGED}:
157bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * String containing the name of the zone.
158bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     */
159bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String EXTRA_NAME = "name";
160bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String EXTRA_PROFILE = "Profile";
161bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
162bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static Intent sQueryProfileIntent;
163bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String ACTION_QUERY_THERMAL_PROFILE =
164bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            "com.intel.thermal.action.QUERY_THERMAL_PROFILE";
165bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String ACTION_KILL = "kill";
166bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
167bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /**
168bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * Integer containing the number of thermal profiles.
169bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     */
170bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String EXTRA_NUM_PROFILE = "NumProfiles";
171bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /**
172bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * Space separated string containing list of thermal profile names.
173bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     */
174bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String EXTRA_PROFILE_LIST = "ProfileList";
175bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /**
176bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * String containing current thermal profile name.
177bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     */
178bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String EXTRA_CUR_PROFILE = "CurProfile";
179bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
180bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* values for "STATE" field in the THERMAL_STATE_CHANGED Intent */
181bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int THERMAL_STATE_OFF = -1;
182bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
183bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int THERMAL_STATE_NORMAL = 0;
184bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
185bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int THERMAL_STATE_WARNING = 1;
186bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
187bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int THERMAL_STATE_ALERT = 2;
188bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
189bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int THERMAL_STATE_CRITICAL = 3;
190bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
191bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int DEFAULT_NUM_THROTTLE_VALUES = 4;
192bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
193bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    // 5 including TOFF and TCRITICAL
194bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int DEFAULT_NUM_ZONE_STATES = 5;
195bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
196bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String STATE_NAMES[] = {
197bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            "OFF", "NORMAL", "WARNING", "ALERT", "CRITICAL"
198bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    };
199bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
200bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* values of the "EVENT" field in the THERMAL_STATE_CHANGED intent */
201bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* Indicates type of event */
202bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int THERMAL_LOW_EVENT = 0;
203bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
204bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int THERMAL_HIGH_EVENT = 1;
205bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
206bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int THERMAL_EMUL_TEMP_EVENT = 2;
207bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
208bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int INVALID_TEMP = 0xDEADBEEF;
209bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
210c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan    /* Absolute zero in millidegree C */
211c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan    public static final int ABS_ZERO = -273000;
212c9dcd35c3100acf9ab3d8d679c12abcf021a33d4Shravan
213bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* base sysfs path for sensors */
214bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String sSysfsSensorBasePath = "/sys/class/thermal/thermal_zone";
215bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
216bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String sSysfsSensorHighTempPath = "trip_point_1_temp";
217bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
218bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String sSysfsSensorLowTempPath = "trip_point_0_temp";
219bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
220bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String sCoolingDeviceBasePath = "/sys/class/thermal/cooling_device";
221bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
222bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String sCoolingDeviceState = "/cur_state";
223bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
224bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int THROTTLE_MASK_ENABLE = 1;
225bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
226bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int DETHROTTLE_MASK_ENABLE = 1;
227bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
228bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /**
229bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * Magic number (agreed upon between the Thermal driver and the Thermal Service)
230bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * symbolising Dynamic Turbo OFF
231bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     */
232bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final int DISABLE_DYNAMIC_TURBO = 0xB0FF;
233bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
234bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static boolean sIsDynamicTurboEnabled = false;
235bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
236bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* thermal notifier system properties for shutdown action */
237bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static boolean sShutdownTone = false;
238bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
239bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static boolean sShutdownToast = false;
240bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
241bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static boolean sShutdownVibra = false;
242bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
243bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* Name of default Thermal Profile */
244bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static final String DEFAULT_PROFILE_NAME = "Default";
245bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
246bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* Lock protecting profile-switch */
247bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static final Object sProfileSwitchLock = new Object();
248bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
249bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /**
250bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * This class stores the zone throttle info. It contains the zoneID,
251bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * CriticalShutdown flag and CoolingDeviceInfo arraylist.
252bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     */
253bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static class ZoneCoolerBindingInfo {
254bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        private int mZoneID;
255bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        // max states includes TOFF also.
256bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        // if user provides k threshold values in XML.
257bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        // mMaxStates = k + 1(for critical) + 1(for TOFF)
258bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        // this is same as the max states stored in corresponding zone object
259bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        protected int mMaxStates;
260bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        private int mIsCriticalActionShutdown;
261bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
262bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        /* cooler ID mask, 1 - throttle device, 0- no action, -1- dont care */
263bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        private ArrayList<CoolingDeviceInfo> mCoolingDeviceInfoList = null;
264bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
265bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        // ManyToOneMapping: ZoneStates >= CoolingDeviceStates
266bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        private ArrayList<Integer> mZoneToCoolDevBucketSize = null;
267bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
268bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        // OneToOneMapping: CoolingDeviceStates >= ThrottleValues
269bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        private ArrayList<Integer> mCoolDevToThrottBucketSize = null;
270bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
271bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        private CoolingDeviceInfo lastCoolingDevInfoInstance = null;
272bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
273bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public ZoneCoolerBindingInfo() {
274bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            mZoneToCoolDevBucketSize = new ArrayList<Integer>();
275bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            mCoolDevToThrottBucketSize = new ArrayList<Integer>();
276bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
277bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
278bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public int getLastState() {
279bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // mMaxStates = k + 1(for critical) + 1(for TOFF)
280bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return mMaxStates - 2;
281bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
282bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
283bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public void setMaxStates(int state) {
284bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            mMaxStates = state;
285bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
286bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
287bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public int getMaxStates() {
288bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return mMaxStates;
289bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
290bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
291bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public void setZoneToCoolDevBucketSize() {
292bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            int size = 1;
293bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            int zoneStates = getMaxStates();
294bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            for (CoolingDeviceInfo coolDev : mCoolingDeviceInfoList) {
295bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                size = (zoneStates - 1) / coolDev.getCoolingDeviceStates();
296bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                mZoneToCoolDevBucketSize.add(size == 0 ? 1 : size);
297bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
298bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
299bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
300bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public int getZoneToCoolDevBucketSizeIndex(int index) {
301bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (mZoneToCoolDevBucketSize.size() > index)
302bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                return mZoneToCoolDevBucketSize.get(index);
303bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
304bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return 1;
305bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
306bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
307bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public int getCoolDevToThrottBucketSizeIndex(int index) {
308bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (mZoneToCoolDevBucketSize.size() > index)
309bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                return mCoolDevToThrottBucketSize.get(index);
310bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
311bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return 1;
312bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
313bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
314bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public void setCoolDevToThrottBucketSize() {
315bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            int size = 1;
316bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            for (CoolingDeviceInfo coolDev : mCoolingDeviceInfoList) {
317bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                size = coolDev.getMaxThrottleStates() / coolDev.getCoolingDeviceStates();
318bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                mCoolDevToThrottBucketSize.add(size == 0 ? 1 : size);
319bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
320bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
321bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
322bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public void printAttributes() {
323bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (mCoolingDeviceInfoList == null) return;
324bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            StringBuilder s = new StringBuilder();
325bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            for (CoolingDeviceInfo c : mCoolingDeviceInfoList) {
326bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                if (c != null) {
327bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    s.append(c.getCoolingDeviceId());
328bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    s.append(",");
329bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                }
330bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
331bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.i(TAG, "zone id:" + mZoneID + " coolingDevID  mapped:" + s.toString());
332bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
333bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
334bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public void printMappedAttributes() {
335bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (mZoneToCoolDevBucketSize == null || mCoolDevToThrottBucketSize == null) return;
336bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            StringBuilder s = new StringBuilder();
337bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            for (int bs : mZoneToCoolDevBucketSize) {
338bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                s.append(bs);
339bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                s.append(",");
340bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
341bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.i(TAG, "zone id:" + mZoneID + " ZoneToCoolDevBucketSize:" + s.toString());
342bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // clear the string
343bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            s.delete(0,s.length());
344bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            for (int bs : mCoolDevToThrottBucketSize) {
345bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                s.append(bs);
346bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                s.append(",");
347bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
348bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.i(TAG, "zone id:" + mZoneID + " CoolDevToThrottBucketSize:" + s.toString());
349bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
350bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
351bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public class CoolingDeviceInfo {
352bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            private int mCDeviceID;
353bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
354bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // mCoolingDeviceState is number of device states exposed under a zone.
355bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // this must be less than or equal to its total number of throttle values
356bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            private int mCoolingDeviceStates = DEFAULT_NUM_THROTTLE_VALUES;
357bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
358bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // store a copy here for fast lookup during throttling/dethrottling
359bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            private int mMaxThrottleStates = 0;
360bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            private ArrayList<Integer> mDeviceThrottleMask = null;
361bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
362bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            private ArrayList<Integer> mDeviceDethrottleMask = null;
363bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
364bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            public CoolingDeviceInfo() {
365bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
366bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
367bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            public int getMaxThrottleStates() {
368bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                return mMaxThrottleStates;
369bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
370bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
371bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            public boolean checkMaskList(int throttleStates) {
372bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                boolean ret = true;
373bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                // if the list is empty this mean, THROTTLE MASK and/or
374bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                // DETHTOTTLE mask was not provided. Initialize default mask.
375bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                if (mDeviceThrottleMask ==  null) {
376bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    mDeviceThrottleMask = new ArrayList<Integer>();
377bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    for (int i = 0; i < mCoolingDeviceStates; i++) {
378bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                        mDeviceThrottleMask.add(THROTTLE_MASK_ENABLE);
379bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    }
380bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                } else if (mDeviceThrottleMask.size() != mCoolingDeviceStates) {
381bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    Log.i(TAG, "cdevid:" + mCDeviceID
382bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                            + " has mismatch in Cooling device state and mask array!deactivate!");
383bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    ret = false;
384bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                }
385bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
386bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                if (mDeviceDethrottleMask ==  null) {
387bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    mDeviceDethrottleMask = new ArrayList<Integer>();
388bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    for (int i = 0; i < mCoolingDeviceStates; i++) {
389bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                        mDeviceDethrottleMask.add(DETHROTTLE_MASK_ENABLE);
390bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    }
391bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                } else if (mDeviceDethrottleMask.size() != mCoolingDeviceStates) {
392bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    Log.i(TAG, "cdevid:" + mCDeviceID
393bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                            + " has mismatch in Cooling device state and mask array!deactivate!");
394bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    ret = false;
395bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                }
396bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                if (ret) {
397bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    mMaxThrottleStates = throttleStates;
398bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                }
399bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                return ret;
400bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
401bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
402bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            public int getCoolingDeviceId() {
403bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                return mCDeviceID;
404bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
405bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
406bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            public void setCoolingDeviceId(int deviceID) {
407bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                mCDeviceID = deviceID;
408bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
409bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
410bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            public int getCoolingDeviceStates() {
411bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                return mCoolingDeviceStates;
412bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
413bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
414bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            public void setCoolingDeviceStates(int num) {
415bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                mCoolingDeviceStates = num;
416bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
417bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
418bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            public ArrayList<Integer> getThrottleMaskList() {
419bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                return mDeviceThrottleMask;
420bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
421bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
422bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            public ArrayList<Integer> getDeThrottleMaskList() {
423bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                return mDeviceDethrottleMask;
424bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
425bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
426bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            public void setThrottleMaskList(ArrayList<Integer> list) {
427bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                this.mDeviceThrottleMask = list;
428bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
429bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
430bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            public void setDeThrottleMaskList(ArrayList<Integer> list) {
431bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                this.mDeviceDethrottleMask = list;
432bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
433bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
434bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
435bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
436bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public ArrayList<CoolingDeviceInfo> getCoolingDeviceInfoList() {
437bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return mCoolingDeviceInfoList;
438bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
439bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
440bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public void createNewCoolingDeviceInstance() {
441bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            lastCoolingDevInfoInstance = new CoolingDeviceInfo();
442bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
443bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
444bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public CoolingDeviceInfo getLastCoolingDeviceInstance() {
445bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return lastCoolingDevInfoInstance;
446bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
447bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
448bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public void setZoneID(int zoneID) {
449bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            mZoneID = zoneID;
450bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
451bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
452bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public int getZoneID() {
453bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return mZoneID;
454bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
455bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
456bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public void setCriticalActionShutdown(int val) {
457bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            mIsCriticalActionShutdown = val;
458bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
459bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
460bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public int getCriticalActionShutdown() {
461bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return mIsCriticalActionShutdown;
462bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
463bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
464bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public void setCoolingDeviceInfoList(ArrayList<CoolingDeviceInfo> devinfoList) {
465bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            mCoolingDeviceInfoList = devinfoList;
466bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
467bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
468bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public void initializeCoolingDeviceInfoList() {
469bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            mCoolingDeviceInfoList = new ArrayList<CoolingDeviceInfo>();
470bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
471bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
472bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        public void addCoolingDeviceToList(CoolingDeviceInfo CdeviceInfo) {
473bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            mCoolingDeviceInfoList.add(CdeviceInfo);
474bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
475bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
476bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
477bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* platform information */
478bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static class PlatformInfo {
479bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan       public int mMaxThermalStates;
480bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
481bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan       public int getMaxThermalStates() {
482bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return mMaxThermalStates;
483bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan       }
484bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
485bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan       public void printAttrs() {
486bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan           Log.i(TAG, Integer.toString(mMaxThermalStates));
487bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan       }
488bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan       public PlatformInfo() {}
489bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
490bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
491bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /* methods */
492bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public ThermalManager() {
493bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        // empty constructor
494bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
495bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
496bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static void setContext(Context context) {
497bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sContext = context;
498bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
499bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
500bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static String getVersion() {
501bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        return sVersion;
502bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
503bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
504bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static void loadiTUXVersion() {
505bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sVersion = SystemProperties.get(ITUX_VERSION_PROPERTY, "none");
506bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if (sVersion.equalsIgnoreCase("none")) {
507bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.i(TAG, "iTUX Version not found!");
508bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        } else {
509bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.i(TAG, "iTUX Version:" + sVersion);
510bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
511bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
512bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
513bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static void addThermalEvent(ThermalEvent event) {
514bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        try {
515bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            ThermalManager.sEventQueue.put(event);
516bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        } catch (InterruptedException ex) {
517bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.i(TAG, "caught InterruptedException in posting to event queue");
518bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
519bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
520bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
521bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static void setCurBindMap(String profName) {
522bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        synchronized (sProfileSwitchLock) {
523bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            sZoneCoolerBindMap = sProfileBindMap.get(profName);
524bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
525bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
526bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
527bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static Hashtable<Integer, ZoneCoolerBindingInfo> getCurBindMap() {
528bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        synchronized (sProfileSwitchLock) {
529bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return sZoneCoolerBindMap;
530bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
531bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
532bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
533bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static Hashtable<Integer, ZoneCoolerBindingInfo> getBindMap(String profName) {
534bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        return sProfileBindMap.get(profName);
535bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
536bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
537bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static void setCurProfileName(String profName) {
538bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sCurProfileName = profName;
539bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
540bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
541bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static String getCurProfileName() {
542bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        return sCurProfileName;
543bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
544bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
545bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static boolean isProfileExists(String profName) {
546bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if (sProfileZoneMap.get(profName) == null || sProfileBindMap.get(profName) == null) {
547bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return false;
548bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
549bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        return true;
550bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
551bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
552bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static void startNewProfile(String profName) {
553bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sThermalZonesList = sProfileZoneMap.get(profName);
554bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sZoneCoolerBindMap = sProfileBindMap.get(profName);
555bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if (sThermalZonesList == null || sZoneCoolerBindMap == null) {
556bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.i(TAG, "Couldn't shift to profile:" + profName);
557bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            return;
558bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
559bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        initializeZoneCriticalPendingMap();
560bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        setCurProfileName(profName);
561bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        int activeZones = startMonitoringZones();
562bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        Log.i(TAG, activeZones + " zones found active in profile " + profName);
563bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        // broadcast a sticky intent for the clients
564bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sendQueryProfileIntent();
565bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
566bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
567bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static void stopCurrentProfile() {
568bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        for (ThermalZone zone : sThermalZonesList) {
569bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // Stop Polling threads
570bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            zone.stopMonitoring();
571bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // Unregister UEvent/EmulTemp observers
572bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            zone.unregisterReceiver();
573bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // Reset Parameters:
574bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // Zone State: Normal, Event Type: LOW, Temperature: Normal Threshold
575bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            zone.setZoneState(0);
576bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            zone.setEventType(ThermalManager.THERMAL_LOW_EVENT);
577bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            zone.setZoneTemp(zone.getZoneTempThreshold(0));
578bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // Send ThermalIntent with above parameters
579bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // This will release all throttle controls this zone had.
580bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // Since we are in the middle of a profile switch(stop),
581bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // set the override parameter as true, so that this
582bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // event is actually queued for processing.
583bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // TODO: Find a way to take care of zones that are not
584bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // present in thermal_sensor_config.xml but present in
585bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // thermal_throttle_config.xml (usually from other components)
586bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            zone.sendThermalEvent();
587bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // Reprogram the sensor thresholds if this zone supported interrupts
588bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // TODO: We are reprogramming the calibrated thresholds in case the
589bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // the sensor was using 'weights' and 'offset'. Hope this is fine.
590bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (zone.isUEventSupported()) {
591bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                zone.programThresholds((zone.getThermalSensorList()).get(0));
592bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
593bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
594bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
595bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
596bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static void startDefaultProfile() {
597bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if (isProfileExists(DEFAULT_PROFILE_NAME)) {
598bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            startNewProfile(DEFAULT_PROFILE_NAME);
599bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
600bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        // register for Thermal Profile Change Intent only after
601bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        // we have started the default profile
602bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sCoolingManager.registerProfChangeListener();
603bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
604bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
605bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static void changeThermalProfile(String newProfName) {
606bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        synchronized (sProfileSwitchLock) {
607bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (newProfName.equalsIgnoreCase(sCurProfileName)) {
608bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                Log.i(TAG, "New Profile same as current profile. Profile change request Ignored");
609bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                return;
610bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
611bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (!isProfileExists(newProfName)) {
612bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                Log.i(TAG, "New Profile does not exist in xml. Profile change request Ignored");
613bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                return;
614bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
615bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.i(TAG, "ACTION_CHANGE_THERMAL_PROFILE received. New Profile: " + newProfName);
616bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
617bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            stopCurrentProfile();
618bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            startNewProfile(newProfName);
619bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
620bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
621bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
622bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static void setBucketSizeForProfiles() {
623bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        Iterator it = ThermalManager.sProfileZoneMap.entrySet().iterator();
624bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        while (it.hasNext()) {
625bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Map.Entry entryProfZone = (Map.Entry) it.next();
626bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            String keyProfile = (String) entryProfZone.getKey();
627bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            sThermalZonesList = (ArrayList<ThermalZone>) entryProfZone.getValue();
628bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            setCurBindMap(keyProfile);
629bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            for (ThermalZone zone : sThermalZonesList) {
630bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                if (sZoneCoolerBindMap == null) {
631bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    Log.e(TAG, "ZoneCoolerBindMap null while setBucketSizeForProfiles");
632bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    return;
633bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                }
634bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                ZoneCoolerBindingInfo bindInfo = sZoneCoolerBindMap.get(zone.getZoneId());
635bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                if (bindInfo == null) {
636bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    Log.e(TAG, "CoolerBindingInfo for zoneid:" + zone.getZoneId() + "not mapped");
637bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    return;
638bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                }
639bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                bindInfo.setMaxStates(zone.getMaxStates());
640bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                bindInfo.setZoneToCoolDevBucketSize();
641bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                bindInfo.setCoolDevToThrottBucketSize();
642bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                if (zone.isUEventSupported()) {
643bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    // calibration of thresholds based on weight, order
644bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                    if (!zone.isMaxThreshExceed())
645bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                        zone.calibrateThresholds();
646bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                }
647bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
648bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
649bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
650bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
651bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static int startMonitoringZones() {
652bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        int activeZonesCount = 0;
653bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        for (ThermalZone zone : sThermalZonesList) {
654bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            zone.computeZoneActiveStatus();
655bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (zone.getZoneActiveStatus() == false) {
656bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                Log.i(TAG, "deactivating inactive zone:" + zone.getZoneName());
657bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                continue;
658bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
659bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
660bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            ZoneCoolerBindingInfo bindInfo = sZoneCoolerBindMap.get(zone.getZoneId());
661bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (bindInfo != null) {
662bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                // TODO: To be conditioned under debug
663bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                bindInfo.printMappedAttributes();
664bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
665bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (zone.isUEventSupported()) {
666bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                zone.registerUevent();
667bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            } else {
668bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                // start polling thread for each zone
669bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                zone.startMonitoring();
670bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
671bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            zone.startEmulTempObserver();
672bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            activeZonesCount++;
673bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
674bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        return activeZonesCount;
675bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
676bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
677bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static void readShutdownNotiferProperties() {
678bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        try {
679bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if ("1".equals(SystemProperties.get("persist.thermal.shutdown.msg", "0"))) {
680bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                sShutdownToast = true;
681bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
682bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if ("1".equals(SystemProperties.get("persist.thermal.shutdown.tone", "0"))) {
683bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                sShutdownTone = true;
684bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
685bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if ("1".equals(SystemProperties.get("persist.thermal.shutdown.vibra", "0"))) {
686bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                sShutdownVibra = true;
687bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
688bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        } catch (java.lang.IllegalArgumentException e) {
689bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.e(TAG, "exception caught in reading thermal system properties");
690bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
691bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
692bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
693bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static void initializeZoneCriticalPendingMap() {
694bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sZoneCriticalPendingMap = new Hashtable<Integer, Integer>();
695bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if (sZoneCriticalPendingMap == null) return;
696bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        Enumeration en;
697bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        try {
698bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // look up for zone list is performed from sZoneCoolerBindMap instead of
699bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // sThermalZonesList since some non thermal zones may not have entry in
700bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // sThermalZonesList. This is because such zones only have entry in throttle
701bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // config file and not in sensor config files.
702bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // 'sZoneCoolerBindMap' is protected by caller here.
703bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            en = sZoneCoolerBindMap.keys();
704bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            while (en.hasMoreElements()) {
705bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                int zone = (Integer) en.nextElement();
706bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                sZoneCriticalPendingMap.put(zone, CRITICAL_FALSE);
707bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
708bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        } catch (NoSuchElementException e) {
709bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Log.i(TAG, "NoSuchElementException in InitializeZoneCriticalPendingMap()");
710bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
711bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
712bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
713bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    /*
714bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * updateZoneCriticalPendingMap updates sZoneCriticalPendingMap synchronously.
715bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * sCriticalZonesCount is incremented iff old value in the map for the zone is
716bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * FALSE (ensures count is incremented only once for a zone) and decremented
717bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     * iff oldval is TRUE (ensures no negative value for count)
718bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan     **/
719bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static boolean updateZoneCriticalPendingMap(int zoneid, int flag) {
720bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        synchronized (sCriticalPendingLock) {
721bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (sZoneCriticalPendingMap == null) return false;
722bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                Integer oldVal = sZoneCriticalPendingMap.get(zoneid);
723bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                if (oldVal == null) return false;
724bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                sZoneCriticalPendingMap.put(zoneid, flag);
725bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                if (oldVal == CRITICAL_FALSE && flag == CRITICAL_TRUE) {
726bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                   sCriticalZonesCount++;
727bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                } else if (oldVal == CRITICAL_TRUE && flag == CRITICAL_FALSE) {
728bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                   sCriticalZonesCount--;
729bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                }
730bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                return true;
731bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
732bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
733bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
734bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static boolean checkShutdownCondition() {
735bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        synchronized (sCriticalPendingLock) {
736bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan           return sCriticalZonesCount > 0;
737bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
738bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
739bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
740bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static ThermalSensor getSensor(String sensorName) {
741bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if (sensorName == null || sSensorMap == null) return null;
742bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        return sSensorMap.get(sensorName);
743bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
744bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
745bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static void buildProfileNameList() {
746bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        int count = 0;
747bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        StringBuilder s = new StringBuilder();
748bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        Iterator it = sProfileZoneMap.entrySet().iterator();
749bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        while (it.hasNext()) {
750bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            Map.Entry entry = (Map.Entry) it.next();
751bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            String key = (String) entry.getKey();
752bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            // create list of only valid profiles
753bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            if (isProfileExists(key)) {
754bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                // build a space seperate list of string
755bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                s.append(key);
756bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                s.append(" ");
757bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan                count++;
758bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            }
759bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
760bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
761bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sProfileNameList = s.toString();
762bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sProfileCount = count;
763bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        Log.i(TAG, "profile name list:" + sProfileNameList);
764bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        Log.i(TAG, "profile count:" + sProfileCount);
765bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
766bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
767bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static void initializeStickyIntent() {
768bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sQueryProfileIntent = new Intent();
769bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sQueryProfileIntent.setAction(ACTION_QUERY_THERMAL_PROFILE);
770bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
771bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
772bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    private static void sendQueryProfileIntent() {
773bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        if (sQueryProfileIntent != null && sContext != null) {
774bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            sQueryProfileIntent.putExtra(ThermalManager.EXTRA_NUM_PROFILE, sProfileCount);
775bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            sQueryProfileIntent.putExtra(ThermalManager.EXTRA_PROFILE_LIST, sProfileNameList);
776bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            sQueryProfileIntent.putExtra(ThermalManager.EXTRA_CUR_PROFILE, sCurProfileName);
777bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan            sContext.sendStickyBroadcastAsUser(sQueryProfileIntent, UserHandle.ALL);
778bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        }
779bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
780bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan
781bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    public static void clearData() {
782bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sThermalZonesList.clear();
783bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        // clearing hastables
784bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sProfileZoneMap.clear();
785bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sZoneCoolerBindMap.clear();
786bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sProfileBindMap.clear();
787bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sCDevMap.clear();
788bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sSensorMap.clear();
789bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan        sZoneCriticalPendingMap.clear();
790bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan    }
791bc0b49155603ba1c0c1fc86d13127d04021e7c70shravan}
792